首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows API无法退出

Windows API无法退出
EN

Stack Overflow用户
提问于 2013-12-16 02:22:00
回答 3查看 448关注 0票数 1

由于某些原因,在我关闭这个窗口后,我的程序不会退出并进入无限循环。这个问题的解决方案似乎是将GetMessage(&message,handel,0,0)更改为GetMessage(&message,NULL,0,0)。然而,我不明白为什么会这样。谁能解释一下。我也不明白为什么我要调用UpdateWindow(handel),因为没有它窗口就会显示出来。

代码语言:javascript
复制
#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);
}
EN

回答 3

Stack Overflow用户

发布于 2013-12-16 02:26:53

WM_QUIT不会发送到任何窗口,只是放在没有HWND的线程的消息队列中,这就是为什么它与您的过滤器不匹配。

票数 2
EN

Stack Overflow用户

发布于 2013-12-16 02:37:30

看看MSDN中的GetMessagePostQuitMessage

如果GetMessage函数的参数hWnd为空,GetMessage将检索属于当前线程的所有窗口的消息,以及当前线程的消息队列中hwnd值为空的所有消息

PostQuitMessage函数将WM_QUIT消息发布到线程的消息队列,而不是当前窗口。

票数 1
EN

Stack Overflow用户

发布于 2013-12-16 02:30:07

这是一个锻炼你的“搜索MSDN文档”能力的好机会:

首先,让我们查找WM_QUIT的文档

表示终止应用程序的请求,在应用程序调用PostQuitMessage函数时生成。此消息会导致GetMessage函数返回零。

..。

WM_QUIT消息与窗口无关,因此永远不会通过窗口的window过程接收。它只能由GetMessagePeekMessage函数检索。

然后,让我们查找GetMessage()的文档

从调用线程的消息队列中检索消息。该函数调度传入的已发送消息,直到有投递的消息可供检索。

..。

hWnd输入,可选类型:硬件

要检索其消息的窗口的句柄。该窗口必须属于当前线程。

如果hWnd为 NULL ,GetMessage将检索属于当前线程的任何窗口的消息,以及当前线程的消息队列中hwnd值为NULL的所有消息(请参阅MSG结构)。因此,如果hWnd为NULL,则同时处理窗口消息和线程消息。

因此,您希望使用NULL作为GetMessage()__的窗口句柄,而不是handel__,因为WM_QUIT与任何窗口都没有关联。

也有来自微软的plenty more information about how Windows programs typically handle messages

注意,窗口关闭事件的消息是WM_CLOSE,这会导致窗口在默认情况下被销毁。WM_DESTROY意味着你的窗口已经在被销毁的路上了。因此,如果您想截获close事件(例如要求用户保存任何更改),则应处理WM_CLOSE事件。

此外,如GetMessage()文档所示,您的GetMessage()循环实际上应该如下所示:

代码语言:javascript
复制
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)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20598022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档