我的 Visual C++ Win32 中有一个无法关闭的 MessageBox!到底是怎么回事?

Posted

技术标签:

【中文标题】我的 Visual C++ Win32 中有一个无法关闭的 MessageBox!到底是怎么回事?【英文标题】:I have a MessageBox in my Visual C++ Win32 that cannot be closed! What is going on? 【发布时间】:2015-03-31 01:59:33 【问题描述】:

我有一个无法关闭的消息框,我不知道为什么。它是在我的窗口过程中为这样创建的对话框创建的:

hwnd = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), NULL, WndProc);

下面是有问题的 WndProc 代码。问题在于 MessageBox 调用,OK 按钮没有任何作用,也没有点击该消息框上的“X”。

BOOL CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

    static HBRUSH bgBrush;
    switch (msg)
    
    case WM_INITDIALOG:
        bgBrush = CreateSolidBrush(RGB(65, 65, 66));
        return TRUE;

    case WM_CTLCOLORDLG:
        return (INT_PTR)(bgBrush);

    case WM_CTLCOLORSTATIC:
        SetBkMode((HDC)wParam, TRANSPARENT);
        SetTextColor((HDC)wParam, RGB(200, 200, 200));
        return (INT_PTR)(bgBrush);

    case WM_DEVICECHANGE:
        USBEnumerateDev();
        break;

    case WM_COMMAND:
    
                       switch (LOWORD(wParam))
                       
                       case IDC_SELECTPROFILE:
                           switch (HIWORD(wParam))
                           
                           case BN_CLICKED:
                               int res = CommonFileDialog.BasicFileOpen(hwnd);
                               if (res == TRUE)
                               
                                   int len = GetWindowTextLength(GetDlgItem(hwnd, IDC_EDITWLAN));
                                   if (len > 0)
                                   
                                       int i;
                                       wchar_t* buf;

                                       buf = (wchar_t*)GlobalAlloc(GPTR, len + 1);
                                       GetDlgItemText(hwnd, IDC_EDITWLAN, buf, len + 1);



                                       GlobalFree((HANDLE)buf);
                                   
                               
                               break;
                           
                           break;

                       case IDC_PROGRAM:
                           switch (HIWORD(wParam))
                           
                           case BN_CLICKED:
                               int len = GetWindowTextLength(GetDlgItem(hwnd, IDC_EDITWLAN));
                               if (len > 0)
                               
                                   int i, fileSize;
                                   LPSTR XMLfilename, buf;
                                   FILE *fXMLfile;

                                   XMLfilename = (LPSTR)GlobalAlloc(GPTR, len + 1);
                                   GetDlgItemTextA(hwnd, IDC_EDITWLAN, XMLfilename, len + 1);
                                   fopen_s(&fXMLfile, XMLfilename, "r");
                                   fseek(fXMLfile, 0L, SEEK_END);
                                   fileSize = ftell(fXMLfile);
                                   fseek(fXMLfile, 0L, SEEK_SET);
                                   buf = (LPSTR)GlobalAlloc(GPTR, fileSize);
                                   fread(buf, 1, fileSize, fXMLfile);
                                   DBG("fileSize: %d", fileSize);
                                   if (USBSetProfile(buf, fileSize))
                                       MessageBox(hwnd, L"Programmed!", L"PC -> USB", MB_OK | MB_ICONINFORMATION);
                                   GlobalFree((HANDLE)XMLfilename);
                                   GlobalFree((HANDLE)buf);
                                   //
                               
                           
                           break;
                       
    
        break;

    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    
    return 0;

什么给了?我已经尝试使用窗口句柄和 NULL 调用 MessageBox,同样的事情。

【问题讨论】:

有可能你的 WndProc 代码的其余部分正在做(或不做)导致关闭消息在 MessageBox() 可以处理之前被丢弃/忽略的事情。你的 WndProc 的其余部分实际上是什么样的? @RemyLebeau pastebin.com/gDdQVR92 它有点大,所以我粘贴了它。另请注意,还有第二个线程正在从 USB 读取,但与对话框无关。但是禁用该线程并不能解决问题。难道是我的消息循环在我的主线程中? 确保 MessageBox 调用是从包含消息循环的同一线程启动的。 您的WndProc() 正在调用DefWindowProc(),但documentation 明确表示不要这样做:“虽然对话框过程类似于窗口过程,但 不得调用 DefWindowProc 函数来处理不需要的消息。不需要的消息由对话框窗口过程在内部处理。". @MarkRansom: MessageBox() 在内部运行自己的消息循环。 【参考方案1】:

您的WndProc() 正在调用DefWindowProc(),但documentation 明确表示不要这样做:

虽然对话框过程类似于窗口过程,但它不能调用 DefWindowProc 函数来处理不需要的消息。不需要的消息由对话框窗口过程在内部处理。

【讨论】:

【参考方案2】:

这是窗口过程和对话框过程的混合。这些是不同的,有不同的规则。

还要注意返回值。对于您处理的案例,您应该返回 TRUE,而对于您没有处理的案例,您应该返回 FALSE。你总是返回 0 (FALSE)。

【讨论】:

以上是关于我的 Visual C++ Win32 中有一个无法关闭的 MessageBox!到底是怎么回事?的主要内容,如果未能解决你的问题,请参考以下文章

.lib 不是有效的 Win32 应用程序 - Visual Studio 2015

将 C++ Win32 控制台项目类集成到 Visual Studio 2008 中的 Visual C++(Windows 窗体应用程序)项目中

使用 Visual Studio 将 HTML 浏览器嵌入到本机 C++/Win32 项目中

Visual Studio 2017 c++ win32 控制台项目模板

Visual Studio 2017 c++ win32 控制台项目模板

(Visual Studio 2015) 无法创建 Win32 C++ 应用程序