BEGIN_MESSAGE_MAP vs Dispatch vs WndProc

66 Views Asked by At

After reading a lot on this, I came to conclusion that these 3 are essentially the same things of processing custom messages:

Using BEGIN_MESSAGE_MAP macro:

#define WM_CUSTOM_MESSAGE WM_APP + 12345

BEGIN_MESSAGE_MAP
    VCL_MESSAGE_HANDLER(WM_CUSTOM_MESSAGE, TMessage, WMCustomMessageHandler);
END_MESSAGE_MAP(TForm)

void TForm1::WMCustomMessageHandler(TMessage &message)
    {
    // <code to handle custom message here>
    }

Or expanding it and directly overriding Dispatch() (the same what above does):

void __fastcall TForm1::Dispatch(void* message)
    {
    switch ((TMessage*)message->Msg)
        {
        case WM_CUSTOM_MESSAGE: // <code to handle custom message here>
                                break;

        default:                TForm::Dispatch(message);
                                break; 
        }
    }

or overriding WndProc:

void __fastcall TForm1::WndProc(TMessage &message)
    {
    switch (message.Msg)
        {
        case WM_CUSTOM_MESSAGE: // <code to handle custom message here>
                                message.Result = 0;
                                break; 

        default:                TForm::WndProc(message);
                                break;
        }
    }

Is there an advantage of using one over another in this example? From what I gathered the first two methods are higher level and the last one is lower level though not sure what difference would it made.

The reason why I am asking is because I get WM_SETICON message which occasionally crashes with read of address 00000018, when my program exits (the crash traces to TForm::WndProc(message);). It could be a bug in my program, but may also be a bug in RAD Studio 10.4.2 which I am using. However this didn't seem to be the problem while I was using BEGIN_MESSAGE_MAP and I switched to WndProc for readability.

Another way of fixing this is perhaps to remove WndProc to default one (e.g. save DefaultWndProc and then this->WindowProc = DefaultWndProc;), just prior to exiting the program (OnClose event) which I find rather unnecessary since the above code really doesn't do anything different than original WndProc when there is no custom message being handled as it crashes for WM_SETICON, or am I mistaken here?

0

There are 0 best solutions below