首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当我按下ALT时,WINAPI应用程序关闭,为什么?

当我按下ALT时,WINAPI应用程序关闭,为什么?
EN

Stack Overflow用户
提问于 2019-10-20 01:42:05
回答 2查看 84关注 0票数 0

我以前练习过winapi应用程序,但从来没有遇到过这个问题。

我已经尝试制作一个自定义的WindowProc来覆盖WM_QUIT/WM_CLOSE/WM_DESTROY消息的默认行为,不做任何事情,但当我按ALT时窗口仍然关闭!

下面是完整的代码:

代码语言:javascript
运行
复制
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
    const LPCSTR className = "Class name";
    WNDCLASS wc = {};
    wc.style = 0;
    wc.lpfnWndProc = DefWindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = GetModuleHandle(nullptr);
    wc.hIcon = nullptr;
    wc.hCursor = nullptr;
    wc.hbrBackground = nullptr;
    wc.lpszMenuName = nullptr;
    wc.lpszClassName = className;

    RegisterClass(&wc);
    HWND window = CreateWindow(className, "Title", WS_OVERLAPPEDWINDOW, 200, 200, 600, 400, nullptr, nullptr, nullptr, nullptr);

    ShowWindow(window, SW_SHOW);

    MSG msg = {};

    while (msg.wParam != WM_QUIT)
    {
        while(PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return msg.wParam;
}

我相信当我按下ALT时,窗口不应该关闭,但它确实关闭了。

EN

回答 2

Stack Overflow用户

发布于 2019-10-20 01:58:06

您将message字段与wParam字段混合在一起:

代码语言:javascript
运行
复制
while (msg.wParam != WM_QUIT)

当您按ALT时,窗口会收到一条wParam为虚拟键码的WM_KEYDOWN消息。碰巧ALT与WM_QUIT (0x12)的常量具有相同的VK代码。

此外,您还需要在退出之前转换和分派WM_QUIT。您可以通过使用带有适当检查的单层缩进来处理这两种情况:

代码语言:javascript
运行
复制
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE) && msg.message != WM_QUIT)

正如评论中所指出的,使用GetMessage会更清晰

代码语言:javascript
运行
复制
while (GetMessage(&msg, nullptr, 0, 0) > 0)
票数 4
EN

Stack Overflow用户

发布于 2019-10-20 02:09:27

你的代码有一些问题。

首先,你应该使用GetMessage()而不是PeekMessage()。根本的区别在于PeekMessage()是非阻塞的,因此您的程序将使用100%运行该循环的CPU。

此外,由于内部循环可能会循环多个消息,也可能不会循环多个消息,因此像您正在做的那样检查外部循环上的内容将是成功或失败的,并且不会检查所有消息。相反,您应该检查内部循环中的每条消息。

但在这种情况下,这是没有必要的,因为如果窗口无论如何都关闭了,这个循环就会结束。你所做的检查是毫无意义的。

您的代码还有其他一些不一致之处,wc.hInstance应该是hInstance,即您在WinMain()中作为参数接收到的那个。不需要使用API来查找这些信息。

另外,CreateWindow()应该再次接收hInstance,因为它是倒数第二个参数,而不是nullptr

最后,正如chris' answer所指出的,您应该在msg.message而不是msg.wParam中查找消息类型。

除此之外,这不是做“自定义WindowProc”的地方。如果你想做一个自定义的WndProc,那么你应该将wc.lpfnWndProc设置为你自己的函数,而不是DefWindowProc,在那里你可以定义你的窗口的自定义行为。

例如:

代码语言:javascript
运行
复制
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CLOSE:
    case WM_DESTROY:
        // do nothing
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

注没有必要测试WM_QUIT,因为只有当您的应用程序调用PostQuitMessage()时才会出现此消息。

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

https://stackoverflow.com/questions/58466352

复制
相关文章

相似问题

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