是一个框架。调整大小后我需要重新排列此面板上的控件(在调整大小事件中执行此操作太忙)。 如果在调整大小后可以执行一次,则更有用。但是如何?
感谢您的帮助
答案 0 :(得分:2)
诀窍是挂钩父表单的消息处理(概念验证代码,使用Delphi 2009测试,错误和角落案例处理需要更多工作):
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;
请注意,只要启动或调整了用于移动/调整大小的辅助消息循环,就会发送消息 - 无法区分移动和调整大小。如果您需要确保仅捕获大小,则应该比较处理程序中框架的新旧大小。
答案 1 :(得分: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;
答案 2 :(得分:0)
我认为可以通过调整大小事件来停止(重置时间)并启动具有et timeout超时(等于0.3秒)的计时器。然后在调整大小的其余部分后不久就会调整fram的大小。
答案 3 :(得分:0)
1)用特殊界面smth标记你的框架。喜欢:INeedLayoutAfterResize:)
2)编写TForm的自定义后代,它将捕获调整大小事件(如前面的答案中所示),而不是查找其子项以及是否标记了某个子项,而不是重新布局其内容。
实际上我使用这种方法来保存和恢复控件状态。 我的自定义迭代它的子控件并查找Tag属性,如果它小于零,将其状态写入ini文件。