如何模拟按键到任何当前聚焦的窗口?

时间:2009-01-30 23:43:36

标签: c winapi keyboard-hook

我正在尝试更改键盘发送给应用程序的密钥。我已经创建了一个全局钩子,可以阻止我想要的键,但我想现在发送一个新的键。这是我的钩子过程:

LRESULT __declspec (dllexport) HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    int ret;

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

    kbStruct = (KBDLLHOOKSTRUCT*)lParam;

    printf("\nCaught [%x]", kbStruct->vkCode);

    if(kbStruct->vkCode == VK_OEM_MINUS)
    {
        printf(" - oem minus!");
        keybd_event(VK_DOWN, 72, KEYEVENTF_KEYUP, NULL);
        return -1;
    }
    else if(kbStruct->vkCode == VK_OEM_PLUS)
    {
        printf(" - oem plus!");
        keybd_event(VK_UP, 75, KEYEVENTF_KEYUP, NULL);
        return -1;
    }

    return CallNextHookEx(hHook, nCode, wParam, lParam);
}

我已尝试将SendMessage和PostMessage与GetFocus()和GetForegroudWindow()一起使用,但无法弄清楚如何为WM_KEYUP或WM_KEYDOWN创建LPARAM。我还尝试了keybd_event(),它模拟了键(我知道因为这个钩子proc捕获模拟按键),包括5或6个不同的扫描码,但没有任何东西影响我的前景窗口。

我基本上试图将ms3200上的缩放栏变成滚动控件,所以我甚至可能发错键(向上和向下)。

3 个答案:

答案 0 :(得分:2)

调用keybd_event是正确的。如果你所做的只是一个关键,也许窗口会处理关键消息。你真的需要发送一个键,然后是一个键:

keybd_event(VK_UP, 75, 0, NULL);
keybd_event(VK_UP, 75, KEYEVENTF_KEYUP, NULL);

或者,更好的是,当OEM密钥关闭时将密钥发送下来,并在OEM密钥上升时按下密钥。您可以通过kbStruct-&gt; flags&amp; amp来告知向下/向上状态。 LLKHF_UP。

答案 1 :(得分:1)

您可能希望使用SendInput,因为keybd_event已被取代。 MSDN杂志文章C++ Q&A: Sending Keystrokes to Any App有一个有用的例子。

答案 2 :(得分:0)

您可能想要尝试Control-UpArrow和Control-DownArrow而不是Up和Down。然而,这似乎并不适用于所有应用程序,甚至在它可行的应用程序中,它可能取决于焦点所在。