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

Winapi 为什么从全局热键处理程序中调用PostMessage时没有效果?,winapi,Winapi,我正在编写的GUI应用程序确实会向另一个窗口发送按键事件,即cmd.exe PostMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0); 当在诸如WM\u CREATE、WM\u KEYUP等事件上完成时,事件会正常发送(在cmd.exe中出现一行新行) 然后,我用注册表快捷键设置了一个全局快捷键。在WM_热键处理程序中,我成功地接收到按键,但PostMessage不再有效 如何解决这个问题 完整示例,尽可能缩小: #include <iostream>

我正在编写的GUI应用程序确实会向另一个窗口发送按键事件,即
cmd.exe

PostMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0);
当在诸如
WM\u CREATE
WM\u KEYUP
等事件上完成时,事件会正常发送(在
cmd.exe
中出现一行新行)

然后,我用注册表快捷键设置了一个全局快捷键。在
WM_热键
处理程序中,我成功地接收到按键,但
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;
}
#包括
#包括
使用名称空间std;
const char g_szClassName[]=“myWindowClass”;
BOOL回调枚举窗口(HWND-HWND,LPARAM-LPARAM){
字符winTitle[1024*10];
GetWindowText(hwnd、winTitle、sizeof(winTitle));
if(strstr(winTitle,“cmd.exe”)!=NULL){

coutRaymond Chen已经记录了为什么这不能按您期望的方式工作(
PostMessage
工作正常,但另一个窗口的响应取决于实际的键盘状态,正如我在评论中所猜测的)。参见他的博文:


Raymond Chen已经记录了为什么这不能按您期望的方式工作(
PostMessage
工作正常,但另一个窗口的响应取决于实际的键盘状态,正如我在评论中所猜测的)。参见他的博客帖子:


也许
WM_KEYDOWN
处理程序会检查热键启动时按下的其他键的状态?伪造输入并出错是错误的。使用官方自动化界面可能会更成功:。也许
WM_KEYDOWN
处理程序会检查按下的其他键的状态在热键触发的那一瞬间被激活?伪造输入,并做错事,是错误的。使用官方自动化界面可能会更成功:。