Base class: HWND_vpapa
This class provides a WndProc that adds a this pointer and calls a virtual function on
an object. It provides the mechanisms for subclassing an
See the Userís Guide for more discussion.
The constructor is unsurprising.
destructor, virtual, public
The destructor will unhook the class, to ensure that subsequent messages donít get sent to a nonexistant object. The WinProc itself is a thunk thatís a member of this class, so the WinProc function pointer becomes invalid! Normally, the window owns this object so it wonít be destructed until after the window is destroyed, but usage can vary and the situation could be complex, so this is there just to be safe.
This calls the WndProc that the window had before it was subclassed by
a call to hook, or calls
DefWndProc if there wasnít
This calls the -W form of the Win32
This assumes that the current WndProc calling this is itself a Unicode form; that is, it is being sent
Unicode-style messages. This is correct if called from handle_message,
because hook installed it using the -W form of
This returns the original WndProc that was displaced by hook.
See also: call_old_wndproc
This returns the generated callback function that is a thunk to turn a
WNDPROC_2 signature into a call to
handle_message on this instance.
This is the value that hook will use as the WndProc to install. If you want to create a "window class" or dialog box using this function directly, then follow these guidelines to correctly attach this instance with the HWND.
You can call set_window_handle at first opportunity to complete the process, but the hook will automatically set it when it processes the first message, so it is guarenteed to be set by the time handle_message is called.
Note that you need to specify the WndProc when registering the "window class" (wndclass), and then all
windows created will use the same WndProc. Unless the wndclass was designed for only a single window,
this is not suitable for this class, since you must use a different instance of
each window created. So, you may want to call hook anyway, even in
cases when you designed the wndclass, and use a generic (dummy) WndProc in the wndclass. That is,
donít try and avoid calling
hook just because you are not subclassing an existing
For dialog boxes, on the other hand, you specify the DlgProc when you create the specific dialog box.
This mechanism works well in this case. However, you do not want to call
so should never call the base
handle_message from your classís override! Recall that a
Dialog Proc returns TRUE/FALSE (most of the time) to specify whether the message was handled. Your
handle_message should do this when used as a Dialog Proc. So use
Dialog_message_tap, which is
designed specifically for this and takes care of these details and others.
It is an error to call this function after calling set_window_handle (including implicitly setting the window handle upon getting the first message). This catches errors from duplicate use of the same instance.
This function is called by the WndProc of the window to which it is attached.
The sMSG structure (short MSG, since it is a subset (base class) of the
MSG structure) is used to pass the
lParam. Passing a structure rather than four parameters
is better design, and passing by reference is more efficient than re-pushing all the parameters with all the
forwarding going on.
The handling of
WM_NCDESTROY, etc. as it relates to keeping up with this class
is performed higher up in the plumbing before it calls this virtual function. So, you are not compelled to chain
back to this base class implementation from your own classís override. Actually, you canít, due to technical
limitations1 on the mix-in techniques. So the way you
should end the derived classís implementation of this function is with
Likewise, this function does not deal with the pre-translation step. See hook_handler for a description of how these are handled invisibly to you.
Override this to do whatever you want, using the normal Win32 concepts of writing a WndProc. This is a Unicode
WndProc, in that it should receive Unicode versions of messages. This is because the hook
function used the -W form of
SetWindowLong to install the thunk.
Overriding this virtual function in a derived class (or mix-in) is the main point of using the
This function associates this object with the specified Window. Call this after calling Win32
CreateWindow or otherwise obtaining an
HWND to a valid Window.
This function will ďsubclassĒ the window, pointing the WndProc back to this instanceís handle_message function and remembering the old WndProc.
It is an error to call this more than once.
See also: set_window_handle, unhook
This function is the invisible plumbing that allows handle_message to not worry about internal handling and concentrate on the outward functionality.
This is where processing really begins, and it will decide whether to do something very special (unhook on destroy), call pre_translate_message, or call handle_message.
It also catches all exceptions, so they may propagate out of
without problems, and calls the report_error function.
This contains the message code number that is seen as the ďlast messageĒ, and to unhook when it
is processed. It is set at construction time to
WM_NCDESTROY, but it may be changed
This virtual function is called after the window and object are put
together. It fills the role of
WM_INITDIALOG, which canít
be used because the call to hook is made after the window has
Note that if you directly supply a
message_tap as a WndProc, then
on_attach is called much earlier than
WM_CREATE, so your
handle_message function will in this case
WM_CREATE. But if a window is created,
then hook is called, then handle_message
will never get a
WM_CREATE because it was issued long before this class became involved.
So, if this function is used to interact with the Window, not just complete its own data setup, it needs to be aware of when it might be invoked. For other uses, it needs only count on the fact that itís called at first oppertunity once the window handle and object are put together.
This is called when the Tomahawk
message is processed. It basically does the same thing that you could do yourself by handling a
WM_TOMAHAWK message from within your handle_message
function, but itís such a common case, and needed for the Dialog_message_tap
class, that itís already separated out for you.
This should be implemented by derived classes, for those windows that need some kind of message transformation done before dispatching. Specifically, the window that is a modeless dialog box, and any window that uses an Accelerator Table.
For regular windows, call the Win32 primitive
For modeless dialog boxes, call the Win32 primitive
(that is what Dialog_message_tapís override does).
For either, return 1 if the translate call returned
true, or return 2 if the translate call returned
More generally, the return codes for this function are:
true. The caller will see this value and know not to call Win32
false. The caller will see this value and stop searching for something to pre-translate the message, and will continue with the other steps in the message pump (including Win32
This base implementation always returns 0 and does nothing.
This is called by simple_message_pump::pre_translate.
This uses a simple and cheap test to verify that the
this pointer is indeed pointing to a
non-destructed object of (or derived from) class
This is used to trap Windows messages sent after the object is destructed, and to verify that untyped data (such as a generic lParam received in a message) correctly contains a pointer to an object as expected.
The test is not 100% reliable, as random memory could mimic the signature by coincedence, but is handy for spotting bugs and usage errors during development.
You are not expected to unhook a window explicitly, but to leave it hooked until the window is destroyed.
You may call this function to unhook the window, but it will be called automatically in the destructor or when
HWND is closed.
To properly coordinate destroying the object, you must stop sending messages to it once the object
is destroyed! So, part of the shutdown is to attempt to unhook the window proc. If nothing else had hooked
the window after this class, then it restores the old pointer. Otherwise, (if
true) it supplies a
DefWindowProc, breaking the chain.
true if it gracefully restored the window to its prehooked state,
false if it had to be blunt and cut the chain (when
or failed (when
This is automatically called when a
WM_NCDESTROY message is handled, which is
supposedly the last message processed. But who knows? Even if Microsoftís docs are correct, whatís to stop
other code from sending messages directly? This unhooking hardens the code against this case. Also, derived
classes can change this behavior by changing the value in LastMessage.
A future version might go to greater lengths to ensure it really is called last, even with other activity going on.
See also: unhook_when_possible, ~message_tap
Calling this function sets a flag, which instructs the class to unhook itself as soon as it is able, after all objects that subclassed the window after this object have restored their WndProc pointers.
This does not change the fact that the object will be forcably unhooked when
WM_NCDESTROY is seen, as described under unhook.
See also: unhook, ~message_tap
In order for the derived class to automatically hook up the sibling that uses the function (
calls it) with the sibling that provides it (
message_parliament defines it), only one sibling can define it.
Even making it pure virtual in
message_tap isnít enough—it cannot be defined in
at all. Without this careful arrangement, the derived class would have to implement the function too, with
a single line that calls the one in
message_parliament. By defining it in one sibling only, the compiler realizes
that it is providing the meaning for all the other siblings that only call it.