C++ Windows API不会退出
由于某种原因,在我关闭此窗口后,我的程序将不会退出并进入无限循环。此问题的解决方案似乎是将GetMessage(&message,handel,0,0)更改为GetMessage(&message,NULL,0,0)。但是我不明白为什么会这样。谁能解释一下吗。我也不明白为什么我要调用UpdateWindow(handel),因为窗口显示时没有它C++ Windows API不会退出,c++,windows,winapi,user-interface,C++,Windows,Winapi,User Interface,由于某种原因,在我关闭此窗口后,我的程序将不会退出并进入无限循环。此问题的解决方案似乎是将GetMessage(&message,handel,0,0)更改为GetMessage(&message,NULL,0,0)。但是我不明白为什么会这样。谁能解释一下吗。我也不明白为什么我要调用UpdateWindow(handel),因为窗口显示时没有它 #include <iostream> #include <Windows.h> using namespace std;
#include <iostream>
#include <Windows.h>
using namespace std;
LRESULT CALLBACK EventHandler(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, PSTR args, int cmd)
{
MSG message;
HWND handel;
WNDCLASS win_class;
win_class.style = CS_HREDRAW | CS_VREDRAW;
win_class.cbClsExtra = 0;
win_class.cbWndExtra = 0;
win_class.lpszClassName = "Window";
win_class.hInstance = inst;
win_class.hbrBackground = GetSysColorBrush(COLOR_3DDKSHADOW);
win_class.lpszMenuName = NULL;
win_class.lpfnWndProc = EventHandler;
win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
RegisterClass(&win_class);
handel = CreateWindow(win_class.lpszClassName, "Window", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 350, 250, NULL, NULL, inst, NULL);
ShowWindow(handel, cmd);
UpdateWindow(handel);
//Loop does not end.
while(GetMessage(&message, handel, 0, 0))
{
cout << "LOOP" << endl;
DispatchMessage(&message);
}
return WM_QUIT;
}
LRESULT CALLBACK EventHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static long long count = 0;
count++;
cout << "CALL #" << count << endl;
if(msg == WM_DESTROY)
{
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
#包括
#包括
使用名称空间std;
LRESULT回调事件处理程序(HWND、UINT、WPARAM、LPARAM);
int WINAPI WinMain(HINSTANCE inst、HINSTANCE prev、PSTR参数、int cmd)
{
消息;
汉德尔;
WNDCLASS win_class;
win_class.style=CS_HREDRAW | CS_VREDRAW;
win_class.cbClsExtra=0;
win_class.cbWndExtra=0;
win_class.lpszClassName=“窗口”;
win_class.hInstance=inst;
win_class.hbrBackground=GetSysColorBrush(彩色阴影);
win_class.lpszMenuName=NULL;
win_class.lpfnWndProc=EventHandler;
win_class.hCursor=LoadCursor(空,IDC_箭头);
win_class.hIcon=LoadIcon(空,IDI_应用程序);
注册类(win_类);
handel=CreateWindow(win_class.lpszClassName,“窗口”,WS_重叠窗口| WS_可见,100100350250,NULL,NULL,inst,NULL);
ShowWindow(handel,cmd);
更新窗口(韩德尔);
//循环不会结束。
while(GetMessage(&message,handel,0,0))
{
coutWM_QUIT
不会发送到任何窗口,只是放置在线程的消息队列中,没有HWND
,这就是它与您的筛选器不匹配的原因。这里有一个很好的机会来锻炼您的“搜索MSDN文档”能力:
首先,让我们查阅以下文档:
指示终止应用程序的请求,并在
应用程序调用PostQuitMessage函数
使GetMessage函数返回零
WM_QUIT消息与窗口无关,因此将
永远不要通过窗口的窗口过程接收。它将被检索
仅通过GetMessage或PeekMessage功能
然后,让我们查阅以下文档:
从调用线程的消息队列中检索消息
函数将发送传入的消息,直到发送的消息被发送为止
可供检索
hWnd[输入,可选]类型:hWnd
要检索其消息的窗口的句柄。该窗口
必须属于当前线程
如果hWnd为NULL,则GetMessage将检索任何窗口的消息
属于当前线程,以及当前线程上的任何消息
hwnd值为NULL的线程消息队列(请参阅消息
因此,如果hWnd为NULL,则窗口消息和线程
消息被处理
因此,您希望使用NULL
作为GetMessage()
的窗口句柄,而不是handel
,因为WM\u QUIT
与任何窗口都没有关联
还有来自MSDN的消息
正如旁注所述,窗口关闭事件的消息是,这反过来会导致默认情况下窗口被销毁。WM\u DESTROY
表示您的窗口已经在被销毁的过程中。因此,如果您想要截获关闭事件(比如要求用户保存任何更改),您将处理WM\u close
事件
另外,如GetMessage()
文档所示,您的GetMessage()
循环实际上应该如下所示:
BOOL bRet;
while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
因为GetMessage()
实际上可以返回1、0或-1(尽管它返回的是BOOL
)。看看MSDN中的和
如果GetMessage
函数的hWnd
参数为NULL,则GetMessage将检索属于当前线程的任何窗口的消息,以及当前线程消息队列中hWnd值为NULL的任何消息
PostQuitMessage函数将WM_QUIT消息发布到线程的消息队列,而不是当前窗口。有误导性。“请注意,GetMessage始终检索WM_QUIT消息,无论您为wMsgFilterMin和wMsgFilterMax指定了哪个值。”正如这个问题和您的答案所显示的,它并不总是被检索。但是,它是否被检索并不取决于wMsgFilterMin和wMsgFilterMax。@hvd:我将该语句解释为“wMsgFilterMin和wMsgFilterMax参数不影响WM_QUIT处理”,但我同意这有误导性(或充其量是模棱两可的)。虽然我很容易看出误解,但文档是正确的。如果手动将WM_QUIT
发布到特定窗口,则使用HWND和筛选器的代码将检索到它,即使它与筛选器不匹配。通过询问为什么传递非空句柄,可以使问题更有趣。推荐使用雷丁:(所以不,循环不需要这样。)@hvd:旧的新的东西,虽然它是一个奇妙的博客,但不是官方文档。另外,请注意,它永远不会返回-1,只有在某些情况下(尽管是最常见的,也可能是唯一合理的)。我更喜欢编写尽可能健壮的程序,而且测试-1不会有什么坏处。您的答案是将其称为GetMessage(&msg,NULL,0,0)
,这正是在某些情况下,您永远不会得到-1的返回值。如果您想检查,也可以,我不会说您的循环是错误的,只是这里没有必要。@hvd:我同意您的看法。我希望看到文档更新以反映这一点,这样我就不必再链接到Raymond Chen的博客whe我从来没有链接到MSDN以及。