5

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:

  • 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.)

user541686
  • 205,094
  • 128
  • 528
  • 886
  • 3
    ATL and WTL ship as source code. You can just read it to see how it works. – Raymond Chen Aug 08 '12 at 05:37
  • 1
    @RaymondChen: That's what I tried (with ATL and WTL), but nowhere did I see references to the additional message maps. I see the message maps declared, but I can't tell how they're getting called (the argument to `ALT_MSG_MAP` looks like a magic number to me, used nowhere else), or what their point is. – user541686 Aug 08 '12 at 05:45
  • 3
    `BEGIN_MSG_MAP` begins the function `ProcessWindowMessage` and opens a switch statement. `ALT_MSG_MAP` adds a new case to the switch statement. [The documentation for `ALT_MSG_MAP`](http://msdn.microsoft.com/library/8d3ws24d) says that it is used by `CContainedWindow`, and [the documentation for `CContainedWindow`](http://msdn.microsoft.com/library/9e286yks) gives an example. – Raymond Chen Aug 08 '12 at 06:00
  • @RaymondChen: That would make sense, except that what confuses me about it is that I don't see a single trace of `CContainedWindow` in WTL, and yet they are using `ALT_MSG_MAP` somehow: http://wpack.googlecode.com/svn-history/r3/trunk/thirdparty/wtl/atlctrls.h ... or perhaps I'm looking in the wrong place? – user541686 Aug 08 '12 at 06:03
  • @RaymondChen: Furthermore, in the Windows 2003 DDK, in `atlframe.h` (essentially an old version of WTL), I see `COwnerDraw` uses `ALT_MSG_MAP(1)`, with no trace of `CContainedWindow` (or any other class) anywhere. There's *got* to be something I'm missing... – user541686 Aug 08 '12 at 06:05
  • Perhaps other classes use alternate message maps too. – Raymond Chen Aug 08 '12 at 06:50
  • @RaymondChen: Yeah probably, but I'm not sure how. Hopefully someone who knows what they're used for throughout WTL and everything can answer this, since WTL is already confusing with its liberal use of templated class/CRTP, and this isn't helping... it's confusing the heck out of me, trying to figure out when exactly I should use alternate message maps when making my own controls. (Though if you don't know the use case here, I guess I'm not too hopeful others who see this will, either...) Thanks for trying to help anyhow. – user541686 Aug 08 '12 at 07:05
  • 2
    They may not be using `CContainedWindow`, but they do use `CHAIN_MSG_MAP_ALT` which also uses alternate message maps. – Raymond Chen Aug 13 '12 at 23:13

1 Answers1

5

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.

Roman R.
  • 68,205
  • 6
  • 94
  • 158