Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do modal Delphi forms not receive WM_SYSCOMMAND when the user clicks the task bar button?

In a Delphi (2007) program, running on Windows 8.1, I would like to get notified when the user clicks on the task bar button belonging to my program. So I am trapping the WM_SYSCOMMAND which usually gets send in that case.

This works fine for program's main window.

If a modal window is active (opened with Form2.ShowModal), the same code cannot trap the WM_SYSCOMMAND, neither in the main for nor in the modal form. What is different? And is there any way to change this?

This is the code I have added to both forms:

unit unit1;

interface

type
  TForm1 = class(TForm)
    // [...]
    procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
  end;

 // [...]

implementation

 // [...]

procedure Tf_dzProgressTest.WMSysCommand(var Msg: TWMSysCommand);
begin
  inherited; // place breakpoint here
end;

 // [...]

end.

I also tried to use Application.OnMessage or a TApplicationEvents component and even overriding the form's WndProc method. Neither could trap WM_SYSCOMMAND while a modal form was active.

like image 269
dummzeuch Avatar asked Mar 17 '16 11:03

dummzeuch


1 Answers

When you click on the task bar button, the system attempts to execute the minimize action for the window associated with the task bar button. Typically that is the window for the main form. That is where the WM_SYSCOMMAND originates.

Now, when a modal form is showing, the main form is disabled. It was disabled with a call to the Win32 EnableWindow function. That is an integral part of modality. The modal window is the only enabled top level window because you are not supposed to interact with any other top level window.

When a window is disabled, its system menu is also disabled. That is why the system is unable to perform the minimize action, and why you do not receive WM_SYSCOMMAND.

There's not a whole lot that you can do about this. Once you show a modal form, the main window has to be disabled. And at that point it is not going to receive WM_SYSCOMMAND and is not going to find out that the user clicked the task bar button.

like image 113
David Heffernan Avatar answered Nov 10 '22 03:11

David Heffernan