c++ - WM_KILLFOCUS逻辑

标签 c++ windows winapi winmain

我有以下代码,请参见下文。

为什么 WinMain()中的代码 case WM_KILLFOCUS 从未达到?
如果我从 WndProc()中删除了 case WM_KILLFOCUS ,则仍未达到 WinMain()中的一个。
情况WM_KEYDOWN 可以正常工作。

如何修复代码,以便达到 WinMain()中的 case 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;
}

最佳答案

Message routing使用以下两种方法之一完成:

The system uses two methods to route messages to a window procedure: posting messages to a first-in, first-out queue called a message queue, a system-defined memory object that temporarily stores messages, and sending messages directly to a window procedure.



发布到消息队列的消息称为queued messages,而立即传递给窗口过程的消息称为nonqueued messages
WM_KILLFOCUS是非排队消息1。这就是为什么窗口过程会观察到此消息,而消息循环却看不到的原因。

这是体系结构上的限制。您不能使未排队的消息显示在消息队列中。

1提示编码在documentation中:“发送到窗口”,而不是“posted”。

关于c++ - WM_KILLFOCUS逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60125261/

相关文章:

c++ - 这两者在位操作方面有什么区别?

c++ - Win32 C++ Alphablend 位图部分透明

wpf - 如何以编程方式禁用 Windows 8 Charms 栏?

winapi - 具有透明背景的 win32 菜单项位图

c++ - 单击按钮显示另一个 ui 文件

c++ - 右值引用是否与左值引用具有相同的开销?

java - C++ 和 Java 之间的主要区别

c++ - 错误位置的对话框

windows - Window 2008 Tomcat 7 MS SQL Server 2008R2 - 无法识别 JNDI JDBC 驱动程序

r - dev.new() 启动到第二台显示器