SendMessage WM_COPY 发送到 chrome window DELPHI 时不起作用

SendMessage WM_COPY not working when sent to chrome window DELPHI

几周来我一直在努力解决这个问题。我正在尝试在 Delphi 中创建一个在后台运行并捕获任何热键并执行 Ctrl + c 的应用程序。所以我所做的是抓住热键,例如 ALT + 右箭头,然后模拟 Ctrl + c 并将命令扔到当前 window.

我注意到,当我尝试向 Firefox 发送命令时,如下所示:

SendMessage(FireFoxHandle, WM_COPY, 0, 0);
sleep(250);
CopiedText := ClipBoard.AsText;

复制成功,我得到了预期的文本。但是,一旦我将同一行代码用于其他 windows,如 chrome(chrome_widget_1) 或记事本,我将无法得到任何东西。所以我尝试的是获取 chrome 和记事本的 child window 并尝试将命令发送到 child window.

  1. Got "Chrome Legacy Window" as child of "chrome_widget_1" window 但是当我尝试 select 选项卡中的文本时,模拟Ctrl + c,还是不行。

  2. 在 Whosebug 中找到了一个示例,用于将 wm_copy 发送到记事本的 child window,这是一个类似于以下代码的编辑:

ParentWindw := FindWindow('Notepad',nil);
if ParentWindow <> 0 then
begin
  ChildWindow := FindWindowEx(ParentWindow, 0, 'Edit', nil);
  SendMessage(ChildWindow, WM_COPY, 0, 0);
  sleep(250);
  CopiedText := ClipBoard.AsText;
end;

该代码有效,但是否有任何动态方法来确定我需要用于 wm_copy 命令的 child window?我不仅要记事本 window,而且要所有可以使用的 window。

或者无论如何我可以在 window 中以编程方式在 Delphi 中特别是在 xe2 中复制突出显示的文本?

我已经研究过 sendenput、keyevents 并尝试过它们,但没有成功。我 运行 无法选择如何让它工作。

提前感谢您的帮助。

好的。在此处 Topic: [SOLVED] Simulate ctrl+c press in active application (Windows). One of the people there suggested to use "MouseAndKeyInput" which can be found and downloaded here BGRA Controls 发现了与我相关的问题。下载后 link 会找到 5 个文件,即:

KeyInputIntf.pas
MouseAndKeyInput.pas
MouseInputIntf.pas
WinKeyInput.pas
WinMouseInput.pas

将这些文件添加到我的项目中并将 "MouseAndKeyInput" 声明为我的项目的实现用途。现在在我模拟 ctr c:

的程序中
Sleep(250);

KeyInput.Apply([ssCtrl]);
KeyInput.Press('C');
KeyInput.Unapply([ssCtrl]);

Sleep(250);

Memo1.Lines.Add(Clipboard.AsText);

备忘录中出现的文本是我从我目前正在使用的当前活动应用程序中突出显示的文本或行。

能够对 google chrome 选项卡和记事本以及任何其他应用程序执行此操作。

感谢所有在这里提供帮助的人!

您在接受的答案中提供的 MouseAndKeyInput 代码只是 Windows 上 SendInput() 的包装,我在评论中告诉您使用 3 天以前。您可以(并且应该)完全摆脱那 5 个 .pas 文件,并将这 3 个单独的 KeyInput 方法调用替换为对 SendInput() 的 1 次调用。它可以一次发送所有 4 个键输入(Ctrl down、C down、C up、Ctrl up)atomically(这对于确保其他事件不会与您的活动),例如:

var
  Inputs: array[0..3] of TInput;
begin
  ZeroMemory(@Inputs, SizeOf(Inputs));

  Sleep(250);

  Inputs[0].type := INPUT_KEYBOARD;
  Inputs[0].ki.wVk := VK_CONTROL;

  Inputs[1].type := INPUT_KEYBOARD;
  Inputs[1].ki.wVk := Ord('C');

  Inputs[2].type := INPUT_KEYBOARD;
  Inputs[2].ki.wVk := Ord('C');
  Inputs[2].ki.dwFlags := KEYEVENTF_KEYUP;

  Inputs[3].type := INPUT_KEYBOARD;
  Inputs[3].ki.wVk := VK_CONTROL;
  Inputs[3].ki.dwFlags := KEYEVENTF_KEYUP;

  SendInput(4, Inputs, SizeOf(TInput));

  Sleep(250);

  Memo1.Lines.Add(Clipboard.AsText);
end;

调用 SendInput() 并将其 cInputs 参数设置为 1(如 KeyInputMouseInput 那样)几乎总是实践中的一个错误,只应在极少数情况下完成。