为什么PostMessage在全局热键处理程序中调用时没有效果?

Pav*_*sov 0 winapi

我正在编写的GUI应用程序确实将一个keydown事件发送到另一个窗口,a cmd.exe.

PostMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0);
Run Code Online (Sandbox Code Playgroud)

当它像事件进行事件被发送就好了WM_CREATE,WM_KEYUP等(新线出现在cmd.exe).

然后我设置了一个全局热键RegisterHotKey.在WM_HOTKEY处理程序中,我成功接收按键但PostMessage不再有效.

如何解决?

完整示例,尽可能缩小:

#include <iostream>
#include <Windows.h>

using namespace std;

const char g_szClassName[] = "myWindowClass";

BOOL CALLBACK enumWindows(HWND hwnd, LPARAM lParam) {
    char winTitle[1024*10];
    GetWindowText(hwnd, winTitle, sizeof(winTitle));
    if (strstr(winTitle, "cmd.exe") != NULL) {
        cout << "Sending a message to window " << hwnd << ": " << winTitle << endl;
        PostMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0);
    }
    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch(msg) {
        case WM_CREATE:
            // register hotkey ctrl+alt+s
            RegisterHotKey(hwnd, 100, MOD_ALT | MOD_CONTROL, 'S');
            break;
        case WM_CLOSE:
            DestroyWindow(hwnd);
            break;
        case WM_DESTROY:
            EnumWindows(enumWindows, 0);
            PostQuitMessage(0);
            break;
        case WM_HOTKEY:
            // hotkey ctrl+alt+s fired
            EnumWindows(enumWindows, 0);
            break;
        case WM_KEYUP:
            EnumWindows(enumWindows, 0);
            break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

// just init stuff, do not waste your time
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    RegisterClassEx(&wc);
    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&Msg, NULL, 0, 0) > 0) {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
Run Code Online (Sandbox Code Playgroud)

Windows 7 64位

Ben*_*igt 5

Raymond Chen已经记录了为什么这不能按照你期望的方式工作(PostMessageIS工作得很好,但是另一个窗口的响应取决于实际的键盘状态,就像我在评论中推测的那样).看他的博文: