对话框的消息处理

问题描述 投票:0回答:1

当使用对话框作为主窗体时,在使用

TranslateMessage
DispatchMessage
之前最少要进行哪些检查?代码中:

MSG msg;
BOOL ret;

hwndDialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), nullptr, (DLGPROC)DialogProc);
ShowWindow(hwndDialog, SW_SHOW);

while ((ret = GetMessage(&msg, 0, 0, 0)) != 0) {
    if (ret == -1) {
        return -1;
    }
    if (!IsWindow(hwndDialog) || !IsDialogMessage(hwndDialog, &msg)) { // are all these checks needed?
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
return 0;

需要

!IsWindow(hwndDialog)
!IsDialogMessage(hwndDialog, &msg)
条件吗?简单的:
if (hwndDialog== (HWND) NULL)
对于无模式对话框来说足够了吗?

c++ winapi
1个回答
0
投票

有问题的代码似乎基于创建无模式对话框。作为文档中描述的示例的动机的场景与这个问题的内容不同:它假设一个动态创建和销毁无模式对话框的 GUI。

此无模式对话框的动态性质通知了示例中展示的消息循环的设计(部分)。对

IsWindow()
的调用专门用于支持单个消息循环体,无论无模式对话框是否处于活动状态,该消息循环体都可以可靠地运行。

由于问题是关于(无模式)对话框和应用程序的生命周期一致的应用程序,因此可以安全地删除

IsWindow()
检查。

IsDialogMessage()
完全是一个不同的野兽。尽管其命名相似,但它并不仅仅验证消息的属性。文档描述其效果为:

确定消息是否用于指定的对话框,如果是,则

处理消息

bold中的部分(而不是其返回值)是我们调用此API的主要原因。 “处理消息”是一种神秘的说法:“实现对话框的键盘接口”。在拥有无模式对话框的线程消息循环上省略对 IsDialogMessage()

 的调用会导致该对话框无法进行键盘导航。

以类似的方式,

IsDialogMessage()

的返回值比
IsWindow()
的响应“嗯嗯,很高兴知道”更有意义。其处方在
细则中详细说明:

由于

IsDialogMessage

 函数执行所有必要的消息翻译和分派,因此 
IsDialogMessage
 处理的消息不得传递给 
TranslateMessage
DispatchMessage
 函数。

返回值记录为:

如果消息已被处理,则返回值非零。

总而言之,同时

if (!IsWindow(hwndDialog) || !IsDialogMessage(hwndDialog, &msg))
似乎正在评估两个条件,

||

运算符的任一侧都会做截然不同的事情。


基础工作完成后,让我们解决所提出的问题:

当使用对话框作为主窗体时,最低限度的[要求]是什么?

如果这是目标,那么事情就简单得多:使用模式对话框并让系统处理实现消息翻译和调度的复杂问题。

DialogBoxW()

 已经为您完成了所有操作:它创建对话框、显示对话框并运行消息循环。

您需要对

DlgProc

 进行的唯一更改是从 
EndDialog()
 消息处理程序调用 
DestroyWindow()
(而不是 
WM_CLOSE
)以退出系统启动的消息循环。

© www.soinside.com 2019 - 2024. All rights reserved.