Clicking a button in another application

Good day all :)

I am trying to simulate a button click on another application form, I have figured it out except for one small snag.

As the second application is mine and I have the source for it, the attached code works. However when I send "ControlCaption" as an empty string, it doesn't work - I understand why but not how to get around it. I would prefer not to make unnecessary modifications to the second application.

My question: How do I simulate a button click to a TSpeedButton which a) has no handle and b) has no caption/text only an image?

Kind Regards
Procedure ClickButton(WindowName, WindowCaption,
  ControlName, ControlCaption: String);
Var
  hParent, hControl : HWND;
Begin
  hParent := 0;
  hControl := 0;

  hParent := FindWindow(pChar(WindowName), pChar(WindowCaption));

  Try
    BringWindowToTop(hParent);
    Application.ProcessMessages;

    hControl := FindWindowEx(hParent, 0, pChar(ControlName),
      pChar(ControlCaption));

    Try
      SendMessage(hControl, BM_CLICK, 0,0);
    Finally
      hControl := 0;
    End;
  Finally
    hParent := 0;
  End;
End;

// WindowName: The name of the form (eg: TForm1)
// WindowCaption: The caption of the form (eg: Form1)
// ControlName: The name of the control (eg: TButton)
// ControlCaption: The text/caption of the control (eg: Ok)

Procedure Button2Click(Sender: TObject);
Begin
  ClickButton('TForm1', 'Form1', 'TSpeedbutton', '');
End;

Open in new window

DeonMAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Dagan HooverDeveloperCommented:
Hmm, try:
Procedure ClickButton(WindowName, WindowCaption,
  ControlName, ControlCaption: PChar);
Var
  hParent, hControl : HWND;
Begin
  hParent := 0;
  hControl := 0;

  hParent := FindWindow(WindowName, WindowCaption);

  Try
    BringWindowToTop(hParent);
    Application.ProcessMessages;

    hControl := FindWindowEx(hParent, 0, ControlName,
      ControlCaption);

    Try
      SendMessage(hControl, BM_CLICK, 0,0);
    Finally
      hControl := 0;
    End;
  Finally
    hParent := 0;
  End;
End;

// WindowName: The name of the form (eg: TForm1)
// WindowCaption: The caption of the form (eg: Form1)
// ControlName: The name of the control (eg: TButton)
// ControlCaption: The text/caption of the control (eg: Ok)

Procedure Button2Click(Sender: TObject);
Begin
  ClickButton('TForm1', 'Form1', 'TSpeedbutton', nil);
End;

Open in new window

0
Emmanuel PASQUIERFreelance Project ManagerCommented:
you cannot click on a button that has no window handle by this method.

Your only solution is to simulate a mouse click on the form, knowing the coordinate of the button

Also, I don't see the need to set your handles to 0 once used.

Procedure ClickSomewhere(WindowName, WindowCaption: PChar; X,Y:Integer);
Var
  hParent : HWND;
Begin
 hParent := FindWindow(WindowName, WindowCaption);
 if hParent<>0 Then
  Begin
   BringWindowToTop(hParent);
   Application.ProcessMessages; // not sure that is useful
   SendMessage(hParent, BM_CLICK, X,Y);
  End;
End;

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
DeonMAuthor Commented:
Hi ThievingSix,

Thanks for the reply.
Tried your solution, didn't work I'm afraid. :(

Kind Regards
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

Emmanuel PASQUIERFreelance Project ManagerCommented:
for this part :
> However when I send "ControlCaption" as an empty string, it doesn't work
> I understand why but not how to get around it.

you must use ControlCaption = NULL (nil) for a match to all window names
Procedure ClickButton(WindowName, WindowCaption, ControlName, ControlCaption: PChar);
Var
  hParent, hControl : HWND;
Begin
 hParent := FindWindow(WindowName, WindowCaption);
 if hParent<>0 Then 
  Begin
   BringWindowToTop(hParent);
   Application.ProcessMessages;
// little fix :
   if ControlCaption='' Then ControlCaption:=Nil;
   hControl := FindWindowEx(hParent, 0, ControlName,ControlCaption);
   if hControl<>0 Then SendMessage(hControl, BM_CLICK, 0,0);
  End;
End;

Open in new window

0
Emmanuel PASQUIERFreelance Project ManagerCommented:
oups, I didn't see that Thieving Six was pointing to this very same fix.

But you said it doesn't work ?

for SpeedButon, no, but it should work for handled buttons without knowing the name (there might be more than one...)
0
DeonMAuthor Commented:
Hi, Epasquier

Thank you for your reply.

While the code you suggested didn't work initially, with a little tweaking I managed to get it too work. While this isn't ideal, at least I know it will work for the time being.

Thank you!

Kind Regards.
Procedure TForm1.ClickSomewhere(WindowName, WindowCaption: PChar);
Var
  hParent           : HWND;
  Pos, oldPos       : TPoint;
  rect              : TRect;
Begin
  hParent := FindWindow(WindowName, WindowCaption);

  If hParent <> 0 Then
  Begin
    BringWindowToTop(hParent);

    GetWindowRect(hParent, rect);

    oldPos.X := Mouse.CursorPos.X;
    oldPos.Y := Mouse.CursorPos.Y;

    Pos.X := Rect.Left - 400;
    Pos.Y := Rect.Top - 158;
    Mouse.CursorPos := ClientToScreen(Pos);

    mouse_event(MOUSEEVENTF_LEFTDOWN, 0,0,0,0);
    mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);

    Mouse.CursorPos := oldPos;

  End;
End;

Open in new window

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.