当 MDI 子窗体最大化时捕获 Delphi MDI 子窗体最小化事件
Catch Delphi MDI Child minimize event when the MDI Child form is maximized
我需要一些帮助来尝试捕获 MDI 子窗体最大化时的最小化事件。
单击下图中红色圆圈中的按钮时,当表单未最大化时,我能够捕获 minimize/restore/maximize 事件。
我使用 WMSysCommand 捕获上述事件:
procedure TMDIChildForm.WMSysCommand(var Msg: TWMSysCommand);
begin
if Msg.CmdType = SC_MINIMIZE then
begin
//my code here
end;
end;
当我尝试在 MDI 子窗体最大化时使用 WMSysCommand 捕获相同的事件并单击下图中红色圆圈中的按钮时,它不会调用此代码。
无论我尝试过什么,我都没有成功捕捉到这些事件。如果有人能指出我正确的方向,将不胜感激。谢谢。
当我尝试时对我来说效果很好:
type
TMDIChildForm = class(TForm)
private
{ Private declarations }
procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
public
{ Public declarations }
end;
procedure TMDIChildForm.WMSysCommand(var Msg: TWMSysCommand);
begin
inherited; // <-- ADD THIS!!
if Msg.CmdType = SC_MINIMIZE then
begin
// code here
end;
end;
WMSysCommand()
会在 MDI 子项最小化时捕获 SC_MINIMIZE
通知,无论它之前是否按预期最大化。
确保 TMDIChildForm.WMSysCommand()
调用 inherited
(如上所示)将 WM_SYSCOMMAND
消息传递给默认处理程序,以便 Windows 有机会处理它。
在做了一些进一步的挖掘之后,我遇到了这个问题。 @Remy 请看下面。
我正在使用 TActionMainMenuBar 代替父 MDI 窗体上的 TMainMenu。 TActionMainMenuBar 处理 minimize/restore/maximize 按钮点击的方式与 TMainMenu 不同。下面的代码来自 Vcl.ActnMenus 文件:
type
TInternalMDIAction = class(TWindowAction)
private
{ Private declarations }
public
{ Public declarations }
procedure ExecuteTarget(Target: TObject); override;
end;
procedure TInternalMDIAction.ExecuteTarget(Target: TObject);
begin
case MDIAction of
maActivate: SendMessage(GetParent(Form.Handle), WM_MDIACTIVATE, Form.Handle, 0);
maClose: Form.Close;
maRestore: SendMessage(GetParent(Form.Handle), WM_MDIRESTORE, Form.Handle, 0);
maMinimize: ShowWindow(Form.Handle, SW_MINIMIZE);
end;
end;
我无法捕获最小化事件,因为 ShowWindow 从未调用过 WMSysCommand。我在下面包含了我的修复:
type
TInternalMDIAction = class(TWindowAction)
private
{ Private declarations }
public
{ Public declarations }
procedure ExecuteTarget(Target: TObject); override;
end;
procedure TInternalMDIAction.ExecuteTarget(Target: TObject);
begin
case MDIAction of
maActivate: SendMessage(GetParent(Form.Handle), WM_MDIACTIVATE, Form.Handle, 0);
maClose: Form.Close;
//maRestore: SendMessage(GetParent(Form.Handle), WM_MDIRESTORE, Form.Handle, 0);
//maMinimize: ShowWindow(Form.Handle, SW_MINIMIZE);
maRestore: SendMessage(Form.Handle, WM_SYSCOMMAND, SC_RESTORE, 0);
maMinimize: SendMessage(Form.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
end;
end;
它现在的表现符合我的预期。如果有人看到我可能遗漏的内容或解决由 VCL TActionMainMenuBar 引起的问题的更好方法,请告诉我。谢谢
我需要一些帮助来尝试捕获 MDI 子窗体最大化时的最小化事件。
单击下图中红色圆圈中的按钮时,当表单未最大化时,我能够捕获 minimize/restore/maximize 事件。
我使用 WMSysCommand 捕获上述事件:
procedure TMDIChildForm.WMSysCommand(var Msg: TWMSysCommand);
begin
if Msg.CmdType = SC_MINIMIZE then
begin
//my code here
end;
end;
当我尝试在 MDI 子窗体最大化时使用 WMSysCommand 捕获相同的事件并单击下图中红色圆圈中的按钮时,它不会调用此代码。
无论我尝试过什么,我都没有成功捕捉到这些事件。如果有人能指出我正确的方向,将不胜感激。谢谢。
当我尝试时对我来说效果很好:
type
TMDIChildForm = class(TForm)
private
{ Private declarations }
procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
public
{ Public declarations }
end;
procedure TMDIChildForm.WMSysCommand(var Msg: TWMSysCommand);
begin
inherited; // <-- ADD THIS!!
if Msg.CmdType = SC_MINIMIZE then
begin
// code here
end;
end;
WMSysCommand()
会在 MDI 子项最小化时捕获 SC_MINIMIZE
通知,无论它之前是否按预期最大化。
确保 TMDIChildForm.WMSysCommand()
调用 inherited
(如上所示)将 WM_SYSCOMMAND
消息传递给默认处理程序,以便 Windows 有机会处理它。
在做了一些进一步的挖掘之后,我遇到了这个问题。 @Remy 请看下面。
我正在使用 TActionMainMenuBar 代替父 MDI 窗体上的 TMainMenu。 TActionMainMenuBar 处理 minimize/restore/maximize 按钮点击的方式与 TMainMenu 不同。下面的代码来自 Vcl.ActnMenus 文件:
type
TInternalMDIAction = class(TWindowAction)
private
{ Private declarations }
public
{ Public declarations }
procedure ExecuteTarget(Target: TObject); override;
end;
procedure TInternalMDIAction.ExecuteTarget(Target: TObject);
begin
case MDIAction of
maActivate: SendMessage(GetParent(Form.Handle), WM_MDIACTIVATE, Form.Handle, 0);
maClose: Form.Close;
maRestore: SendMessage(GetParent(Form.Handle), WM_MDIRESTORE, Form.Handle, 0);
maMinimize: ShowWindow(Form.Handle, SW_MINIMIZE);
end;
end;
我无法捕获最小化事件,因为 ShowWindow 从未调用过 WMSysCommand。我在下面包含了我的修复:
type
TInternalMDIAction = class(TWindowAction)
private
{ Private declarations }
public
{ Public declarations }
procedure ExecuteTarget(Target: TObject); override;
end;
procedure TInternalMDIAction.ExecuteTarget(Target: TObject);
begin
case MDIAction of
maActivate: SendMessage(GetParent(Form.Handle), WM_MDIACTIVATE, Form.Handle, 0);
maClose: Form.Close;
//maRestore: SendMessage(GetParent(Form.Handle), WM_MDIRESTORE, Form.Handle, 0);
//maMinimize: ShowWindow(Form.Handle, SW_MINIMIZE);
maRestore: SendMessage(Form.Handle, WM_SYSCOMMAND, SC_RESTORE, 0);
maMinimize: SendMessage(Form.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
end;
end;
它现在的表现符合我的预期。如果有人看到我可能遗漏的内容或解决由 VCL TActionMainMenuBar 引起的问题的更好方法,请告诉我。谢谢