【发布时间】:2010-11-29 00:08:21
【问题描述】:
我遇到了一个奇怪的问题。我正在 VC++ 2008 中制作一个 Win32 应用程序,制作一个类来封装大部分工作,以便在调用 MessageBox 时轻松重复。消息框`已创建(我认为)但除非我按 Alt 键否则不会显示!
究竟发生了什么:
我运行程序
按 Enter
主窗口失去焦点
当我点击主窗口时发出哔哔声,就像存在模态消息框一样
要么按 Escape... 获得焦点,要么按 Alt 然后消息框出现并按下 alt 键(即菜单将下降)!!!!!!
附:它工作正常,但突然发生了这种情况。我没有发现任何不同 - 我什至做了一个新项目!
这应该是主程序:
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
MSG msg;
CWnd cMainWindow(TEXT("DentoMan"), TEXT("Bejkoman")); // pass The class name and window name to the constructor
cMainWindow.CreateDef(); //Create the Window
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
虽然这是类文件
CWnd::CWnd() {
};
CWnd::CWnd(LPTSTR lpszClassName, LPTSTR lpszWindowName) {
CWnd::lpszClassName = lpszClassName;
CWnd::lpszWindowName = lpszWindowName;
};
CWnd::~CWnd() {
};
// Create the window with default parameters
HWND CWnd::CreateDef(void) {
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = StaticWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = (HINSTANCE)GetModuleHandle(NULL);
wcex.hIcon = 0;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 4);
wcex.lpszMenuName = 0;
wcex.lpszClassName = lpszClassName;
wcex.hIconSm = 0;
RegisterClassEx(&wcex);
g_hWnd = CreateWindowEx(0,lpszClassName, lpszWindowName, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, wcex.hInstance, this);
hInst = wcex.hInstance; //Store hInstance in the class hInst variable
if (!g_hWnd) return false;
ShowWindow(g_hWnd, SW_SHOW);
UpdateWindow(g_hWnd);
return g_hWnd;
}
LRESULT CALLBACK CWnd::StaticWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
/* The Only Message we take here so we store the 'this' pointer within the window to identify messages
comming from it by the 'this' pointer*/
if ( Message == WM_CREATE ) {
SetWindowLong( hWnd, GWL_USERDATA, (LONG)((CREATESTRUCT FAR *)lParam)->lpCreateParams);
}
/* Store the window pointer in the class pointer we just created in order to run the right public WndPRoc */
CWnd *Destination = (CWnd*)GetWindowLong( hWnd, GWL_USERDATA );
// If the hWnd has a related class, pass it through
if (Destination) {
return Destination->WndProc( hWnd, Message, wParam, lParam );
}
// No destination found, defer to system...
return DefWindowProc( hWnd, Message, wParam, lParam );
};
LRESULT CWnd::WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
// Determine message type
switch (Message) {
case WM_LBUTTONDOWN:
{
/* this is a common trick for easy dragging of the window.this message fools windows telling that the user is
actually dragging the application caption bar.*/
SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION,NULL);
break;
}
/*case WM_CREATE:
break;
*/
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_DESTROY:
UnregisterClass(lpszClassName, hInst);
PostQuitMessage(0);
break;
case WM_KEYDOWN: //KeyBoard keys
// Which key was pressed?
switch (wParam) {
case VK_ESCAPE: //close through escape key
PostQuitMessage(0);
return 0;
case VK_RETURN:
MessageBox(hWnd, TEXT("DFGDGD"), TEXT("DFGDFG"), NULL);
return 0;
} // End Switch
break;
case WM_COMMAND:
/*switch(LOWORD(wParam))
{
}*/
break;
case WM_PAINT:
break;
default:
return DefWindowProc(hWnd, Message, wParam, lParam);
} // End Message Switch
return 0;
};
类头:
class CWnd {
public:
CWnd();
CWnd(LPTSTR lpszClassName, LPTSTR lpszWindowName);
virtual ~CWnd();
virtual HWND CreateDef(void); // Create the window with default parameters
virtual LRESULT WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam );
private:
static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
HWND g_hWnd; //Global window handle for this window
HINSTANCE hInst; //Global instance for this window
LPTSTR lpszClassName;
LPTSTR lpszWindowName;
};
附:我包含了所有需要的头文件,除了 MessageBox 一切都很好
这也是here上代码的链接
【问题讨论】:
-
把相关代码贴在这里。另外,在黑暗中拍摄:在显示消息框时指定父窗口。
-
已编辑,已删除链接。不要发布不安全的 .exe 文件。只需粘贴相关代码即可。
-
@Jim Brissom,您也可以在此函数中将 NULL 作为窗口句柄传递,它应该可以工作(至少在我的情况下可以)。不确定它是否正确(也许我应该使用
HWND_DESKTOP或其他东西),但它仍然有效。 -
愿古老的帖子永不消亡... FWIW,我遇到了这个问题,其中 ::MessageBox() 没有出现(在名为 ::MessageBox() 的 win 64 MFC 应用程序中)。我可以通过将 AfxGetMainWnd()->m_hWnd 传递给 hWnd(而不是 nullptr)或通过将 MB_DEFAULT_DESKTOP_ONLY 作为标志传递来修复它。
标签: messagebox winapi