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 toALT_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 theWindowProc
method in yourCWindowImpl
-derived class and callProcessWindowMessage
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:
How they get called. (How does the code know about the existence of the alternate message maps?)
How they differ from default message maps. They all look like they're handling the same kinds of messages for the same windows...
Why they are useful. (Aren't they all for the same window anyway?)
Does anyone have a better explanation for what alternate message maps do?
(A motivation for why they were invented would be very helpful.)
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.