SendInput与keybd_event

时间:2013-09-06 16:44:28

标签: delphi keyboard-events sendinput

MSDN声明keybd_event已被SendInput取代。在重写期间,我切换到使用SendInput ...在尝试发送Alt-key组合时,除了之外没什么问题。在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;

2 个答案:

答案 0 :(得分:8)

问题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;

答案 1 :(得分:3)

这样您就可以使用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);