【问题标题】:MessageBox return without user input?MessageBox 在没有用户输入的情况下返回?
【发布时间】:2014-06-09 05:38:56
【问题描述】:

我正在尝试在 Win32 项目中实现关闭保存文件对话框,但遇到了一个奇怪的问题。这是我的解决方案。

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

  2. 处理 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;
  1. 处理 WM_SYSCOMMNAD 以显示退出前保存消息框。

    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 确保在所有窗口关闭后终止。


// 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

上面的代码有两个bug:

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

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

怎么会这样,我的代码有什么问题?

【问题讨论】:

    标签: winapi messagebox


    【解决方案1】:

    1、WM_DESTROY的Handler错误,正确的handler应该是:

    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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-13
      • 1970-01-01
      • 2019-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多