处理来自 DialogBox 的 WM_DESTROY 事件时,MessageBox 将不起作用 [英] MessageBox won't work when handling WM_DESTROY event from DialogBox

查看:25
本文介绍了处理来自 DialogBox 的 WM_DESTROY 事件时,MessageBox 将不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在为另一个问题(我自己)详细阐述答案时,我想到了使用MessageBox 来报告我的对话框的结果.它是一个使用 DialogBox() 函数创建的 WinAPI 模态对话框.

While elaborating an answer for another question (by myself), I've come up with the idea of using a MessageBox to report the result of my dialog box. It is a WinAPI modal dialog box created with the DialogBox() function.

但是,我注意到在对话框的过程函数中处理 WM_DESTROY 会阻止消息框出现.我想了解这背后的机制.

However, I noticed that handling WM_DESTROY in the dialog's procedure function will prevent the message box from appearing. I would like to understand the mechanics behind that.

这是完整的代码,引用的消息框在末尾,就在 return 0 之前:

Here's the full code, and the referred message box is at the end, right before 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 内部.当您从对话框过程中发布 WM_QUIT 消息时,您正在生成一个对话框不会使用的附加消息*,因此一旦 DialogBox 函数返回.

When you use DialogBox rather than DialogBoxParam, the dialog runs its own message loop that handles WM_DESTROY internally. When you post the WM_QUIT message from your dialog procedure you are generating an additional message* that the dialog box won't use, so it remains in your thread's message queue once the DialogBox function returns.

然后调用 MessageBox,它运行自己的消息循环.这会立即将 WM_QUIT 拉出队列,退出循环并在对话框显示之前返回.

You then call MessageBox, which runs its own message loop. This immediately pulls the WM_QUIT out of the queue, exits the loop and returns before the dialog is even displayed.

(* 实际上它不是一个真实的"消息 - 设置了一个内部标志,表明已发布退出 - 但在随后的消息循环中效果相同)

(* actually it's not a "real" message - an internal flag is set that indicates quit has been posted - but the effect is the same on the subsequent message loop)

这篇关于处理来自 DialogBox 的 WM_DESTROY 事件时,MessageBox 将不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