Как работают карты альтернативных сообщений ATL/WTL (ALT_MSG_MAP)? Когда я их использую?

Я прочитал документация, в которой говорится:

ATL поддерживает карты альтернативных сообщений, объявленные с помощью макроса ALT_MSG_MAP.
Каждая карта альтернативных сообщений идентифицируется уникальным номером, который вы передаете макросу ALT_MSG_MAP.
Используя карты альтернативных сообщений, вы можете обрабатывать сообщения нескольких окна в одной карте.
Обратите внимание, что по умолчанию CWindowImpl не использует альтернативные карты сообщений.
Чтобы добавить эту поддержку, переопределите метод WindowProc в классе, производном от CWindowImpl, и вызовите ProcessWindowMessage с картой сообщений. идентификатор.

И когда я смотрю на WTL, я вижу такие карты сообщений, как:

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()

Однако я не понимаю:

  • Как их вызывают. (Как код узнает о существовании альтернативных карт сообщений?)

  • Чем они отличаются от карт сообщений по умолчанию. Все они выглядят так, как будто обрабатывают одни и те же сообщения для одних и тех же окон...

  • Почему они полезны. (Разве они все равно не для одного и того же окна?)

Есть ли у кого-нибудь лучшее объяснение того, что делают альтернативные карты сообщений?
(Мотивация того, почему они были изобретены, была бы очень полезна.)


person user541686    schedule 08.08.2012    source источник
comment
ATL и WTL поставляются в виде исходного кода. Вы можете просто прочитать его, чтобы увидеть, как это работает.   -  person Raymond Chen    schedule 08.08.2012
comment
@RaymondChen: это то, что я пробовал (с ATL и WTL), но нигде не видел ссылок на дополнительные карты сообщений. Я вижу объявленные карты сообщений, но не могу сказать, как они вызываются (аргумент ALT_MSG_MAP выглядит для меня как магическое число, больше нигде не используется) или в чем их смысл.   -  person user541686    schedule 08.08.2012
comment
BEGIN_MSG_MAP начинает функцию ProcessWindowMessage и открывает оператор switch. ALT_MSG_MAP добавляет новый случай в оператор switch. В документации для ALT_MSG_MAP указано, что он используется CContainedWindow, и документация для CContainedWindow дает пример.   -  person Raymond Chen    schedule 08.08.2012
comment
@RaymondChen: Это имело бы смысл, за исключением того, что меня смущает то, что я не вижу ни единого следа CContainedWindow в WTL, и тем не менее они каким-то образом используют ALT_MSG_MAP:   -  person user541686    schedule 08.08.2012
comment
@RaymondChen: Кроме того, в Windows 2003 DDK, в atlframe.h (по сути, старой версии WTL), я вижу, что COwnerDraw использует ALT_MSG_MAP(1), без следов CContainedWindow (или любого другого класса) где-либо. Должно быть что-то, чего мне не хватает...   -  person user541686    schedule 08.08.2012
comment
Возможно, другие классы тоже используют альтернативные карты сообщений.   -  person Raymond Chen    schedule 08.08.2012
comment
@RaymondChen: Да, возможно, но я не уверен, как это сделать. Надеюсь, кто-то, кто знает, для чего они используются в WTL и во всем, может ответить на этот вопрос, поскольку WTL уже сбивает с толку своим либеральным использованием шаблонного класса/CRTP, и это не помогает... это чертовски сбивает меня с толку, пытаясь выяснить, когда именно я должен использовать альтернативные карты сообщений при создании своих собственных элементов управления. (Хотя, если вы не знаете здесь прецедент, я думаю, я не слишком надеюсь, что другие, кто это увидит, тоже...) В любом случае спасибо за попытку помочь.   -  person user541686    schedule 08.08.2012
comment
Возможно, они не используют CContainedWindow, но используют CHAIN_MSG_MAP_ALT, который также использует альтернативные карты сообщений.   -  person Raymond Chen    schedule 14.08.2012


Ответы (1)


Альтернативная карта сообщений позволяет определить обработчики сообщений в той же карте для сообщений других окон. Взгляните на свою карту выше:

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

Это класс CCommandBarCtrlImpl, с ним связан дескриптор окна, HWND. Все сообщения проходят через карту по умолчанию (строки выше ALT_MSG_MAP(1)).

Не по какой-то причине класс хочет обрабатывать сообщения родителя. Он подклассифицирует его, используя переменную класса-члена, и вы подходите к моменту, когда вам нужно определить обработчики сообщений. Вы не можете добавить их прямо на ту же карту, потому что это может привести к путанице с собственными оконными сообщениями.

Здесь на помощь приходят альтернативные карты. Сообщения родительского окна направляются на альтернативную карту сообщений номер 1.

Вам не нужны альтернативные карты, если вы обрабатываете только сообщения своего собственного окна.

person Roman R.    schedule 08.08.2012