【问题标题】:Detect all situations where form is minimized检测所有形式最小化的情况
【发布时间】:2013-11-25 14:27:19
【问题描述】:

我需要检测何时最小化表单(隐藏覆盖表单)。我拦截了WM_SYSCOMMAND 消息,如果我单击表单的最小化按钮,它工作正常,但如果我使用 [Windows] + [M],这个事件似乎不会被触发。此外,WM_ACTIVATEWM_ACTIVATEAPP 在这种情况下不会被触发。

我可以使用什么事件,是否还有其他需要检测的情况?

【问题讨论】:

  • 如果项目中没有Application.MainFormOnTaskbar := True;,挂钩 WM_SIZE 将无法按预期工作(AFAIK 在 D 2007 中引入)。在这种情况下,您可以使用Application.OnMinimize 或封装的 ApplicationEvents.OnMinimize 来检测主窗体的最小化。

标签: windows delphi delphi-xe2


【解决方案1】:

正如这里所解释的,How to detect when the form is being maximized?,收听WM_SIZE 消息。

在您的表格中声明:

procedure WMSize(var Msg: TMessage); message WM_SIZE;

及实施:

procedure TForm1.WMSize(var Msg: TMessage);
begin
  Inherited;
  if Msg.WParam  = SIZE_MINIMIZED then
    ShowMessage('Minimized');
end;

更新

另请参阅@bummi 的答案,Application.MainFormOnTaskbar = false 时有解决方案。

【讨论】:

  • 别忘了inherited;
  • 关于什么时候这不起作用的任何想法?它适用于新的 VCL 表单,但在我的实际主表单中,最小化时我没有得到任何 WM_SIZE :(
  • 我不明白你为什么谈论 WM_GETMINMAXINFO
  • @DavidHeffernan,是的,这与这里无关,已删除。
  • 这在我看来很清楚,检测最大化或最小化是类似的,问题是一样的,如何检测用户按下[Window] + [Special Key],不仅仅是在使用windows时最小化/最大化按钮。
【解决方案2】:

由于不会在不使用设置 Application.MainFormOnTaskbar := True; 的项目的主窗体上调用 WM_SIZE,我建议采用一种方法,灵感来自 @kobik 对 , How to detect when the form is being maximized? 的回答。

WM_WINDOWPOSCHANGING 将独立于 MainFormOnTaskbar 调用,在 Message.WindowPos^.flags 上具有不同的签名,并在 WIN + M 上作出响应。

procedure TForm3.WMWindowPosChanging(var Message: TWMWindowPosChanging);
const
  Hide1=(SWP_NOCOPYBITS or SWP_SHOWWINDOW or SWP_FRAMECHANGED or SWP_NOACTIVATE);
  Hide2=((SWP_HIDEWINDOW or SWP_NOACTIVATE or SWP_NOZORDER or SWP_NOMOVE or SWP_NOSIZE));
begin
  inherited;
  if ((Message.WindowPos^.flags AND Hide1)  = Hide1)
         or ((Message.WindowPos^.flags AND Hide2)  = Hide2)  then
  begin
      Memo1.Lines.Add('Window got minimized');
  end;
end;

【讨论】:

  • +1 非常感谢!这正是问题所在(未设置“Application.MainFormOnTaskbar”)。我会接受另一个答案,因为它可以更好地回答问题本身。
【解决方案3】:

使用 SIZE_MINIMIZED 的 wParam 参数侦听 WM_SIZE 通知消息。

【讨论】:

  • 关于什么时候这不起作用的任何想法?它适用于新的 VCL 表单,但在我的实际主表单中,最小化时我没有得到任何 WM_SIZE :(
  • 你的表单有什么不同?
  • 我看不出有什么不同。我将不得不对此进行调查。到目前为止,两个答案都 +1。
  • 在主窗体中覆盖 WndProc 并查看消息是否到达那里。它甚至交付了吗?
  • WM_SIZEDefWindowProc 在处理WM_WINDOWPOSCHANGINGWM_WINDOWPOSCHANGED 时生成(我不记得是哪个,但我相信它是第二个)。如果WM_WINDOWPOSCHANGED 消息没有转发到 DefWindowProc,那么您将不会收到WM_SIZE 消息。
猜你喜欢
  • 2016-08-07
  • 2017-06-26
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-22
  • 2020-08-22
相关资源
最近更新 更多