Good bye, BEGIN_MSG_MAP!






3.46/5 (17 votes)
May 28, 2005
2 min read

71694

384
A replacement for BEGIN_MSG_MAP macros, using the Boost.MPL library.
Preface
Four yeas ago, I made a program. Everything WTL originally had was useless except Win32 thin wrappers. As CUpdateUI
was the one of them, I made the replacement by macros. Later, I read the book, C++ Template Metaprogramming, and I was inspired by the sample code, the finite state machine. That could remove the macros and the result was named ketchup, intended to replace BEGIN_MSG_MAP
of ATL/WTL.
In time, the experience of making biscuit gave me the way of avoiding compile-time crashes. Now that ketchup is the type-safe synonym of BEGIN_MSG_MAP
to help WTL catch up the modern programming.
Introduction
Ketchup is a message map generator implemented using class templates. The templates allow us to write type-safe BEGIN_MSG_MAP
.
A simple BEGIN_MSG_MAP
macro snippet:
BEGIN_MSG_MAP(CMainFrame) MESSAGE_HANDLER(WM_CREATE, OnCreate) COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit) COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew) COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout) CHAIN_MSG_MAP(WTL::CFrameWindowImpl<CMainFrame>) END_MSG_MAP()
is approximated using Ketchup's facilities as seen in this code snippet:
begin_msg_map < message_handler<WM_CREATE, &_::OnCreate>, command_id_handler<ID_APP_EXIT, &_::OnFileExit>, command_id_handler<ID_FILE_NEW, &_::OnFileNew>, command_id_handler<ID_APP_ABOUT, &_::OnAppAbout>, chain_msg_map< WTL::CFrameWindowImpl<CMainFrame> > > end_msg_map;
Requirements
Microsoft Visual C++ .NET version 7.1, WTL 7.5 and Boost C++ libraries (no build required). I did test the demo in Visual C++ .NET standard edition with Visual C++ toolkit 2003. Ketchup itself is a header-only template library.
Quick Start
- Include a header and derive from
ketchup::message_processor<CMainFrame>
:#include "ketchup/ketchup.hpp" class CMainFrame : public WTL::CFrameWindowImpl<CMainFrame>, public WTL::CUpdateUI<CMainFrame>, public WTL::CMessageFilter, public WTL::CIdleHandler, public ketchup::message_processor<CMainFrame> {
- Define message handlers:
private: LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // create command bar window HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE); // attach menu m_CmdBar.AttachMenu(GetMenu()); // ... } // ...
- Let
CMainFrame
a message map:public: begin_msg_map < message_handler<WM_CREATE, &_::OnCreate>, command_id_handler<ID_APP_EXIT, &_::OnFileExit>, command_id_handler<ID_FILE_NEW, &_::OnFileNew>, command_id_handler<ID_VIEW_TOOLBAR, &_::OnViewToolBar>, command_id_handler<ID_VIEW_STATUS_BAR, &_::OnViewStatusBar>, command_id_handler<ID_APP_ABOUT, &_::OnAppAbout>, chain_msg_map< WTL::CUpdateUI<CMainFrame> >, chain_msg_map< WTL::CFrameWindowImpl<CMainFrame> > > end_msg_map;
- Finally, override
CMessageMap::ProcessWindowMessage
asBEGIN_MSG_MAP
insidiously does, usingprocess_window_message
provided byketchup::message_processor<CMainFrame>
:virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) { return process_window_message(hWnd, uMsg, wParam, lParam, lResult, dwMsgMapID); } };
Bear in mind that declarations of message handlers should be placed before the entry and C++ Standard doesn't allow you to abbreviate the syntax of member function pointers.
Points of interest
The last point is the performance. The program size seems not to be a problem. VC++ 7.1 generates the same size program as the original one, because Ketchup's message map is almost same as BEGIN_MSG_MAP
. But VC++ 7.1 can't inline message handlers, unlike BEGIN_MSG_MAP
. Could this be a problem of the speed?
Well, I did not intend to emulate the appearance of BEGIN_MSG_MAP
. It is not just a syntax sugar but the coincidence as a result of naming consistency with ATL/WTL. It was an amazing discovery for me.
By the way, Ketchup must be the first application using Boost.Xpressive
for the implementation.
References
- Full documentation of the Ketchup message map library
- p-stade
- C++ Template Metaprogramming
- Boost C++ Libraries
- Boost.MPL
- Boost.Xpressive
History
- 23rd May, 2005 - version 0.910 (Initial release).
- 27th May, 2005 - version 0.940.
- 30th May, 2005 - version 0.950 (
class_trace
anddebugging_entry
added). - 12th Jun, 2005 - version 0.951 (
debugging_entry
removed;empty_entry
anddebug_entry
added). - 20th Jul, 2005 - version 0.9992.