Catch Delphi MDI Child最小化MDI子窗体最大化时的事件

时间:2017-05-10 22:23:40

标签: delphi mdi minimize mdichild wm-syscommand

我需要一些帮助来尝试捕获MDI子窗体最小化时的最小化事件。

当单击下图中以红色圈出的按钮时,表单未最大化时,我能够捕获最小化/恢复/最大化事件。

MDI Child

我使用WMSysCommand捕获上述事件:

procedure TMDIChildForm.WMSysCommand(var Msg: TWMSysCommand);
begin
  if Msg.CmdType = SC_MINIMIZE then
  begin
    //my code here
  end;
end;

当我尝试使用WMSysCommand捕获相同的事件时,MDI子窗体最大化并单击下图中红色圆圈的按钮,它将不会调用此代码。

Maximized MDI Child

无论我尝试过什么,我都没有成功抓住这些事件。如果有人能指出我正确的方向,我将不胜感激。谢谢。

2 个答案:

答案 0 :(得分:1)

当我尝试时,对我来说工作正常:

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;
每当MDI子项被最小化时,

WMSysCommand() 会捕获SC_MINIMIZE通知,无论它是否先前已按预期最大化。

确保TMDIChildForm.WMSysCommand()调用inherited(如上所示)将WM_SYSCOMMAND消息传递给默认处理程序,以便Windows有机会处理它。

答案 1 :(得分:0)

在进一步挖掘后,我遇到了问题。 @Remy请看下面。

我使用TActionMainMenuBar代替父MDI表单上的TMainMenu。 TActionMainMenuBar处理最小化/恢复/最大化按钮的点击次数与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引起的问题,请告诉我。感谢。