簡體   English   中英

WINAPI 應用程序在我按下任一 ALT 時關閉,為什么?

[英]WINAPI application closes when I press either ALT, why?

我之前練習過 winapi 應用程序,但從未遇到過這個問題。

我嘗試制作自定義 WindowProc 來覆蓋 WM_QUIT/WM_CLOSE/WM_DESTROY 消息的默認行為以不執行任何操作,但是當我按下 ALT 時 window 仍然關閉!

這是整個代碼:

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 時 window 不應該關閉,但確實如此。

您正在將message字段與wParam字段混合:

while (msg.wParam != WM_QUIT)

當您按下 ALT 時,window 會收到一條WM_KEYDOWN消息,其wParam是虛擬鍵碼。 碰巧 ALT 與WM_QUIT (0x12) 的常量具有相同的 VK 代碼。

此外,您還在退出前翻譯和調度WM_QUIT 您可以通過使用適當的檢查進行單級縮進來處理這兩種情況:

while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE) && msg.message != WM_QUIT)

正如評論中所指出的,這更干凈GetMessage

while (GetMessage(&msg, nullptr, 0, 0) > 0)

您的代碼存在一些問題。

首先,您應該使用GetMessage()而不是PeekMessage() 根本區別在於PeekMessage()是非阻塞的,因此您的程序將使用 100% 的 CPU 運行該循環。

此外,由於內部循環可能會或可能不會連續遍歷多條消息,因此像您正在做的那樣檢查外部循環上的內容將是命中或未命中,並且不會檢查所有消息。 您應該檢查內部循環中的每條消息。

但在這種情況下,沒有必要,因為如果 Window 無論如何關閉,這個循環就會結束。 你做的這個檢查是沒有意義的。

您的代碼還有其他一些不一致之處, wc.hInstance應該是hInstance ,這是您在WinMain()中作為參數收到的那個。 無需 go 使用 API 查找此信息。

CreateWindow()也應該再次接收hInstance ,因為它是倒數第二個參數,而不是nullptr

最后,正如克里斯的回答所指出的那樣,您應該在msg.message而不是在msg.wParam中尋找消息類型。

除此之外,這里沒有做“自定義 WindowProc”的地方。 如果你想做一個自定義的 WndProc,那么你應該將wc.lpfnWndProc設置為你自己的 function 而不是DefWindowProc ,你可以在那里為你的 Window 定義自定義行為。

例如:

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()時才會發生。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM