Reputation: 313
I am in need of some help trying to capture the minimize event of an MDI Child form when it is maximized.
I am able to capture the minimize/restore/maximize events when the form is not maximized when clicking the buttons circled in red in the image below.
I capture the aforementioned events by using WMSysCommand:
procedure TMDIChildForm.WMSysCommand(var Msg: TWMSysCommand);
begin
if Msg.CmdType = SC_MINIMIZE then
begin
//my code here
end;
end;
When I try to capture the same events using WMSysCommand when the MDI Child form is maximized and clicking the buttons circled in red in the image below, it will not call this code.
No matter what I have tried I have been unsuccessful in catching these events. If someone could point me in the right direction it would be greatly appreciated. Thank you.
Upvotes: 0
Views: 1319
Reputation: 313
After doing some further digging I've come across the problem. @Remy please see below.
I am using TActionMainMenuBar in place of a TMainMenu on the parent MDI form. The TActionMainMenuBar handles the minimize/restore/maximize button clicks differently than that of TMainMenu. The code below is from the Vcl.ActnMenus file:
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;
I am unable to catch the minimize event because WMSysCommand is never called by ShowWindow. I have included my fix below:
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;
It is now performing as I would expect it to. If anyone sees something I might have missed or a better way of fixing the problem caused by VCL TActionMainMenuBar please let me know. Thanks.
Upvotes: 0
Reputation: 595319
Works fine for me when I try it:
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()
does capture the SC_MINIMIZE
notification whenever the MDI child is minimized, regardless of whether it was previously maximized or not, as expected.
Make sure TMDIChildForm.WMSysCommand()
calls inherited
(as shown above) to pass the WM_SYSCOMMAND
message to the default handler so Windows has a chance to process it.
Upvotes: 1