我正在尝试将一个close-save-file对话框实现到Win32项目中,但是却遇到了一个奇怪的问题。这是我的解决方案。
在Visual Studio中创建一个简单的win32项目。
处理WM_COMMAND以创建新窗口。
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
InitInstance(hInst, SW_SHOW);
//DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
windowCount--;
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_SYSCOMMAND:
if (wParam == SC_CLOSE) {
int ret = MessageBox(NULL, L"do you really want to close", L"question", MB_YESNO|MB_APPLMODAL);
if (ret == IDNO)
return 0;
closedCount++;
StringCchPrintf(buff, 256, L"hwnd %x user choose to close\n", hWnd);
OutputDebugString(buff);
}
return DefWindowProc(hWnd, message, wParam, lParam);
closeCount
和windowCount
,以确保在所有窗口关闭后终止。
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0) || (closedCount != windowCount))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
windowCount++;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
完整代码:http://pastebin.com/EVWWMz8L
上面的代码中有两个错误:
创建两个窗口并单击每个窗口的关闭按钮,然后确认关闭一个窗口将关闭两个窗口。这意味着,在一个窗口中关闭MessageBox会导致其他窗口中的MessageBox在没有任何用户输入的情况下返回。
创建两个窗口,然后单击每个窗口的关闭按钮。然后使用aero缩略图激活一个消息框并确认关闭,但关联的窗口不会关闭。我需要确认两个消息框都关闭窗口。
这怎么可能发生,我的代码出了什么问题?
答案 0 :(得分:0)
1,WM_DESTROY处理程序错误,右边处理程序应为:
case WM_DESTROY: {
StringCchPrintf(buff, 256, L"%x recieved Wm-DESTROY\n", hWnd);
OutputDebugString(buff);
closedCount++;
if (closedCount == windowCount) {
PostQuitMessage(0);
}
}
完整代码:http://pastebin.com/EU7cVKUb
根本原因:
PostQuitMessage
终止MessageBox / DialogBox消息循环,导致它们丢失并立即返回。总之,在你真的需要这样做之前不要调用PostQuitMessage。
2,MessageBox / DialogBox应该有所有者窗口,否则用户可以使用alt + tab / aero-thumbnail选择该框。因此,使用hwnd创建消息框,因为父级可以解决问题2.