I'm currently writing my own mini visual framework to wrap pure WinAPI in classes.
Currently the process of analyzing messages looks as follows:
static Application::Run
has a message loop; it gets new message and dispatches it to apropriate WndProc.
All windows I create are created from the same class (in terms of WinAPI), so the same WndProc
is being called. Actually, it's a static FormAPI::WndProc
method. This one checks, which window the message refers to and calls its WndProc
.
Form::WndProc
method is called, which analyzes message. Suppose, that it's a WM_MOUSEMOVE
. It calls ProcessMouseMove
and then DefWindowProc
. Remember this point as [1].
private Form::ProcessMouseMove
gets the actual data from the message (eg. x, y, shift state), converts it into usable data and calls protected Form::OnMouseMove
.
Finally, protected OnMouseMove
checks, whether event handler is set (that is, std::function<void(Form *, int, int, ShiftState)>
) and if so, it calls the handler. Otherwise it does nothing.
My concern is about calling DefWindowProc
. It may seem, that its simply "do the default behavior for me", but sometimes it actually does some critical stuff. For instance, disabling WM_LBTNDOWN
by not calling DefWindowProc
will result in inability to close window by clicking the [X] button.
On the other hand, sometimes I don't want to call DefWindowProc
. For instance, if WM_CLOSE
comes, I may decide not to close application. DefWindowProc
in this case calls DestroyWindow
.
My question is: should I call the DefWindowProc
or not? If so, always or only sometimes?
You've got three choices when deciding how to handle a message:
Not calling DefWindowProc(). Appropriate when you want to completely customize the way the message is handled and do not want the default implementation. WM_COMMAND and WM_PAINT are typical examples.
Do something custom, then calling DefWindowProc(). Appropriate when you like or need the default implementation. WM_CLOSE is a typical example.
First call DefWindowProc(), then altering the result if appropriate. A typical example is WM_NCHITTEST
There is no golden rule to select the appropriate choice, it depends a great deal on the specific message and the specific default handling for the window. Note that this may not be the documented default handling if you are subclassing a window. Getting it wrong is however generally easy to diagnose.
It seems, that I've answered my question simply by asking it. I presented two cases:
WM_LBTNDOWN
when DefWindowProc
has to be called - otherwise window won't work properly;WM_CLOSE
, when - depending on event handler - DefWindowProc
must not be called - otherwise it'll break the framework's logic.The answer is then: it depends on kind of message. I have to read carefully, how DefWindowProc works in every case and act appropriately.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With