处理来自 DialogBox 的 WM_DESTROY 事件时,MessageBox 将不起作用
MessageBox won't work when handling WM_DESTROY event from DialogBox
在详细说明 的答案(由我自己)时,我想到了使用 MessageBox 来报告对话框结果的想法。它是使用 DialogBox()
函数创建的 WinAPI 模式对话框。
但是,我注意到在对话框的过程函数中处理 WM_DESTROY
会阻止消息框出现。我想了解其背后的机制。
这是完整代码,引用的消息框在最后,就在 return 0
之前:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <string.h>
#include "resource.h"
INT_PTR CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
// uncomment these and the MessageBox won't show up
//case WM_DESTROY:
//PostQuitMessage(0);
//break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
if (MessageBoxW(hwnd, L"Close the window?", L"Confirm", MB_OKCANCEL) == IDOK)
EndDialog(hwnd, (INT_PTR)wParam);
break;
case IDCANCEL:
MessageBoxW(hwnd, L"Goodbye.", L"Close", MB_OK);
EndDialog(hwnd, (INT_PTR)TRUE);
break;
}
}
return (INT_PTR)FALSE;
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
INT_PTR ret = DialogBoxW(NULL, MAKEINTRESOURCEW(IDD_DIALOG1), NULL, DlgProc);
wchar_t retTxt[10];
if (ret == IDOK)
wcscpy(retTxt, L"Alright!");
else
wcscpy(retTxt, L"Error");
MessageBoxW(NULL, retTxt, L"Result", MB_OK);
return 0;
}
当您使用 DialogBox
而不是 DialogBoxParam
时,对话框会运行自己的消息循环,在内部处理 WM_DESTROY
。当您 post 来自您的对话过程的 WM_QUIT
消息时,您正在生成一条对话框不会使用的附加消息*,因此一旦 DialogBox
函数,它就会保留在您线程的消息队列中returns.
然后调用 MessageBox
,它运行自己的消息循环。这会立即将 WM_QUIT
拉出队列,退出循环并在对话框显示之前 returns。
(* 实际上它不是 "real" 消息 - 设置了一个内部标志,指示退出已被 posted - 但在后续消息循环中效果相同)
在详细说明 DialogBox()
函数创建的 WinAPI 模式对话框。
但是,我注意到在对话框的过程函数中处理 WM_DESTROY
会阻止消息框出现。我想了解其背后的机制。
这是完整代码,引用的消息框在最后,就在 return 0
之前:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <string.h>
#include "resource.h"
INT_PTR CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
// uncomment these and the MessageBox won't show up
//case WM_DESTROY:
//PostQuitMessage(0);
//break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
if (MessageBoxW(hwnd, L"Close the window?", L"Confirm", MB_OKCANCEL) == IDOK)
EndDialog(hwnd, (INT_PTR)wParam);
break;
case IDCANCEL:
MessageBoxW(hwnd, L"Goodbye.", L"Close", MB_OK);
EndDialog(hwnd, (INT_PTR)TRUE);
break;
}
}
return (INT_PTR)FALSE;
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
INT_PTR ret = DialogBoxW(NULL, MAKEINTRESOURCEW(IDD_DIALOG1), NULL, DlgProc);
wchar_t retTxt[10];
if (ret == IDOK)
wcscpy(retTxt, L"Alright!");
else
wcscpy(retTxt, L"Error");
MessageBoxW(NULL, retTxt, L"Result", MB_OK);
return 0;
}
当您使用 DialogBox
而不是 DialogBoxParam
时,对话框会运行自己的消息循环,在内部处理 WM_DESTROY
。当您 post 来自您的对话过程的 WM_QUIT
消息时,您正在生成一条对话框不会使用的附加消息*,因此一旦 DialogBox
函数,它就会保留在您线程的消息队列中returns.
然后调用 MessageBox
,它运行自己的消息循环。这会立即将 WM_QUIT
拉出队列,退出循环并在对话框显示之前 returns。
(* 实际上它不是 "real" 消息 - 设置了一个内部标志,指示退出已被 posted - 但在后续消息循环中效果相同)