我的 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 控制台项目模板