首页 > 解决方案 > mouse_event / PostMessage 按键消息 - 与 GetKeyState() 不一致

问题描述

我正在尝试做两件事:

  1. 将键盘键和鼠标键的“key down”事件发送到外部进程的窗口
  2. 稍后,查询当前是否在该窗口中按下了给定的键盘或鼠标键,如果
    • 我的工具之前已经向窗口发送了一个“key down”(但显然没有 key up)事件
    • 用户与窗口进行了任何手动交互

例如,其中一种情况可能是我将鼠标左键的“按下”事件发送到窗口。然后用户自己手动点击窗口内部。结果,在这两个交互之后,窗口再次将鼠标键识别为“向上”。

到目前为止,对于按键,我一直在使用 user32.dll API 调用 PostMessage(用于键盘事件)和 mouse_event(用于鼠标键)。

至于检索当前状态,我一直在尝试使用“GetKeyState”。但是,它的返回值与实际行为不一致。例如,当我通过我的工具发布一个键,并且没有进一步的交互(我和用户都没有)时,GetKeyState() 仍然返回 0(= 未按下键)。

我想我在这里使用错误的 API 来检索状态(特别是因为 GetKeyState 也不接受窗口句柄?)。有没有办法找出给定窗口的实际键状态?还是我在这里的其他地方出错了?

谢谢


示例代码:

    class NativeCalls
    {
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

        [DllImport("user32.dll")]
        public static extern short GetKeyState(int nVirtKey);

        [DllImport("user32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        static extern short GetAsyncKeyState(int vKey);


        public static void test()
        {
            var state_x1 = GetAsyncKeyState(0x41);

            var ok1 = SetForegroundWindow(Globals.Hwnd);
            var ok2 = PostMessage(Globals.Hwnd, 0x0100, 0x41, 0); // key down "A"
            Thread.Sleep(10);
            var state = GetKeyState(0x41); // check if key "A" Is down
            var state_x2 = GetAsyncKeyState(0x41);

            // state_x1, state, and state_x2 are all 0
        }
    }

标签: windowswinapiuser32

解决方案


推荐阅读