2

I've been trying to send keystrokes to a notepad window in Delphi. That's the code I have so far:

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.

I've also found this example:

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.

How can I simulate/Send CTRL+V to a Parentwindow so it would also work with other applications? Not every application has the same ClassNames and controls as notepad.

Ben
  • 3,380
  • 2
  • 44
  • 98
  • 1
    Do you know if it's getting the handle correctly? (e.g., pop up a message if your `if` triggers) – lurker Jun 08 '13 at 18:23
  • 3
    Why don't you post `WM_PASTE` message instead ? – TLama Jun 08 '13 at 18:23
  • It finds the handle of the window and it's valid. I've also tried `SendMessage(H, WM_PASTE, 0, 0);` but with no success. – Ben Jun 08 '13 at 18:24

1 Answers1

4

If you switch SendMessage() to PostMessage(), it will work:

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.

According to this thread, I beleive you cannot use SendMessage()/PostMessage() to send state of key modifiers (CTRL in this case), and that your only option is to go with SendInput(), but that will work only on window that currently has focus.

Community
  • 1
  • 1
rsrx
  • 1,433
  • 1
  • 13
  • 25
  • This would work, but you need a control handle. What if I want to use it in another application which has not a `Edit` Class at all? I would need to find the active child window that's currently focused, and I don't know how to that. – Ben Jun 08 '13 at 19:15
  • 1
    Thats another question. If application that you want to paste in currently has focus, why just not go with SendInput()? – rsrx Jun 08 '13 at 19:19
  • 1
    Anyways, you can enumerate child windows with EnumChildWindows() API. – rsrx Jun 08 '13 at 19:22
  • Thank you this works! I've also used a `AttachThreadInput` technique with this. – Ben Jun 08 '13 at 19:23