2009-03-17 1 views
1

Delphi 2009의 TButtonedEdit와 같은 구성 요소를 만들려고합니다. 왼쪽과 오른쪽에 두 개의 단추가있는 사용자 지정 TEdit입니다.내 구성 요소 크래시 (TCustomEdit 자손)

내 버전에서는 왼쪽 및 오른쪽 단추에 2 개의 TSpeedButton 개체를 사용합니다.

다음 간단한 코드를 살펴보십시오.

설치하는 것이 좋으며 부품 pallete에서 볼 수 있습니다.

하지만 알 수없는 이유로 애플리케이션을 저장할 수 없습니다. 구성 요소를 추가하고 속성 변경 또는 이벤트 작성을 시작하자마자 Delphi가 즉시 종료됩니다 (충돌이 발생 했습니까?).

나는 무엇이 잘못 되었는가를 모른다. 그러나 이것은 내가 옳지 않다는 것이 나의 첫 번째 구성 요소이다.

문제점을 확인해주세요.

이 구성 요소를 사용하면 Delphi 7.0에서 .dfm을 저장하는 데 문제가있는 것으로 보입니다.

폼에이 구성 요소를 추가 할 때 저장하면 "Unit1.pas"를 저장하라는 메시지가 나타나면 즉시 종료됩니다.

감사합니다.

unit MyButtonedEdit; 

interface 

uses 
    Windows, Buttons, Classes, Controls, Forms, Graphics, Messages, StdCtrls; 

type 
    TMyCustomButtonedEdit = class(TCustomEdit) 
    private 
    FLeftButton: TSpeedButton; 
    FRightButton: TSpeedButton; 

    procedure LeftButtonClick(Sender: TObject); 
    procedure RightButtonClick(Sender: TObject); 

    function GetLeftGlyph: TBitmap; 
    function GetRightGlyph: TBitmap; 

    procedure SetLeftGlyph(const g: TBitmap); 
    procedure SetRightGlyph(const g: TBitmap); 

    protected 
    procedure CreateParams(var Params: TCreateParams); override; 
    procedure DoLeftButtonClick; virtual; abstract; 
    procedure DoRightButtonClick; virtual; abstract; 
    function GetEnabled: boolean; override; 
    procedure SetEnabled(e: boolean); override; 
    procedure WMSize(var Message: TWMSize); message WM_SIZE; 
    property LeftButton: TSpeedButton read FLeftButton write FLeftButton; 
    property RightButton: TSpeedButton read FRightButton write FRightButton; 
    property Enabled: boolean read GetEnabled write SetEnabled; 
    property LeftGlyph: TBitmap read GetLeftGlyph write SetLeftGlyph; 
    property RightGlyph: TBitmap read GetRightGlyph write SetRightGlyph; 

    public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 
    published 
    end; 


    TMyButtonedEdit = class(TMyCustomButtonedEdit) 
    private 
    FOnLeftButtonClick: TNotifyEvent; 
    FOnRightButtonClick: TNotifyEvent; 
    protected 
    procedure DoLeftButtonClick; override; 
    procedure DoRightButtonClick; override; 
    public 
    published 
    property LeftButton; 
    property RightButton; 
    property AutoSelect; 
    property BorderStyle; 
    property Color; 
    property Ctl3d; 
    property DragCursor; 
    property DragMode; 
    property Enabled; 
    property Font; 
    property LeftGlyph; 
    property RightGlyph; 
    property HideSelection; 
    property ParentColor; 
    property ParentCtl3D; 
    property ParentFont; 
    property ParentShowHint; 
    property PopupMenu; 
    property ReadOnly; 
    property ShowHint; 
    property TabOrder; 
    property Text; 
    property Visible; 
    property OnLeftButtonClick: TNotifyEvent read FOnLeftButtonClick write FOnLeftButtonClick; 
    property OnRightButtonClick: TNotifyEvent read FOnRightButtonClick write FOnRightButtonClick;  
    property OnChange; 
    property OnClick; 
    property OnDblClick; 
    property OnDragDrop; 
    property OnDragOver; 
    property OnEndDrag; 
    property OnEnter; 
    property OnExit; 
    property OnKeyDown; 
    property OnKeyPress; 
    property OnKeyUp; 
    property OnMouseDown; 
    property OnMouseMove; 
    property OnMouseUp; 
    property OnStartDrag; 
    end; 

procedure Register; 

implementation 

procedure Register; 
begin 
    RegisterComponents('MyComponents',[TMyButtonedEdit]); 
end; 

{ TMyCustomButtonedEdit } 

constructor TMyCustomButtonedEdit.Create(AOwner: TComponent); 
begin 
    inherited; 
    ControlStyle := ControlStyle - [csSetCaption]; 

    FLeftButton := TSpeedButton.Create(self); 
    with FLeftButton do begin 
    Parent := self; 
    TabStop := false; 
    Visible := true; 
    OnClick := LeftButtonClick; 
    end; 

    FRightButton := TSpeedButton.Create(self); 
    with FRightButton do begin 
    Parent := self; 
    TabStop := false; 
    Visible := true; 
    OnClick := RightButtonClick; 
    end; 
end; 

