0

I'm in my first try with WinAPI and I am trying to send some text from a Delphi program (well Lazarus) to Notepad++.

I already found a good example to use simple Notepad, that goes like this :

Procedure TForm1.Button1Click(Sender: TObject);
var Var1, Var2 : HWND;
Begin
    Var1 := FindWindow('notepad', nil);
    Var2 := FindWindowEx(Var1, FindWindow('Edit', nil), nil, nil);
    Clipboard.AsText:='This is some sample text.';
    SendMessage(Var2, WM_PASTE, 0, 0);
End;

So this works fine for Notepad. Now I would like to adapt it to use with any other program. Taking Notepad++ for example, how do I find it's equivalent to 'Edit' used there in the FindWindowEx() ? Or let's say the correct cell and workbook to paste in LibreOffice Calc?

Any samples or clues?

Thanks.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    You can use e.g. Spy++ for inspecting application windows. But there's no ultimate answer for every application. For example mentioned LibreOffice has its own API that you should use. – Victoria Apr 06 '18 at 11:15
  • 1
    `notepad++` and `Scintilla` class names – RbMm Apr 06 '18 at 11:17
  • 1
    "any other program", you basically need a database of every program ever written for Windows. Reconsider your objectives. – Jonathan Potter Apr 06 '18 at 11:20
  • @Victoria Thanks for the tip. I guess that's exactly what i need. Will give it a try. – Paulo Silva Apr 06 '18 at 11:31
  • @RbMm, will test and let you know, thanks – Paulo Silva Apr 06 '18 at 11:32
  • @JonathanPotter, it will be for a very specific usage. I'm just testing with other programs for now to understand exactly how it works. Thanks. – Paulo Silva Apr 06 '18 at 11:32
  • 1
    I would not be happy if random programs overwrote my clipboard! – Anders Apr 06 '18 at 11:42
  • 1
    How are you planning to identify the correct instance, when multiple instances of the target application are running? And @Anders is correct here, too: The clipboard belongs to the user. Your app has no business trashing the user's data. – IInspectable Apr 06 '18 at 11:48
  • 1
    The clipboard belongs to the user, not the programmer. I'd rethink what you're trying to do (or at least how you're doing it). – Ken White Apr 06 '18 at 12:12
  • Don't worry guys, it's for an automated task on a specific situation, just avoiding user input (and typing errors). I'm sure he will not mind ;) And the clipboard, again, is just for testing. Will have to use other method as i can't risk pasting whatever the user had just copy. Basically, the app i'm developing will get info from a QR code, do some treatment and send it to some 3rd party app, filling the corresponding fields minimising user input. A nice little project. – Paulo Silva Apr 06 '18 at 12:41
  • The tool to use is [UI Automation](https://msdn.microsoft.com/en-us/library/windows/desktop/ee684009.aspx). That still doesn't help you answer the question: How do you identify the correct instance to automate, in case there are multiple instances of the target application running. – IInspectable Apr 06 '18 at 13:30
  • @IInspectable Thanks for the info. In this particular case i know the target application won't allow more that one instance. Will not be a problem there. Will take a closer look to UI Automation – Paulo Silva Apr 06 '18 at 14:44
  • 1
    You don't need the clipboard to set the text of an edit control. – Sertac Akyuz Apr 06 '18 at 15:31
  • 1
    In the provided code, the call to `FindWindowEx()` is wrong. It should be `FindWindowEx(Var1, 0, 'Edit', nil)` instead. The original code is using `FindWindow('Edit', nil)` to search for a top-window window and treat it as if it were a child window. It should be looking for an actual child window instead. The original code "works" only because `FindWindow('Edit', nil)` fails and returns 0, and then `FindWindowEx()` ends up returning the 1st child window, which *happens* to be the actual `Edit` window. – Remy Lebeau Apr 06 '18 at 15:37
  • @RemyLebeau, Thanks for the explanation. Actualy, i started from [This Post](https://stackoverflow.com/questions/15853732/sending-keystroke-to-another-application-using-winapi) and have been experimenting since there. I corrected my code and now is working fine. – Paulo Silva Apr 09 '18 at 07:24
  • @SertacAkyuz I'm planing not to do that but if you can point me to a better direction it'll help me get there faster. Thanks. – Paulo Silva Apr 09 '18 at 07:29
  • @Paulo you can send a WM_SETTEXT. message. – Sertac Akyuz Apr 09 '18 at 09:29
  • I'm closing this as for the question asked the solution was found between **RbMm** and **Remy Lebeau**. – Paulo Silva Apr 10 '18 at 12:51
  • @SertacAkyuz Thanks a lot. – Paulo Silva Apr 10 '18 at 12:51

0 Answers0