Articles

This example shows, how to break the 'hello' string on symbols. And for each symbol two messages WM_KEYDOWN and WM_KEYUP are created. These messages are brought in the list of the messages. After that the hook is created, which processes these messages in the Word document. ... type TMessageList = class(TList); var Form1: TForm1; MessageList: TMessageList = nil; MessageBuffer: TEventMsg; HookHandle: hHook = 0; MessageCount: Word = 0; Go: Boolean = False; implementation {$R *.DFM}

procedure Stop;
begin
  if Go then UnHookWindowsHookEx(HookHandle);
  MessageList.Free;
  Go:=False;
end;

function FBack(Code: Integer; wParam, lParam: LongInt): LongInt; stdcall;
begin
  case Code of
    HC_SKIP:
    begin
      Inc(MessageCount);
      if MessageCount>=MessageList.Count then Stop
      else MessageBuffer:=TEventMsg(MessageList.Items[MessageCount]^);
      Result:=0;
    end;
    HC_GETNEXT:
    begin
      PEventMsg(lParam)^:=MessageBuffer;
      Result:=0;
    end
    else
      Result:=CallNextHookEx(HookHandle, Code, wParam, lParam);
  end;
end;

procedure SetHook;
begin
  MessageBuffer:=TEventMsg(MessageList.Items[0]^);
  MessageCount:=0;
  HookHandle:=SetWindowsHookEx(WH_JOURNALPLAYBACK, FBack, hInstance, 0);
  Go:=True;
end;

procedure MakeMessage(Key: byte; Mes: Cardinal);
var
  MyEvent: PEventMsg;
begin
  New(MyEvent);
  with MyEvent^ do
  begin
    message:=Mes;
    ParamL:=Key;
    ParamH:=MapVirtualKey(Key, 0);
    Time:=GetTickCount;
    hWnd:=Form1.Handle;
  end;
  MessageList.Add(MyEvent);
end;

procedure Imitation(KeyCode: Word);
begin
  MakeMessage(Lo(KeyCode), WM_KEYDOWN);
  MakeMessage(Lo(KeyCode), WM_KEYUP);
end;

procedure SetMessages(S: string);
var
  i: Integer;
  KeyCode: Word;
begin
  i:=1;
  repeat
    KeyCode:=vkKeyScan(S[i]);
    Imitation(KeyCode);  // simulate key presses
    Inc(i);
  until i>Length(S);
end;

function SendStr(S: string): Integer;
begin
  try
    MessageList:=TMessageList.Create;
    SetMessages(S);  // set messages
    SetHook;         // set hook
  except
  end;
  Result:=0;  
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Handle: hWnd;
  ProcessInfo: TProcessInformation;
  StartInfo: TStartUpInfo;
  APath: string;
begin
  APath:=Edit1.Text;
  if CreateProcess(
       nil, 
       PChar(APath), 
       nil,
       nil, 
       False, 
       0, 
       nil, 
       nil, 
       StartInfo, 
       ProcessInfo) then
  begin
    WaitForInputIdle(ProcessInfo.hProcess, INFINITE);
    Handle:=FindWindow('winword', nil);
    SetForegroundWindow(Handle);
    SendStr('hello');
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
    Edit1.Text:=OpenDialog1.FileName;
end;