填充HARDWAREINPUT结构以与SendInput一起使用的正确方法是什么?

时间:2013-01-27 11:23:57

标签: c++ winapi keyboard hardware sendinput

我正在尝试将WM_KEYDOWN / WM_KEYUP对发送到通常不响应KEYBDINPUT结构使用的应用程序。我需要发送转义键以及字母数字字符。由于MSDN仅提供有关使用硬件结构的模糊信息,我只能假设uMsg字段用于保存WM_KEYDOWN / WM_KEYUP消息,接下来的两个字段用于lParam的LOWORD和HIWORD(由几个位组成)定义扫描码,键是否“重复”等等。

但经过几个小时的调整后,我完全失去了如何正确模拟硬件击键。我该怎么做才能让它发挥作用?

2 个答案:

答案 0 :(得分:2)

你根本不应该使用HARDWAREINPUT。要模拟键盘输入,必须使用INPUT.type = INPUT_KEYBOARD并设置INPUT.ki成员。 INPUT_HARDWARE选项保留给输入设备其他而不是鼠标或键盘。

如果应用程序没有响应此输入,则下一个可能的问题是您有焦点问题。 SendInput()只能在应用程序窗口位于前台并且应用程序中需要输入的子窗口具有焦点时才能工作。这可能很难实现。键入键的另一种方法是将带有SendMessage的WM_CHAR消息直接发送到应该接收它们的窗口。这也避免了处理活动键盘布局和修改键(Alt,Shift,Ctrl)状态的相当大的困难。您现在遇到的一个新问题是检索正确的窗口句柄。

答案 1 :(得分:0)

原来我没有正确实现KEYBDINPUT,并且还在一次调用SendInput时发送每次击键。以下内容似乎适用于目标应用程序中的标准和扩展虚拟键:

VOID SimulateKeystroke(USHORT vk, BOOL bExtended)
{
    INPUT input = {0};

    if(bExtended) input.ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
    input.ki.wVk  = vk;  
    input.type = INPUT_KEYBOARD;
    SendInput(1, &input, sizeof(input));

    ZeroMemory(&input, sizeof(INPUT));
    input.ki.dwFlags  =  KEYEVENTF_KEYUP;
    if( bExtended ) input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;

    input.ki.wVk = vk;
    input.type = INPUT_KEYBOARD;
    SendInput(1, &input, sizeof(input));
}