1

I need to detect when a form is minimized (to hide overlay form). I intercept WM_SYSCOMMAND message and it works fine if I click the form's minimize button, but this event seems not to be fired if I use [Windows] + [M]. Also, WM_ACTIVATE and WM_ACTIVATEAPP are not triggered in this case.

What event could I use and are there any other situations that I would have to detect?

jpfollenius
  • 16,456
  • 10
  • 90
  • 156
  • 1
    Hooking WM_SIZE will not work as expected without `Application.MainFormOnTaskbar := True;` in the project (AFAIK introduced with D 2007). You might use `Application.OnMinimize` or encapsulated ApplicationEvents.OnMinimize to detect the minimizing of the mainform in such cases. – bummi Nov 25 '13 at 16:00

3 Answers3

6

As explained here, How to detect when the form is being maximized?, listen to the WM_SIZE messages.

Declare in your form:

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

And implementation:

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

Update

See also the answer by @bummi where there is a solution when Application.MainFormOnTaskbar = false.

Community
  • 1
  • 1
LU RD
  • 34,438
  • 5
  • 88
  • 296
6

Since WM_SIZE will not be called on a mainform of a project not using the setting Application.MainFormOnTaskbar := True; I'd suggest an approach, inspired by inspired by @kobik 's answer on , How to detect when the form is being maximized?.

WM_WINDOWPOSCHANGING will be called independed from MainFormOnTaskbar with different signatures on Message.WindowPos^.flags and respond on WIN + M too.

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;
Community
  • 1
  • 1
bummi
  • 27,123
  • 14
  • 62
  • 101
  • +1 thank you very much! That was exactly the problem ('Application.MainFormOnTaskbar` being not set). I will accept the other answer though as it answers the question itself better. – jpfollenius Nov 26 '13 at 07:54
2

Listen for WM_SIZE notification messages with a wParam parameter of SIZE_MINIMIZED.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Any ideas as to when this does not work? It works on a new VCL form but in my actual main form I do not get any WM_SIZE when minimizing :( – jpfollenius Nov 25 '13 at 15:10
  • What's different about your form? – David Heffernan Nov 25 '13 at 15:16
  • I can't see any difference. I will have to investigate this. So far, +1 for both answers. – jpfollenius Nov 25 '13 at 15:30
  • Override WndProc in your main form and see if the message arrives there. Is it even delivered? – David Heffernan Nov 25 '13 at 15:40
  • `WM_SIZE` is generated by `DefWindowProc` when it handles `WM_WINDOWPOSCHANGING` or `WM_WINDOWPOSCHANGED` (I don't remember which, but I believe it's the second one). If the `WM_WINDOWPOSCHANGED` message is not forwarded to DefWindowProc, then you will not get a `WM_SIZE` message. – William Nov 26 '13 at 06:06