【问题标题】:SendInput vs. keybd_eventSendInput 与 keybd_event
【发布时间】:2013-09-10 20:10:57
【问题描述】:

MSDN 声明 keybd_event 已被 SendInput 取代。在重写期间,我切换到使用 SendInput ......这很好 except 在尝试发送 Alt 键组合时。在 Win7 64 位系统上(尚未在其他地方尝试过),发送 Alt 键会导致在目标应用程序中出现击键之前有很长的延迟。

任何想法为什么?还是我做错了什么?现在,我回到了 keybd_event——下面的第二个版本。

//Keyboard input from this version appears only after a ~4-5 second
//time lag...
procedure SendAltM;
var
  KeyInputs: array of TInput;
  KeyInputCount: Integer;
  //--------------------------------------------
  procedure KeybdInput(VKey: Byte; Flags: DWORD);
  begin
    Inc(KeyInputCount);
    SetLength(KeyInputs, KeyInputCount);
    KeyInputs[KeyInputCount - 1].Itype := INPUT_KEYBOARD;
    with  KeyInputs[KeyInputCount - 1].ki do
    begin
      wVk := VKey;
      wScan := MapVirtualKey(wVk, 0);
      dwFlags := KEYEVENTF_EXTENDEDKEY;
      dwFlags := Flags or dwFlags;
      time := 0;
      dwExtraInfo := 0;
    end;
  end;
begin
  KeybdInput(VK_MENU, 0);                 // Alt
  KeybdInput(Ord('M'), 0);                 
  KeybdInput(Ord('M'), KEYEVENTF_KEYUP);   
  KeybdInput(VK_MENU, KEYEVENTF_KEYUP);   // Alt
  SendInput(KeyInputCount, KeyInputs[0], SizeOf(KeyInputs[0]));
end;


//Keyboard input from this version appears immediately...
procedure SendAltM;
begin
  keybd_event( VK_MENU, MapVirtualkey( VK_MENU, 0 ), 0, 0);
  keybd_event( Ord('M'), MapVirtualKey( Ord('M'),0), 0, 0);
  keybd_event( Ord('M'), MapVirtualKey( Ord('M'),0), KEYEVENTF_KEYUP, 0);
  keybd_event( VK_MENU, MapVirtualkey( VK_MENU, 0 ), KEYEVENTF_KEYUP, 0);
end;

【问题讨论】:

  • keybd_event 的这个大问题是您的事件可能会与真实事件拼接。所以SendInput 就是工作。不知道你为什么会遇到问题。然而。

标签: delphi keyboard-events sendinput


【解决方案1】:

问题 1

您没有初始化KeyInputCount。所以它的值是不确定的。在第一次调用KeybdInput 之前将其设置为零。或者干脆去掉它,改用Length(KeyInputs)

问题 2

您的dwFlags 设置不正确。不要包含KEYEVENTF_EXTENDEDKEY。您没有将它包含在调用keybd_event 的代码中,并且您不应该将它包含在SendInput 中。

更正的代码

此版本有效。

procedure SendAltM;
var
  KeyInputs: array of TInput;
  //--------------------------------------------
  procedure KeybdInput(VKey: Byte; Flags: DWORD);
  begin
    SetLength(KeyInputs, Length(KeyInputs)+1);
    KeyInputs[high(KeyInputs)].Itype := INPUT_KEYBOARD;
    with  KeyInputs[high(KeyInputs)].ki do
    begin
      wVk := VKey;
      wScan := MapVirtualKey(wVk, 0);
      dwFlags := Flags;
    end;
  end;
begin
  KeybdInput(VK_MENU, 0);                 // Alt
  KeybdInput(Ord('M'), 0);
  KeybdInput(Ord('M'), KEYEVENTF_KEYUP);
  KeybdInput(VK_MENU, KEYEVENTF_KEYUP);   // Alt
  SendInput(Length(KeyInputs), KeyInputs[0], SizeOf(KeyInputs[0]));
end;

【讨论】:

  • 未初始化的计数可以解释延迟。操作系统将花费不知道多长时间来处理数组中所有虚假的空鼠标事件,然后最终到达最后的四个有效键盘事件。
  • @Rob 主要问题是我认为的错误标志。
  • 感谢大卫和@Rob。我不知道未初始化的 KeyInputCount 或标志是否是问题所在;很高兴能弄清楚这一点。哦,很容易看出 KeyInputCount 未初始化......现在其他人已经指出了!
【解决方案2】:

这样你就可以使用keybd_event:

keybd_event( VK_MENU, MapVirtualkey( VK_MENU, 0 ), KEYEVENTF_EXTENDEDKEY or 0, 0);
  keybd_event( Ord('M'), MapVirtualKey( Ord('M'),0), KEYEVENTF_EXTENDEDKEY or 0, 0);
  keybd_event( Ord('M'), MapVirtualKey( Ord('M'),0), KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
  keybd_event( VK_MENU, MapVirtualkey( VK_MENU, 0 ), KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);

【讨论】:

    猜你喜欢
    • 2017-12-13
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 2011-10-13
    • 1970-01-01
    相关资源
    最近更新 更多