簡體   English   中英

WM_KILLFOCUS 邏輯

[英]WM_KILLFOCUS logic

我有以下代碼,請參見下文。

為什么WinMain() 中的代碼案例 WM_KILLFOCUS從未達到? 如果我從WndProc() 中刪除case WM_KILLFOCUS ,則仍然沒有到達WinMain() 中的那個。 案例 WM_KEYDOWN工作得很好。

如何修復代碼以便達到WinMain() 中的WM_KILLFOCUS 情況

代碼非常基礎。

謝謝你。

#include <windows.h>
HINSTANCE m_hinstance_Module = NULL;
HWND m_hwnd_Window = NULL;
LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
{
    switch (umessage)
    {
    case WM_KILLFOCUS:
        // THE CODE REACHES THIS POINT.
        MessageBoxA(hwnd, "WM_KILLFOCUS", "WndProc()", 0);
        return DefWindowProc(hwnd, umessage, wparam, lparam);
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    default:
        return DefWindowProc(hwnd, umessage, wparam, lparam);
    }
    // Done.
    return 0;
}

void InitializeWindow()
{
    WNDCLASSEX struct_WNDCLASSEX;

    m_hinstance_Module = GetModuleHandle(NULL); // If this parameter is NULL, GetModuleHandle returns a 
    handle to the file used to create the calling process (.exe file).
    struct_WNDCLASSEX.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    struct_WNDCLASSEX.lpfnWndProc = WndProc;
    struct_WNDCLASSEX.cbClsExtra = 0;
    struct_WNDCLASSEX.cbWndExtra = 0;
    struct_WNDCLASSEX.hInstance = m_hinstance_Module;
    struct_WNDCLASSEX.hIcon = LoadIcon(NULL, IDI_WINLOGO);
    struct_WNDCLASSEX.hIconSm = struct_WNDCLASSEX.hIcon;
    struct_WNDCLASSEX.hCursor = LoadCursor(NULL, IDC_ARROW);
    struct_WNDCLASSEX.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    struct_WNDCLASSEX.lpszMenuName = NULL;
    struct_WNDCLASSEX.lpszClassName = L"TEST";
    struct_WNDCLASSEX.cbSize = sizeof(WNDCLASSEX);
    RegisterClassEx(&struct_WNDCLASSEX);
    m_hwnd_Window = CreateWindowEx(WS_EX_APPWINDOW, L"TEST", L"TEST", WS_OVERLAPPEDWINDOW, 0, 0, 800, 
    600, NULL, NULL, m_hinstance_Module, NULL);
    ShowWindow(m_hwnd_Window, SW_SHOW);
    SetForegroundWindow(m_hwnd_Window);
    SetFocus(m_hwnd_Window);
}

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, 
    _In_ int nShowCmd)
{
    MSG structMsg;
    bool blnDone = false;

    InitializeWindow();
    ZeroMemory(&structMsg, sizeof(MSG));
    while (!blnDone)
    {
        if (PeekMessage(&structMsg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&structMsg);
            DispatchMessage(&structMsg);
        }
        if (structMsg.message == WM_QUIT)
        {
            blnDone = true;
        }
        else
        {
            switch (structMsg.message)
            {
                case WM_KILLFOCUS:
                    // THE CODE NEVER REACHES THIS POINT.
                    MessageBoxA(m_hwnd_Window, "WM_KILLFOCUS", "WinMain()", 0);
                    break;
                case WM_KEYDOWN:
                    MessageBoxA(m_hwnd_Window, "WM_KEYDOWN", "WinMain()", 0);
                    break;
            }
        }
    }
    return 0;
}

消息路由使用以下兩種方法之一完成:

系統使用兩種方法將消息路由到窗口過程:將消息發布到稱為消息隊列的先進先出隊列,系統定義的臨時存儲消息的內存對象,以及將消息直接發送到窗口過程。

發送到消息隊列的消息稱為排隊消息,而立即傳遞到窗口過程的消息稱為非排隊消息

WM_KILLFOCUS是非排隊消息1 這就是為什么窗口過程會觀察到這條消息,而消息循環不會。

這是架構限制。 您不能使未排隊的消息顯示在消息隊列中。


1提示在文檔中編碼:“發送到窗口”,而不是“發布”。

暫無
暫無

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

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