2009-12-03 95 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文件。