How to dispatch messages for multiple dialogs in an ATL exe

112 views Asked by At

Microsoft had a knowledge base article describing how to modify the message loop in at ATL .exe so that modeless dialogs can receive appropriate messages.

I was wondering how to elegantly do this if you have potentially multiple modeless dialogs, and you don't know which dialogs might exist at any given time. Like perhaps the .exe hosts several different COM classes, each with different dialogs, and who knows which one might be instantiated.

Would you create a global set of hwnds, and have each dialog class place its hwnd in the set upon creation, and then have the message loop iterate through the set calling IsDialogMessage (and TranslateAccelerator)?

2

There are 2 answers

1
SoronelHaetir On

The message specifies its target (which might be a child of the actual dialog), I would handle this by having a set of dialog pointers and then simply iterate the set testing each with IsChild() and only when the right dialog HWND is found would I use IsDialogMessage.

The alternative is to walk up the ancestor tree from the HWND in the MSG translating HWNDs to objects somehow and when you get to a window that is a dialog use IsDialogMessage.

3
Roman Ryltsov On

WTL's solution for this challenge is to have a specialized message loop class which registers itself in static container so that dialogs could discover message loops for the threads they belong to.

Dialogs can register themselves with these message loops via CMessageLoop::AddMessageFilter and have their callbacks invoked once it comes to translating the messages.

Example:

    // register object for message filtering and idle updates
    CMessageLoop* pLoop = _Module.GetMessageLoop();
    ATLASSERT(pLoop != NULL);
    pLoop->AddMessageFilter(this);
    pLoop->AddIdleHandler(this);