winapivisual-c++atlwtlmessage-map

How do ATL/WTL alternative message maps (ALT_MSG_MAPs) work? When do I use them?


I've read the documentation, which says:

ATL supports alternate message maps, declared with the ALT_MSG_MAP macro.
Each alternate message map is identified by a unique number, which you pass to ALT_MSG_MAP.
Using alternate message maps, you can handle the messages of multiple windows in one map.
Note that by default, CWindowImpl does not use alternate message maps.
To add this support, override the WindowProc method in your CWindowImpl-derived class and call ProcessWindowMessage with the message map identifier.

And when I look at WTL, I see message maps like:

BEGIN_MSG_MAP(CCommandBarCtrlImpl)
    MESSAGE_HANDLER(WM_CREATE, OnCreate)
    MESSAGE_HANDLER(WM_FORWARDMSG, OnForwardMsg)
    ...
ALT_MSG_MAP(1)   // Parent window messages
    MESSAGE_HANDLER(WM_INITMENUPOPUP, OnParentInitMenuPopup)
    ...
ALT_MSG_MAP(2)   // MDI client window messages
    // Use CMDICommandBarCtrl for MDI support
ALT_MSG_MAP(3)   // Message hook messages
    MESSAGE_HANDLER(WM_MOUSEMOVE, OnHookMouseMove)
    ...
END_MSG_MAP()

However, I don't understand:

Does anyone have a better explanation for what alternate message maps do?
(A motivation for why they were invented would be very helpful.)


Solution

  • Alternative message map let's you define message handlers within the same map for messages of other windows. Take a look at your map above:

    BEGIN_MSG_MAP(CCommandBarCtrlImpl)
        MESSAGE_HANDLER(WM_CREATE, OnCreate)
        MESSAGE_HANDLER(WM_FORWARDMSG, OnForwardMsg)
        ...
    ALT_MSG_MAP(1)   // Parent window messages
        MESSAGE_HANDLER(WM_INITMENUPOPUP, OnParentInitMenuPopup)
        ...
    

    This is class CCommandBarCtrlImpl, it has a window handle associated with it, HWND. All messages go through default map (lines above ALT_MSG_MAP(1)).

    Not for some reason, the class wants to handle messages of the parent. It subclasses it using a member class variable, and you come to the point where you need to have your message handlers defined. You cannot add them right into the same map because it would be a confusion with its own window messages.

    This is where alternate maps come to help. Parent window messages are routed to alternative message map number 1.

    You don't need alternate maps if you only handle messages of your own window.