MessageBox返回没有用户输入?

时间:2014-06-09 05:38:56

标签: winapi messagebox

我正在尝试将一个close-save-file对话框实现到Win32项目中,但是却遇到了一个奇怪的问题。这是我的解决方案。

  1. 在Visual Studio中创建一个简单的win32项目。

  2. 处理WM_COMMAND以创建新窗口。

  3. 
    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;
    
    1. 处理WM_SYSCOMMNAD以显示save-before-quit消息框。
    2. 
          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);
      
      1. 两个变量closeCountwindowCount,以确保在所有窗口关闭后终止。
      2. 
        
        // 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

        上面的代码中有两个错误:

        1. 创建两个窗口并单击每个窗口的关闭按钮,然后确认关闭一个窗口将关闭两个窗口。这意味着,在一个窗口中关闭MessageBox会导致其他窗口中的MessageBox在没有任何用户输入的情况下返回。

        2. 创建两个窗口,然后单击每个窗口的关闭按钮。然后使用aero缩略图激活一个消息框并确认关闭,但关联的窗口不会关闭。我需要确认两个消息框都关闭窗口。

        3. 这怎么可能发生,我的代码出了什么问题?

1 个答案:

答案 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.