0

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

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

MDI 儿童

我使用 WMSysCommand 捕获上述事件:

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

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

最大化 MDI 儿童

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

4

2 回答 2

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;

WMSysCommand() 确实会在 MDI 子项最小化时捕获SC_MINIMIZE通知,无论它之前是否已按预期最大化。

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

于 2017-05-10T22:35:23.683 回答
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 引起的问题的更好方法,请告诉我。谢谢。

于 2017-05-11T20:37:59.407 回答