Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

To use DefWindowProc or not to use DefWindowProc

Tags:

c++

winapi

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?

like image 689
Spook Avatar asked Jan 24 '13 11:01

Spook


2 Answers

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.

like image 90
Hans Passant Avatar answered Nov 04 '22 11:11

Hans Passant


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.

like image 24
Spook Avatar answered Nov 04 '22 10:11

Spook