2009-12-03 54 views
1

在應用程序的中間是一個框架。調整大小後,我需要重新排列此面板上的控件(在調整大小的事件中執行此操作太繁忙)。 它更有用,如果這可以在所有調整大小後進行一次。但是如何?如何實現TFrame的OnResizeEnd事件?

謝謝你的幫助

回答

0

你可以試試下面的實現。

- 在Resize事件上掛鉤所有者窗體,在窗體中處理它,並觸發父OnResize可能擁有的任何事件處理程序。

type 
    TFrame2 = class(TFrame) 
    Label1: TLabel; 
    procedure FrameClick(Sender: TObject); 
    private 
    { Private declarations } 
    FOnResize: TNotifyEvent; 

    procedure OnFrameResize(Sender: TObject); 
    public 
    { Public declarations } 
    // custom Frame constructor 
    constructor Create(AOwner: TComponent); override; 
    end; 

implementation 

{$R *.dfm} 

{ TFrame2 } 

constructor TFrame2.Create(AOwner: TComponent); 
begin 
    inherited; 

    FOnResize := TForm(AOwner).OnResize; 
    TForm(AOwner).OnResize := OnFrameResize; 
end; 

procedure TFrame2.OnFrameResize(Sender: TObject); 
begin 
    Label1.Caption := 'resize fired'; 
    if @FOnResize <> nil then 
    FOnResize(Parent); 
end; 
+0

我認爲他想推遲調整大小「(在調整大小的事件中這樣做太忙)」。 PS。調整大小也可以通過在框架上放置面板並將所有組件放入。 – BennyBechDk 2009-12-04 08:32:04

+0

OnResizeEnd事件恰好在調用Paren'ts OnResize之後。就在它說'FOnResize(Parent)'的地方,你可以插入任何代碼來處理它 – zz1433 2009-12-04 11:10:15

2

訣竅是掛鉤到母體形式的消息處理(驗證的概念代碼,與2009年的Delphi測試,錯誤和角情況下的處理需要更多的工作):

type 
    TFrame2 = class(TFrame) 
    strict private 
    fOnEnterSizeMove: TNotifyEvent; 
    fOnExitSizeMove: TNotifyEvent; 
    fSavedWndProc: TWndMethod; 
    procedure DoEnterSizeMove; 
    procedure DoExitSizeMove; 
    procedure ParentWindowProc(var AMessage: TMessage); 
    protected 
    procedure CreateWnd; override; 
    procedure DestroyWnd; override; 
    published 
    property OnEnterSizeMove: TNotifyEvent read fOnEnterSizeMove 
     write fOnEnterSizeMove; 
    property OnExitSizeMove: TNotifyEvent read fOnExitSizeMove 
     write fOnExitSizeMove; 
    end; 

{ TFrame2 } 

procedure TFrame2.CreateWnd; 
var 
    ParentForm: TCustomForm; 
begin 
    inherited; 
    ParentForm := GetParentForm(Self); 
    if ParentForm <> nil then begin 
    fSavedWndProc := ParentForm.WindowProc; 
    ParentForm.WindowProc := ParentWindowProc; 
    end; 
end; 

procedure TFrame2.DestroyWnd; 
var 
    ParentForm: TCustomForm; 
begin 
    ParentForm := GetParentForm(Self); 
    if ParentForm <> nil then 
    ParentForm.WindowProc := fSavedWndProc; 
    inherited; 
end; 

procedure TFrame2.DoEnterSizeMove; 
begin 
    if Assigned(fOnEnterSizeMove) then 
    fOnEnterSizeMove(Self); 
end; 

procedure TFrame2.DoExitSizeMove; 
begin 
    if Assigned(fOnExitSizeMove) then 
    fOnExitSizeMove(Self); 
end; 

procedure TFrame2.ParentWindowProc(var AMessage: TMessage); 
begin 
    fSavedWndProc(AMessage); 
    if AMessage.Msg = WM_ENTERSIZEMOVE then 
    DoEnterSizeMove; 
    if AMessage.Msg = WM_EXITSIZEMOVE then 
    DoExitSizeMove; 
end; 

注只要用於移動/調整大小的輔助消息循環已經開始或留下,就會發送消息 - 無法區分移動和調整大小。如果您需要確保只抓取大小,您應該比較處理程序中框架的新舊大小。

0

我認爲這可以通過調整大小事件停止(重置時間)並啓動一個具有短暫超時(類似0,3秒)的計時器來完成。然後,重新調整大小將在其他大小調整後不久完成。

0

1)用特殊的接口標記你的幀。例如:INeedLayoutAfterResize :)

2)編寫可捕獲調整大小事件(如前面的答案中所示)的TForm的自定義後代,而不是尋找它的子代以及是否有子標記,而不是重新佈局其內容。

實際上我使用這種方法來保存和恢復控制狀態。 我的自定義從遍歷其子控件並查找Tag屬性,如果它小於零,則將其狀態寫入ini文件。