Recent

Author Topic: Need assistance how to set Focus on (Win10) Notepad & send key-presses to it.  (Read 4534 times)

ocnuybear

  • New member
  • *
  • Posts: 7
Hi I'm new to Delphi with some background in VB.Net & have done the Lazarus Tutorial, would like to know how to automate other win apps like setting focus on it and sending it key strokes or hotkeys.

I have tried this code:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.   var notepad, edit: HWND;
  3. begin
  4.   notepad := FindWindow('notepad', nil);
  5.   edit := FindWindowEx(notepad, FindWindow('Edit', nil), nil, nil);
  6.  
  7.   SendMessage(edit, WM_CHAR, dword('H'), 0);
  8.   SendMessage(edit, WM_CHAR, dword('e'), 0);
  9.   SendMessage(edit, WM_CHAR, dword('y'), 0);
  10. end;

But it is complaining about the HWND, so my question is how is HWND declared or is there any additional packages needed?

Or is there an better way to do it?

taazz

  • Hero Member
  • *****
  • Posts: 5368
Hi I'm new to Delphi with some background in VB.Net & have done the Lazarus Tutorial, would like to know how to automate other win apps like setting focus on it and sending it key strokes or hotkeys.

I have tried this code:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.   var notepad, edit: HWND;
  3. begin
  4.   notepad := FindWindow('notepad', nil);
  5.   edit := FindWindowEx(notepad, FindWindow('Edit', nil), nil, nil);
  6.  
  7.   SendMessage(edit, WM_CHAR, dword('H'), 0);
  8.   SendMessage(edit, WM_CHAR, dword('e'), 0);
  9.   SendMessage(edit, WM_CHAR, dword('y'), 0);
  10. end;

But it is complaining about the HWND, so my question is how is HWND declared or is there any additional packages needed?

Or is there an better way to do it?
add lcltype in the uses clause of your unit
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   lcltype;//add this
  10.  
  11.  
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

ocnuybear

  • New member
  • *
  • Posts: 7
Thank you, but now it says when compiling:

Compile Project, Target: project1.exe: Exit code 1, Errors: 1
unit1.pas(9,3) Fatal: Syntax error, "IMPLEMENTATION" expected but "identifier LCLTYPE" found

taazz

  • Hero Member
  • *****
  • Posts: 5368
Thank you, but now it says when compiling:

Compile Project, Target: project1.exe: Exit code 1, Errors: 1
unit1.pas(9,3) Fatal: Syntax error, "IMPLEMENTATION" expected but "identifier LCLTYPE" found
that's because you did not do it properly (I guess). Check to make sure that between the key word uses and the last unit name on that clause, in this case I guess it is lcltype) there are no semicolons except the one after the last unit name. if everything else fails post the complete unit code (assuming only has code for the problem at hand) so we can see where things wend of road.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

ocnuybear

  • New member
  • *
  • Posts: 7
Ok I saw I had this:
Code: Pascal  [Select][+][-]
  1. uses
  2.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
  3.   lcltype;
  4. type    

that should have been this:

Code: Pascal  [Select][+][-]
  1. uses
  2.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  3.   lcltype;
  4. type    
[/code]

the lcltype works now, but now it asks this:

Compile Project, Target: project1.exe: Exit code 1, Errors: 9
unit1.pas(44,14) Error: Identifier not found "FindWindow"
unit1.pas(45,11) Error: Identifier not found "FindWindowEx"
unit1.pas(45,33) Error: Identifier not found "FindWindow"
unit1.pas(47,3) Error: Identifier not found "SendMessage"
unit1.pas(47,21) Error: Identifier not found "WM_CHAR"
unit1.pas(48,3) Error: Identifier not found "SendMessage"
unit1.pas(48,21) Error: Identifier not found "WM_CHAR"
unit1.pas(49,3) Error: Identifier not found "SendMessage"
unit1.pas(49,21) Error: Identifier not found "WM_CHAR"


« Last Edit: July 27, 2018, 12:23:44 pm by ocnuybear »

Pascal

  • Hero Member
  • *****
  • Posts: 932
Place your cursor on FindWindow and press F1 and you'll see (after a while) that FindWindow is located
in unit windows. Add it to your uses clause.
laz trunk x64 - fpc trunk i386 (cross x64) - Windows 10 Pro x64 (21H2)

ocnuybear

  • New member
  • *
  • Posts: 7
Mouse over the error says the compiler does not know this symbol and pressing F1 says "No Help found"

ocnuybear

  • New member
  • *
  • Posts: 7
I presume sending keystrokes to an application is not so straightforward?

Pascal

  • Hero Member
  • *****
  • Posts: 932
Never mind! Just add windows to the used units.
laz trunk x64 - fpc trunk i386 (cross x64) - Windows 10 Pro x64 (21H2)

ocnuybear

  • New member
  • *
  • Posts: 7
Finally it is working after adding Windows - thank you all  :)

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   lcltype,Windows;
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     Button2: TButton;
  17.     procedure Button1Click(Sender: TObject);
  18.     procedure Button2Click(Sender: TObject);
  19.   private
  20.  
  21.   public
  22.  
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. { TForm1 }
  33.  
  34. procedure TForm1.Button1Click(Sender: TObject);
  35.   var notepad, edit: HWND;
  36. begin
  37.   notepad := FindWindow('Notepad', nil);
  38.   edit := FindWindowEx(notepad, FindWindow('Edit', nil), nil, nil);
  39.  
  40.   SendMessage(edit, WM_CHAR, dword('H'), 0);
  41.   SendMessage(edit, WM_CHAR, dword('e'), 0);
  42.   SendMessage(edit, WM_CHAR, dword('y'), 0);
  43. end;
  44.  
  45. procedure TForm1.Button2Click(Sender: TObject);
  46. begin
  47.      showmessage('Quitting');
  48.      Close;
  49. end;
  50.  
  51. end.
  52.  

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Finally it is working after adding Windows - thank you all  :)
Do not forget to check the result of the function call
Code: Pascal  [Select][+][-]
  1. uses Windows;
  2.  
  3. procedure TForm1.Button1Click(Sender: TObject);
  4. var
  5.   NotepadApp, NotepadEdit: HWND;
  6.   C: Char;
  7. begin
  8.   NotepadApp := FindWindow('Notepad', nil);
  9.   if NotepadApp = 0 then
  10.     Exit; // No Notepad running
  11.   NotepadEdit := FindWindowEx(NotepadApp, 0, 'Edit', nil);
  12.   if NotepadEdit = 0 then
  13.     Exit; // Notepad without edit ?!?
  14.   for C in 'Hello' do
  15.     SendMessage(NotepadEdit, WM_CHAR, WPARAM(C), 0);
  16. end;

ocnuybear

  • New member
  • *
  • Posts: 7
Ok thank you will do  :D

 

TinyPortal © 2005-2018