检测另一个进程中按下的键

时间:2014-07-12 22:42:19

标签: delphi process keyboard

我有一个Delphi 2007 Win32可执行文件,可以将键击发送到其他应用程序。我的应用程序是通过F11或Shift + F11等热键从这些目标应用程序中调用的。

我希望用户能够按住键来中止键击发送(例如,如果他们意识到他们在错误的位置调用了我的应用程序)。我曾认为Shift,Ctrl和Alt是很好的候选者,因为单独这些按键不会破坏目标应用程序中的任何内容。 (例如,逃避是一个糟糕的选择,因为它可能导致目标应用程序关闭一个或多个窗口。)

我在下面写了下面的函数并定期调用它,如下所示,同时发送按键以检测按下的键。

if wsAnyKeysDownInWindow( TgtWindow, [VK_Escape, VK_Menu{Alt}, VK_Control, VK_Shift] ) then 
  Abort;

问题是,我的应用程序发送按键组合,如Shift + Tab和Ctrl + Home,这(我认为)使这种方法失败 - 总是检测到Shift和/或Ctrl的关闭状态。 (我还尝试了一个类似的功能,在开始发送击键之前调用SetKeyboardState,设置关键状态'高阶(向下)位,但这没有帮助。)

有人想到一种可行的方法,而不是挂钩键盘吗?

function wsAnyKeysDownInWindow(Handle: HWnd; VKeys: array of byte): boolean;
{ Checks whether each of the VKeys set of virtual keys is down in Handle,
  a window created by another process. }
var
  OtherThreadID : integer;
  State: TKeyboardState;
  AKey: byte;
begin
  Result := False;
  if not IsWindow(Handle) then
    exit;
  OtherThreadID := GetWindowThreadProcessID( Handle, nil);
  if AttachThreadInput( GetCurrentThreadID, OtherThreadID, True ) then try
    GetKeyboardState(State);
    for AKey in VKeys do
      if (State[AKey] and 128) <> 0 then begin  //If high-order bit is set, key is down
        Result := True;
        exit;
      end;
  finally
    AttachThreadInput( GetCurrentThreadID, OtherThreadID, False );
  end;
end;

1 个答案:

答案 0 :(得分:0)

考虑使用Scroll Lock。它很少使用(只有Excel出现在我的脑海中),如果正在发送密钥,你甚至会有视觉指示。

BTW,Alt不是另一个原因的好选择 - 它调用应用程序中的主菜单(当然,如果有的话)。