0

几天前,我拿到了我的 Microsoft Arc Touch Mouse Surface Edition。不幸的是,它没有前进/后退按钮(它只执行 Page-Up/Page-Down)。

因此,我编写了一个小程序,它可以捕捉到 Page_Up/Page_Down 键的按下并发送浏览器后退/前进按钮。

在我的电脑(Win 8.1 Pro)上,这工作得很好。但是,在我的 Surface Pro 2(主要是为此编写程序)上,它不会发送 Browser_Back-/Forward-Buttons。对于每个其他键,该程序似乎都可以工作(如空格、字母、数字)。

这里是发送密钥代码的代码:

      public static uint send(short keyCode) {

        INPUT structure = new INPUT();
        structure.type = (int)InputType.INPUT_KEYBOARD;
       structure.ki.wVk = keyCode;

        structure.ki.dwFlags = (int)KEYEVENTF.KEYDOWN;
        structure.ki.dwExtraInfo = GetMessageExtraInfo();

        INPUT input2 = new INPUT();
        structure.type = (int)InputType.INPUT_KEYBOARD;
        structure.ki.wVk = keyCode;

        input2.mi.dwFlags = (int)KEYEVENTF.KEYUP;
        input2.ki.dwExtraInfo = GetMessageExtraInfo();

        INPUT[] pInputs = new INPUT[] { structure, input2 };

        return SendInput(2, pInputs, Marshal.SizeOf(structure));
    }

这里是 KeyboardHook:

       public static int KeyHookProc(int nCode, IntPtr wParam, IntPtr lParam) {

        KeyHookStruct myKeyHookStruct =
            (KeyHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyHookStruct));

        if (nCode < 0) {
            return CallNextHookEx(hHook, nCode, wParam, lParam);
        } else {

            if (wParam == (IntPtr)0x0100) {


                int keyCode = myKeyHookStruct.vkCode;
                if (keyCode == 33) {

                    Input.send(0xA7);
                } else if (keyCode == 34) {

                    Input.send(0xA6);
                } else {
                    return CallNextHookEx(hHook, nCode, wParam, lParam);
                }


            }

            return 1;

        }

    }

因此,如果按下我键盘上的 Page-Down/page-Up 按钮,就会调用 send() 方法。0xA6 和 0xA7 是 Browser_Back 和 Browser_Forward 的键码。

在我的 Surface 上,可以正确识别 Page-Up/Page-Down 按钮。send() 方法也被调用,但它不会发送正确的键码。根据 Spy++ 的说法,如果 Keycode 为 0xA6 或 0xA7(在我的 PC 上可以使用),则 send() 不会发送任何内容。

Surface Pro 2 的问题在哪里?我能做什么,它工作,或者我怎么能确定它为什么不工作?

4

1 回答 1

0

您发布的代码是错误的,因为您从未设置typeinput2(代码使用structure.type

编辑:

来自SendInput的 MSDN 文档:

此函数在被 UIPI 阻止时失败。请注意,GetLastError 和返回值都不会表明失败是由 UIPI 阻塞引起的。

此功能受 UIPI 约束。仅允许应用程序将输入注入到具有相同或更低完整性级别的应用程序中。

您还应该删除对GetMessageExtraInfo

新编辑:

我不喜欢你KeyHookProc函数的逻辑:如果消息不是WM_KEYDOWN(0x0100),那么你返回 1...

我会去:

if (wParam != (IntPtr)0x0100) {
   return CallNextHookEx(hHook, nCode, wParam, lParam);
} else {
   int keyCode = myKeyHookStruct.vkCode;
   if (keyCode == 33) {
      Input.send(0xA7);
   } else if (keyCode == 34) {
      Input.send(0xA6);
   } else {
      return CallNextHookEx(hHook, nCode, wParam, lParam);
   }
   return 1;
}
于 2014-01-02T11:42:42.807 回答