使用WinAPI将击键发送到另一个应用程序

Vit*_*.us 4 delphi winapi postmessage delphi-7 sendmessage

我有喜欢发送击键它来控制其他应用程序CTRLSCTRLSHIFTCCTRLF.

我尝试了很多东西,但是我无法让它发挥作用.所以我试图在一个更简单的案例中做到这一点.

这成功发送Hey到记事本:

procedure TForm1.Button1Click(Sender: TObject);
  var notepad, edit: HWND;
begin
  notepad := FindWindow('notepad', nil);
  edit := FindWindowEx(notepad, FindWindow('Edit', nil), nil, nil);

  SendMessage(edit, WM_CHAR, dword('H'), 0);
  SendMessage(edit, WM_CHAR, dword('e'), 0);
  SendMessage(edit, WM_CHAR, dword('y'), 0);
end;
Run Code Online (Sandbox Code Playgroud)

这成功地将F5密钥发送到记事本,并且还可以F3弹出查找对话框.

notepad := FindWindow('notepad', nil);
PostMessage(notepad, WM_KEYDOWN, VK_F5, 0);
PostMessage(notepad, WM_KEYUP, VK_F5, 0);
Run Code Online (Sandbox Code Playgroud)

但我不知道为什么使用SendMessage上面的例子不起作用.

我能提出的最好的事情就是这样,什么都不做.

notepad := FindWindow('notepad', nil);
PostMessage(notepad, WM_KEYDOWN, VK_CONTROL, 0);
PostMessage(notepad, WM_KEYDOWN, VkKeyScan('F'), 0);
PostMessage(notepad, WM_KEYUP, VkKeyScan('F'), 0);
PostMessage(notepad, WM_KEYUP, VK_CONTROL, 0);
Run Code Online (Sandbox Code Playgroud)

我在这里发现了一个库,它有点模仿VBScript发送键功能,但只是查看代码,它似乎只是向当前应用程序或所有应用程序广播键,因为没有Handle参数.

And*_*and 5

警告:此方法取决于实现细节,如果您需要保证程序的正确性,则不应使用此方法.(另一方面,你已经在那条路上.例如,IIRC,在Windows 95中甚至没有Go to对话框.)

notepad.exe在我最喜欢的资源编辑器中打开,并调查了菜单栏.我注意到Save菜单项的ID 是3.因此,以下代码Save在记事本中执行菜单命令:

var
  notepad: HWND;
begin
  notepad := FindWindow('notepad', nil);

  SendMessage(notepad, WM_COMMAND, 3, 0);
Run Code Online (Sandbox Code Playgroud)

同样的,Find21在我的版本的notepad.exe.Go to24.

根据评论更新:如果你需要发送Ctrl+ Key,你可以使用SendInput:

var
  notepad: HWND;
  inputArray: array[0..3] of TInput;
begin
  notepad := FindWindow('notepad', nil);

  // TODO: Either exit if notepad isn't focused, or set focus to notepad

  FillChar(inputArray, length(inputArray) * sizeof(TInput), 0);

  inputArray[0].Itype := INPUT_KEYBOARD;
  inputArray[0].ki.wVk := VK_LCONTROL;
  inputArray[1].Itype := INPUT_KEYBOARD;
  inputArray[1].ki.wVk := VkKeyScan('S');
  inputArray[2].Itype := INPUT_KEYBOARD;
  inputArray[2].ki.wVk := VkKeyScan('S');
  inputArray[2].ki.dwFlags := KEYEVENTF_KEYUP;
  inputArray[3].Itype := INPUT_KEYBOARD;
  inputArray[3].ki.wVk := VK_LCONTROL;
  inputArray[3].ki.dwFlags := KEYEVENTF_KEYUP;

  SendInput(length(inputArray), inputArray[0], sizeof(TInput));
Run Code Online (Sandbox Code Playgroud)