【问题标题】:How to dispatch messages for multiple dialogs in an ATL exe如何在 ATL exe 中为多个对话框发送消息
【发布时间】:2021-07-18 14:46:09
【问题描述】:

Microsoft 有一个 knowledge base article 描述如何修改 ATL .exe 中的消息循环,以便无模式对话框可以接收适当的消息。

如果您可能有多个无模式对话框,并且您不知道在任何给定时间可能存在哪些对话框,我想知道如何优雅地做到这一点。就像 .exe 可能托管几个不同的 COM 类,每个类都有不同的对话框,谁知道可能会实例化哪一个。

您是否会创建一个全局 hwnd 集,并让每个对话框类在创建时将其 hwnd 放入该集中,然后让消息循环遍历调用 IsDialogMessage(和 TranslateAccelerator)的集?

【问题讨论】:

    标签: winapi dialog atl out-of-process message-loop


    【解决方案1】:

    WTL 对这个挑战的解决方案是有一个专门的消息循环类,它在静态容器中注册自己,以便对话可以发现它们所属线程的消息循环。

    对话框可以通过CMessageLoop::AddMessageFilter 在这些消息循环中注册自己,并在翻译消息时调用它们的回调。

    Example:

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

    【讨论】:

    • 酷,谢谢。那么这是否与 ATL 自己的模块和消息循环一起工作,还是取代它?
    • WTL 通常与 ATL 配合得很好,但两者都有些过时了。如果您对 WTL 感兴趣,您可能想查看 WTL 示例,或者只是查看他们对 CMessageLoop 的使用,以了解他们对多个无模式对话框的解决方案。
    • 或许类似的想法可以通过实现IInputObject和IInputObjectSite来实现。
    【解决方案2】:

    消息指定它的目标(可能是实际对话框的子对象),我将通过一组对话框指针来处理这个问题,然后简单地使用 IsChild() 迭代测试每个集合,并且仅当正确的对话框 HWND发现我会使用 IsDialogMessage。

    另一种方法是从 MSG 中的 HWND 向上遍历祖先树,以某种方式将 HWND 转换为对象,当您到达一个对话框窗口时,使用 IsDialogMessage。

    【讨论】:

    • 只有一个代表激活对话框的全局 hwnd 怎么样?然后每当一个对话框被激活(WM_ACTIVATE),它分配它自己的 hwnd 给全局的。消息循环根据激活对话框 hwnd 检查消息。
    猜你喜欢
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多