destructor TMyCustomButtonedEdit.Destroy; 
begin 
    FLeftButton.Free; 
    FRightButton.Free; 
    inherited; 
end; 

procedure TMyCustomButtonedEdit.CreateParams(var Params: TCreateParams); 
begin 
    inherited CreateParams(Params); 
    Params.Style := Params.Style or WS_CLIPCHILDREN; 
end; 

function TMyCustomButtonedEdit.GetEnabled: boolean; 
begin 
    result := inherited Enabled; 
end; 

function TMyCustomButtonedEdit.GetLeftGlyph: TBitmap; 
begin 
    result := FLeftButton.Glyph; 
end; 

function TMyCustomButtonedEdit.GetRightGlyph: TBitmap; 
begin 
    result := FRightButton.Glyph; 
end; 

procedure TMyCustomButtonedEdit.LeftButtonClick(Sender: TObject); 
begin 
    DoLeftButtonClick; 
    SetFocus; 
end; 

procedure TMyCustomButtonedEdit.RightButtonClick(Sender: TObject); 
begin 
    DoRightButtonClick; 
    SetFocus; 
end; 

procedure TMyCustomButtonedEdit.SetEnabled(e: boolean); 
begin 
    inherited Enabled := e; 
    FLeftButton.Enabled := e; 
    FRightButton.Enabled := e; 
end; 

procedure TMyCustomButtonedEdit.SetLeftGlyph(const g: TBitmap); 
begin 
    FLeftButton.Glyph := g; 
end; 

procedure TMyCustomButtonedEdit.SetRightGlyph(const g: TBitmap); 
begin 
    FRightButton.Glyph := g; 
end; 

procedure TMyCustomButtonedEdit.WMSize(var Message: TWMSize); 
var 
    b: integer; 
begin 
    if (BorderStyle = bsSingle) and not Ctl3d then 
    b := 1 
    else 
    b := 0; 
    FLeftButton.Top := b; 
    FLeftButton.Height := ClientHeight - b * 2; 
    FLeftButton.Width := FLeftButton.Height; 
    FLeftButton.Left := b; 

    FRightButton.Top := b; 
    FRightButton.Height := ClientHeight - b * 2; 
    FRightButton.Width := FRightButton.Height; 
    FRightButton.Left := ClientWidth - FRightButton.Width - b; 
end; 

{ TMyButtonedEdit } 

procedure TMyButtonedEdit.DoLeftButtonClick; 
begin 
    inherited; 
    if Assigned(FOnLeftButtonClick) then 
    FOnLeftButtonClick(Self); 
end; 

procedure TMyButtonedEdit.DoRightButtonClick; 
begin 
    inherited; 
    if Assigned(FOnRightButtonClick) then 
    FOnRightButtonClick(Self); 
end; 

end. 

답변

0

내가 모든 구성 요소 개발을 한 이후 오랜 시간,하지만 난 구성 요소의 소유자는 보통 부모의 소유자가 아닌 부모 자체가 너무

FLeftButton := TSpeedButton.Create(self); 

가해야 할 것을 기억하는 것 be :

FLeftButton := TSpeedButton.Create(AOwner); 
+0

복합 구성 요소에 없습니다.당신이 설명하는 것은 디자인 타임에 폼에 고정 된 컴포넌트들입니다. 이는 델파이의 IDE 동작입니다. 그러나 VCL의 컴포지트 구성 요소에서도 복합 요소는 하위 구성 요소의 소유자, 즉 복합 요소입니다. –

7

귀하의 문제는 당신이 전화를 사용합니다. 오류가 발생하기 전에 실제로받은 오류는

Project Project1a.exe raised exception class EStackOverflow with message 
'Stack overflow'. Process stopped. Use Step or Run to continue. 

무한 루프에 빠졌습니다.

구성 요소를 디버깅하려면 런타임에 구성 요소를 만드는 것이 가장 좋습니다. 디자인 타임에 시도하는 것보다 디버깅이 훨씬 쉽습니다. 런타임에 디버깅하려면이 작업을 수행했습니다.

var 
BE : TMyButtonedEdit; 
begin 
BE := TMyButtonedEdit.Create(self); 
be.Parent := self; 
be.Visible := true; 

컨트롤을 만들 때 오랜 시간이 걸렸지 만 일반적으로 무한 루프를 의미하는 stackoverflow 오류가 발생합니다. 나는 아직도 그 이유를 알지 못했지만 그 일을하고 있습니다.

해결책.

당신은 속성을 상속 할 수 없습니다 (물론 당신이 수 - 주석 참조), 통화 있도록

inherited Enabled; 

실제로 자신을 호출했다. 당신이해야 할 일은

inherited GetEnabled; 

정신 운동에 감사드립니다.

+0

SetEnabled와 동일합니다 –

+0

실제로 상속 된 속성을 호출 할 수 있습니다. 접근자가 개인이 아니고 보호되지 않는 경우 가끔있는 유일한 방법입니다. 이 경우 접근자는 가상이라는 것이 문제입니다. (고맙게도, 당신은 개인 가상 메서드를 가질 수 없으며, 이것은 진짜 엉망이 될 수 있습니다 ...);) –