在应用程序的中间是一个框架。调整大小后,我需要重新排列此面板上的控件(在调整大小的事件中执行此操作太繁忙)。 它更有用,如果这可以在所有调整大小后进行一次。但是如何?如何实现TFrame的OnResizeEnd事件?
谢谢你的帮助
在应用程序的中间是一个框架。调整大小后,我需要重新排列此面板上的控件(在调整大小的事件中执行此操作太繁忙)。 它更有用,如果这可以在所有调整大小后进行一次。但是如何?如何实现TFrame的OnResizeEnd事件?
谢谢你的帮助
你可以试试下面的实现。
- 在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;
诀窍是挂钩到母体形式的消息处理(验证的概念代码,与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,3秒)的计时器来完成。然后,重新调整大小将在其他大小调整后不久完成。
1)用特殊的接口标记你的帧。例如:INeedLayoutAfterResize :)
2)编写可捕获调整大小事件(如前面的答案中所示)的TForm的自定义后代,而不是寻找它的子代以及是否有子标记,而不是重新布局其内容。
实际上我使用这种方法来保存和恢复控制状态。 我的自定义从遍历其子控件并查找Tag属性,如果它小于零,则将其状态写入ini文件。
我认为他想推迟调整大小“(在调整大小的事件中这样做太忙)”。 PS。调整大小也可以通过在框架上放置面板并将所有组件放入。 – BennyBechDk 2009-12-04 08:32:04
OnResizeEnd事件恰好在调用Paren'ts OnResize之后。就在它说'FOnResize(Parent)'的地方,你可以插入任何代码来处理它 – zz1433 2009-12-04 11:10:15