模拟按键,但仅模拟特定窗口?

时间:2018-09-06 18:02:05

标签: delphi

有许多有关如何使用Windows API模拟按键操作的示例。一种选择是类似于下面的代码。

但是,我要努力实现的目标又是一步。下面的代码要求您要发送密钥的应用程序始终是前台窗口。我正在尝试将键发送到一个没有聚焦的窗口,因此我可以在最小化该窗口的情况下自动执行任务/宏。

还有其他选择吗?

谢谢

procedure PostKeyEx32(key: Word; const shift: TShiftState;
  specialkey: Boolean);
type
    TShiftKeyInfo = record
      shift: Byte ;
      vkey: Byte ;
    end;
    ByteSet = set of 0..7 ;
 const
    shiftkeys: array [1..3] of TShiftKeyInfo =
      ((shift: Ord(ssCtrl) ; vkey: VK_CONTROL),
      (shift: Ord(ssShift) ; vkey: VK_SHIFT),
      (shift: Ord(ssAlt) ; vkey: VK_MENU)) ;
 var
    flag: DWORD;
    bShift: ByteSet absolute shift;
    j: Integer;
 begin
    for j := 1 to 3 do
    begin
      if shiftkeys[j].shift in bShift then
        keybd_event(shiftkeys[j].vkey, MapVirtualKey(shiftkeys[j].vkey, 0), 0, 0) ;
    end;
    if specialkey then
      flag := KEYEVENTF_EXTENDEDKEY
    else
      flag := 0;

    if key = 47 then
      begin
      keybd_event(VkKeyScan('/'), 1, 0, 0);
      end
      else
      begin
      keybd_event(key, MapvirtualKey(key, 0), flag, 0) ;
      flag := flag or KEYEVENTF_KEYUP;
      keybd_event(key, MapvirtualKey(key, 0), flag, 0) ;
      end;

    for j := 3 downto 1 do
    begin
      if shiftkeys[j].shift in bShift then
        keybd_event(shiftkeys[j].vkey, MapVirtualKey(shiftkeys[j].vkey, 0), KEYEVENTF_KEYUP, 0) ;
    end;
 end;

2 个答案:

答案 0 :(得分:3)

这是一个通过特定窗口发送/处理WM_KEYUP消息的示例。但这对于其他任何消息类型都是相同的(自定义消息类型也一样,只是参数取决于其类型) 目标窗口必须实现消息处理程序过程。

procedure onKeyPressed( var message_ : TWMKeyUp ); message WM_KEYUP;

要发送消息,必须使用带有正确参数的sendMessage。 第一个参数是窗口的句柄,第二个参数是消息ID,第三个和第四个参数取决于消息ID定义的消息类型。

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure onKeyPressed( var message_ : TWMKeyUp ); message WM_KEYUP;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if ( edit1.text <> '' ) then
    sendMessage( handle, WM_KEYUP, cardinal( edit1.text[1] ), 0 );
end;

procedure TForm1.onKeyPressed( var message_ : TWMKeyUp );
var
  c : char;
begin
  c := char( message_.CharCode );
  label1.caption := label1.caption + c;
end;

答案 1 :(得分:1)

对于大多数应用程序,WM_KEYDOWN和WM_KEYUP就足够了: http://www.delphigroups.info/2/80/324746.html

但是对于某些应用,您将需要在API hooks上使用functions like GetAsyncKeyState,以及将dll加载到目标进程中的方法:https://progamercity.net/delphi/647-delphi-dll-injection-functions.html。从防病毒软件的角度来看,所有这些都是非常可疑的。