I was inspired by a recent post by Brent Simmons to write about some ancient C++ code I wrote back in the min-90’s. At that time I was just learning to develop Windows applications in C and C++ was just starting to get some traction, not unlike Swift in the Mac and iOS community today.
When you created a Windows application you’d have to write a WindowProc (Windows Procedure) that would process all messages for a particular window. A Window Proc would receive a message and other parameters. You’d switch on the message and the WPARAM and LPARAM parameters would contain other information specific to a particular message. It was well documented, but it was quite ugly.
Believe it or not this is how a lot of your favorite Windows applications were originally written. Giant switch statements that dissected two other values to determine how to respond to different types of messages.
When I started learning C++ I was trying to find a way to create a Window Proc that didn’t have to implement every Windows message in the system, there must be thousands of them. Could you imagine a base C++ class that responded to every Windows API message in the system? I can’t. It would be a real mess to deal with.
It took me quite a while to come up with a way to do it. I happened upon the answer in the C++ FAQ. This would allow me to create a base class that provided one Window Proc that would look in a dispatch table (a map) to see if the Windows Message was handled by the Window in question.
Here’s what it looked like. I hope this gets the point across.
When you implemented a Window Proc class you would derive from a base class and provide it with a message dispatch table (at the top of the above gist.) The dispatch table would direct the base classes Window Proc to call the correct handler for a specific message.
Notice that this Window Proc is a straight C function. That’s how the Windows API operates. It’s a C based API, but it provides a mechanism to attach user provided data to a Window Procedure. That’s how this operates. When the Windows WM_CREATE message is sent it includes a this pointer to derived Window Class, which can be looked up later based on the HWND identifier.
In the gist above the code that calls pWindow->DispatchMessage knows how to look at the dispatch table and direct the message to the appropriate pointer to a method.
The code that knows how to send a message to a particular method is (this->*pHandler)(wParam, lParam). This is dereferencing a pointer to a method. All methods have the same signature, which is consistent with how the Windows API works.By the way. This code still builds and runs with up to date versions of Visual Studio on Windows 10. A lot of this code was written in 1995 and has been tweaked over time to keep it up to date with changes to the Windows API.
As I’ve said before, old code never dies.
If you’re feeling really brave you’re welcome to grab my crusty old C++ library and build the simple sample application on your Windows box. Please note, the code is provided as is without warranty, expressed or implied.