如何使用 delphi 2010 将虚拟键发送到其他应用程序?

Posted

技术标签:

【中文标题】如何使用 delphi 2010 将虚拟键发送到其他应用程序?【英文标题】:How to send virtual keys to other application using delphi 2010? 【发布时间】:2013-08-10 15:53:38 【问题描述】:

我需要将几个虚拟键 (VK_RETURN) 从我的 delphi 应用程序 (myapp.exe) 发送到另一个应用程序 (target.exe)。 Eg : Send VK_RETURN twice , from myapp.exe , into target.exe

我使用的操作系统是 Windows 7 64 位和 Windows XP。

我读到:How to send an "ENTER" key press to another application?、Send Ctrl+Key to a 3rd Party Application(对我不起作用)和其他以前提出的问题。 但我仍然感到困惑。

如何将焦点设置到目标应用程序?

如何将虚拟键发送到目标应用程序?

简单示例:我想将 VK_RETURN 两次发送到 notepad.exe 或 calc.exe(已加载)或我的 delphi 应用程序中的任何其他程序。怎么做 ?

请在 Delphi 2010 中执行此操作的最简单方法...

PS: 我从http://delphi.about.com/od/adptips2004/a/bltip1104_3.htm 尝试了 SndKey32.pass 并得到错误:[DCC Error] SndKey32.pas(420): E2010 Incompatible types: 'Char' and 'AnsiChar'

  If (Length(KeyString)=1) then MKey:=vkKeyScan(KeyString[1])

【问题讨论】:

焦点是什么意思。窗口,还是上面的特定控件? Delphi XE - Send Ctrl+Key to 3rd Party Application的可能重复 @Tony : focus 表示直接将虚拟键发送到 target.exe @Ken White :在我问这个问题之前,我已经阅读了该链接以及建议的所有链接。但是如何仅将虚拟密钥发送到 target.exe 中? 如果我的问题很难理解,我只想从我的 delphi 应用程序中将 VK_RETURN 发送到 notepad.exe(已经加载)两次。该怎么做? 【参考方案1】:

如果您的目标应用程序不是前台窗口,您需要使用PostMessage 将击键发送到其窗口句柄。您可以使用FindWindow 获取该窗口句柄。下面的代码将 Enter 键发送到正在运行的记事本实例中的文本区域(请注意,它首先使用附加的FindWindowEx 来定位备忘录区域)。它在 Windows 7 64 上使用 Delphi 2007 和 Delphi XE4(32 位目标)进行了测试。

uses Windows;
    
procedure TForm1.Button1Click(Sender: TObject);
var
  NpWnd, NpEdit: HWnd;
begin
  NpWnd := FindWindow('Notepad', nil);
  if NpWnd <> 0 then
  begin
    NpEdit := FindWindowEx(NpWnd, 0, 'Edit', nil);
    if NpEdit <> 0 then
    begin
      PostMessage(NpEdit, WM_KEYDOWN, VK_RETURN, 0);
      PostMessage(NpEdit, WM_KEYUP, VK_RETURN, 0); 
    end;
  end;
end;

要改为按标题(标题)查找窗口,您可以使用FindWindow 的第二个参数。这会找到一个新的记事本实例,其中默认打开了“无标题”文件:

NpWnd := FindWindow(nil, 'Untitled - Notepad');

请注意,这需要在窗口标题上进行 精确 匹配。例如,- 之前或之后的额外空格将导致匹配失败并且无法检索窗口句柄。

如果您有多个实例正在运行,您可以同时使用窗口类和标题。要查找加载了Readme.txt 的记事本副本,您可以使用

NpWnd := FindWindow('Notepad', 'Readme.txt - Notepad');

要查找其他应用程序,您需要使用 WinSpy 或 WinSight 之类的工具来查找窗口类名称。 (还有其他的,例如 Winspector 或 WinDowse(两者都是用 Delphi 编写的)。)

您的评论提到了Calculator;根据 Winspector,Calculator 主窗口位于 Windows 7 上名为 CalcFrame 的窗口类中,显示数字的区域是 Static 窗口(这意味着它似乎不直接接收击键)。这些按钮被简单地称为Button,因此您必须使用EnumChildWindows 遍历它们,寻找各个按钮来识别它们以获得它们的句柄。

(如何枚举子窗口是一个单独的问题;您可能可以通过在此处或通过 Google 搜索找到一个示例。如果您不能,请发布一个新的单独问题,我们可以尝试为您提供答案.)

这是一个在通过窗口类找到它后将键发送到计算器的快速示例。它没有做任何有用的事情,因为它需要花费一些时间来识别不同的按钮和每个响应的键(以及消息的正确组合)。此代码只是将 11Numpad+22 发送到计算器窗口(a快速测试表明它们被正确接收和展示,这就是我想花在这个过程上的所有时间。

uses Windows;

procedure TForm1.Button1Click(Sender: TObject);
var
  NpWnd: HWnd;
begin
  NpWnd := FindWindow('CalcFrame',  nil);
  if NpWnd <> 0 then
  begin
    PostMessage(NpWnd, WM_KEYDOWN, VK_NUMPAD1, 0);
    PostMessage(NpWnd, WM_KEYDOWN, VK_ADD, 0);
    PostMessage(NpWnd, WM_KEYDOWN, VK_NUMPAD2, 0);
  end;
end;

【讨论】:

是的,它可以在记事本中使用。但是其他应用程序呢?我有一个名为 DKQC.EXE 和 DKQG.EXE 的应用程序,我想在 DKQG.EXE 内发送两次 Enter (VK_Return) 击键以获得按钮及其确认消息,以替换鼠标单击。 或者你可以用acdess12.exe测试脚本,在哪里打开一个文件夹,我们按回车/回车。要在其中打开一个文件,我们按另一个回车键(两次回车键)。如何使其在 ACDSee12.exe 中工作?因为你的脚本只能在记事本上运行。 我的“脚本”(它不是脚本,它是代码)可以在记事本上运行,因为这就是它专门寻找的内容(以及 you asked for 的内容)。如果您需要它为另一个应用程序工作,您需要弄清楚您需要寻找什么窗口类 - 我没有在我的计算机上安装我不需要的软件来为您找出它。 :-) 搜索 WinSpy 或 WinSight,它们可以帮助您找到该信息(就像我在记事本中所做的那样)。 我将您链接到文档,并为您提供了有关 WinSpy 和 WinSight 的信息(还有 WInspector 和 WinDowse)。如果您打算使用 WinAPI 做事,有时您需要阅读文档并弄清楚。我将更新我的代码,同时向 Calc 发送几个数字键(并按名称查找),但之后您需要使用我给您的工具并花一些时间自己尝试解决这个问题。 :-) @ShaunRoselt:它们是在 Windows.pas 中定义的。

以上是关于如何使用 delphi 2010 将虚拟键发送到其他应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

Delphi 2010 虚拟键盘,以CapsLock 开头?

delphi 对右键菜单的操作

你如何干净地中止一个 Delphi 程序?

如何将Outlook发送的电子邮件唯一匹配到其对应的Outlook草稿(MAPI MailItem)

如何理解网站正在将上传的文件发送到其服务器?

delphi to java,soap delphi,短信发送