2012-09-03 10 views
2

왜 그런지 궁금하지만 간단하게 간단한 프로그램을 디버깅 할 수는 없습니다. 로드 된 메서드는 무시되고 절대 실행되지 않습니다. 이유는 모르겠다. 모양 :로드 된 메서드가 무시되는 이유는 무엇입니까?

TGridObj = class (TComponent) 
private 
    FPen1:TPen; 
    FBrush1:TBrush; 
    FChange:TNotifyEvent; 

protected 
    procedure Loaded; override; 


public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 
published 
    property OnChange:TNotifyEvent read FChange write FChange; 

    property Pen1:TPen read FPen1 write FPen1; 
    property Brush1:TBrush read FBrush1 write FBrush1; 
end; 

. .

constructor TGridObj.Create(AOwner: TComponent); 
    begin 
    inherited Create(AOwner); 
    FPen1:=TPen.Create; 
    FPen1.OnChange:=FChange; 


    FBrush1:=TBrush.Create; 
    FBrush1.OnChange:=FChange; 
    end; 


destructor TGridObj.destroy; 
    begin 
    FPen1.Free; 
    FBrush1.Free; 
    inherited; 
    end; 

procedure TGridObj.Loaded(); 
begin 
    inherited Loaded; 
    ShowMessage(''); // this is never executed; 
    FPen1.OnChange:=FChange; 
    FBrush1.OnChange:=FChange; 
end; 

. . 컴퍼넌트 형태 자원 DFM (파일)로부터로드 된 경우 고맙습니다

답변

8

Loaded은 구성 요소의 속성이 양식 파일에서 스트리밍 될 때만 호출됩니다. 런타임에 생성하기 때문에 Loaded이 호출되지 않습니다. 이는 의도적으로 설계된 동작입니다.

OnChange 이벤트가 런타임에 수정되고 해당 필터가 펜 및 브러시까지 내려갈 수 있도록하려면 코드가 작동해야합니다. 나는 이런 식으로 할 거라고 :

TGridObj = class (TComponent) 
private 
    FPen1: TPen; 
    FBrush1: TBrush; 
    FChange: TNotifyEvent; 
    procedure DoChange(Sender: TObject); 
public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 
published 
    property OnChange: TNotifyEvent read FChange write FChange; 
    property Pen1: TPen read FPen1; 
    property Brush1: TBrush read FBrush1; 
end; 

constructor TGridObj.Create(AOwner: TComponent); 
begin 
    inherited; 
    FPen1 := TPen.Create; 
    FPen1.OnChange := DoChange; 
    FBrush1 := TBrush.Create; 
    FBrush1.OnChange := DoChange; 
end; 

destructor TGridObj.Destroy; 
begin 
    FBrush1.Free; 
    FPen1.Free; 
    inherited; 
end; 

procedure TGridObj.DoChange(Sender: TObject); 
begin 
    if Assigned(FChange) then 
    FChange(Sender); 
end; 

지금 같은 Loaded 또는 아무것도 필요가 없습니다. OnChange 펜과 브러시 이벤트가 실제로 실행될 때까지 대기하기 때문에 FChange에 액세스합니다.

그런데 코드에서 기본 필드를 수정하는 Pen1Brush1에 대한 속성 설정자를 추가하는 것은 실수입니다. 그것은 누출과 모든 종류의 혼란을 가져옵니다. 또한 펜과 브러시를 공공 장소로 노출하면 TGridObj 고객이 OnChange 이벤트를 변경할 수 있습니다. 그리고 그것은 TGridObj.OnChange을 파괴합니다.

1

OnLoaded 만 실행될

procedure TForm1.FormCreate(Sender: TObject); 
begin 
Grid:=TGridObj.Create(nil); 
Grid.OnChange:=ev1.OnChange; 
Form1.InsertComponent(Grid); 
end; 

.

런타임에 코드에서만 구성 요소를 만들면 실행되지 않습니다.

업데이트 :

나는 그들이 만든 너무 런타임에 구성 할 수 있도록 구성 요소를 디자인하는 것이 좋습니다

- 나는 OnLoaded 재정의하는 피할 것을 의미한다. 장점은 패키지 설치/구성 요소 등록이 필요 없다는 것입니다.

관련 문제