【问题标题】:Send CTRL+V to a ParentWindow in Delphi with SendMessage使用 SendMessage 将 CTRL+V 发送到 Delphi 中的 ParentWindow
【发布时间】:2013-06-04 20:10:27
【问题描述】:

我一直在尝试将击键发送到 Delphi 中的记事本窗口。 这是我到目前为止的代码:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  windows,
  messages;

var
  H : HWND;

begin
  H := FindWindowA(NIL, 'Untitled - Notepad');
  if H <> 0 then begin
    SendMessage(H, WM_KEYDOWN, VK_CONTROL, 1);
    SendMessage(H, WM_KEYDOWN, MapVirtualKey(ord('v'), 0), 1);
    SendMessage(H, WM_KEYUP, MapVirtualKey(ord('v'), 0), 1);
    SendMessage(H, WM_KEYUP, VK_CONTROL, 1);
  end;
end.

我也找到了这个例子:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  windows,
  messages;

var
  H : HWND;
  I : Integer;
  s : String;

begin
  h := FindWindowA(NIL, 'Untitled - Notepad');
  if h <> 0 then
  begin
    h := FindWindowEx(h, 0, 'Edit', nil);
    s := 'Hello';
    for i := 1 to Length(s) do
    SendMessage(h, WM_CHAR, Word(s[i]), 0);
    PostMessage(h, WM_KEYDOWN, VK_RETURN, 0);
    PostMessage(h, WM_KEYDOWN, VK_SPACE, 0);
  end;
end.

如何模拟/发送 CTRL+V 到父窗口,以便它也可以与其他应用程序一起使用? 并非每个应用程序都具有与记事本相同的类名和控件。

【问题讨论】:

  • 你知道手柄是否正确吗? (例如,如果您的if 触发,则会弹出一条消息)
  • 你为什么不发WM_PASTE消息呢?
  • 它找到窗口的句柄并且它是有效的。我也试过SendMessage(H, WM_PASTE, 0, 0);,但没有成功。

标签: delphi winapi keyboard keystroke


【解决方案1】:

如果将 SendMessage() 切换为 PostMessage(),它将起作用:

uses
  Winapi.Windows, Winapi.Messages;

procedure PasteTo(const AHWND: HWND);
begin
  PostMessage(AHWND, WM_PASTE, 0, 0);
end;

var
  notepad_hwnd, notepad_edit_hwnd: HWND;

begin
  notepad_hwnd := FindWindow(nil, 'Untitled - Notepad');
  if notepad_hwnd <> 0 then
  begin
    notepad_edit_hwnd := FindWindowEx(notepad_hwnd, 0, 'Edit', nil);
    if notepad_edit_hwnd <> 0 then
      PasteTo(notepad_edit_hwnd);
  end;
end.

根据this thread,我相信您不能使用 SendMessage()/PostMessage() 发送键修饰符的状态(在这种情况下为 CTRL),并且您唯一的选择是使用 SendInput(),但这将仅适用于当前具有焦点的窗口。

【讨论】:

  • 这可行,但您需要一个控制手柄。如果我想在另一个根本没有 Edit 类的应用程序中使用它怎么办?我需要找到当前焦点所在的活动子窗口,但我不知道该怎么做。
  • 那是另一个问题。如果您要粘贴的应用程序当前具有焦点,为什么不使用 SendInput()?
  • 无论如何,您可以使用 EnumChildWindows() API 枚举子窗口。
  • 谢谢你的作品!我还使用了AttachThreadInput 技术。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-21
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多