如何在 ATL exe 中为多个对话框发送消息

问题描述

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

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

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

解决方法

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

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

,

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...