当使用对话框作为主窗体时,在使用
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)
对于无模式对话框来说足够了吗?
有问题的代码似乎基于创建无模式对话框。作为文档中描述的示例的动机的场景与这个问题的内容不同:它假设一个动态创建和销毁无模式对话框的 GUI。
此无模式对话框的动态性质通知了示例中展示的消息循环的设计(部分)。对
IsWindow()
的调用专门用于支持单个消息循环体,无论无模式对话框是否处于活动状态,该消息循环体都可以可靠地运行。
由于问题是关于(无模式)对话框和应用程序的生命周期一致的应用程序,因此可以安全地删除
IsWindow()
检查。
IsDialogMessage()
完全是一个不同的野兽。尽管其命名相似,但它并不仅仅验证消息的属性。文档描述其效果为:
确定消息是否用于指定的对话框,如果是,则处理消息。
bold中的部分(而不是其返回值)是我们调用此API的主要原因。 “处理消息”是一种神秘的说法:“实现对话框的键盘接口”。在拥有无模式对话框的线程消息循环上省略对 IsDialogMessage()
的调用会导致该对话框无法进行键盘导航。以类似的方式,
IsDialogMessage()
的返回值比
IsWindow()
的响应“嗯嗯,很高兴知道”更有意义。其处方在细则中详细说明:
由于
IsDialogMessage
函数执行所有必要的消息翻译和分派,因此IsDialogMessage
处理的消息不得传递给TranslateMessage
或DispatchMessage
函数。
返回值记录为:
如果消息已被处理,则返回值非零。总而言之,同时
if (!IsWindow(hwndDialog) || !IsDialogMessage(hwndDialog, &msg))
似乎正在评估两个条件,||
运算符的任一侧都会做截然不同的事情。
当使用对话框作为主窗体时,最低限度的[要求]是什么?如果这是目标,那么事情就简单得多:使用模式对话框并让系统处理实现消息翻译和调度的复杂问题。 已经为您完成了所有操作:它创建对话框、显示对话框并运行消息循环。 您需要对
DlgProc
进行的唯一更改是从
EndDialog()
消息处理程序调用
DestroyWindow()
(而不是
WM_CLOSE
)以退出系统启动的消息循环。