I have defined a WndProc
which looks similar to below (the code is written in C Builder, but it applies in similar form to Delphi as well):
#define WM_SETTINGS_UPDATE WM_APP 1234
#define WM_GUI_UPDATE WM_APP 1235
void __fastcall TForm1::WndProc(TMessage &fMessage)
{
switch (fMessage.Msg)
{
default: break;
case WM_SETTINGS_UPDATE: ProcessMySettingsUpdate();
fMessage.Result = 1;
return;
break; // I know this is not needed, I do this purely for aesthetics
case WM_GUI_UPDATE: ProcessMyGUIUpdate();
fMessage.Result = 1;
return;
break; // I know this is not needed, I do this purely for aesthetics
}
TForm::WndProc(fMessage);
}
So in essence this:
checks for my custom
WM_APP
range messages (WM_SETTINGS_UPDATE
andWM_GUI_UPDATE
) in this case.processes those messages and then sets
fMessage.Result
to1
indicating message was processed and returns (avoidingTForm:WndProc(fMessage)
, which I understand is the same asinherited
in Delphi, and not needed if the message is processed).if my messages are not processed, it just calls
TForm:WndProc(fMessage)
(orinherited
) to do the default processing.
My concern is this - what if there is a situation where the application is shutting down, and there are still some messages being unprocessed (left in the message queue by PostMessage()
)?
What I'd like to do in such a situation is to avoid calling my own processing, as it might result in some uninitialized memory Access Violations or similar. Is this basically enough, or do I need to apply some special processing to avoid that kind of situation, or process some "application shutting down" code?
And also - do I need to call inherited
/ TForm:WndProc(fMessage)
after I am done with my processing, or is it safe to do it like above (set Result
to 1 and return)?
Note - this does not necessarily apply to the MainForm
(the first Form being created).
CodePudding user response:
what if there is a situation where the application is shutting down, and there are still some messages being unprocessed (left in the message queue by
PostMessage()
)?
That is perfectly OK. Once a Form's HWND
is destroyed, any remaining messages that were posted for that window will simply be discarded when dispatched by the main message loop. Your WndProc
will not be called for them.
What I'd like to do in such a situation is to avoid calling my own processing, as it might result in some uninitialized memory Access Violations or similar.
That should not be a concern. One, because messages won't be dispatched to your Form's HWND
after it is destroyed, and two, when the MainForm
is closed, the main message loop is signaled to stop running, before any active Form HWND
s are destroyed. So, there won't be any further message dispatching anyway.
Is this basically enough, or do I need to apply some special processing to avoid that kind of situation
It should be enough. You typically do not need to handle this special (unless your custom messages are carrying pointers to objects that have to be freed).
or process some "application shutting down" code?
If you really want to detect when the app is being shut down, try having your WndProc
handle the WM_CLOSE
message (or you can use the Form's OnClose/Query
events).
do I need to call
inherited
/TForm:WndProc(fMessage)
after I am done with my processing, or is it safe to do it like above (setResult
to 1 and return)?
That is perfectly OK for custom messages.