Link to home
Start Free TrialLog in
Avatar of l3m0n
l3m0n

asked on

[Delphi] Mouse click simulation with PostMessage or something similar

Hi i need to simulate mouse click on window that is not a foreground window. (before i was doing it with SetCursorPos and postmessage like this:
PostMessageA(Handle1, WM_LBUTTONDOWN, MK_LBUTTON, MakeLParam(X, Y));

Open in new window

It is possible to simulate without SetCursorPos? Please help
ASKER CERTIFIED SOLUTION
Avatar of systan
systan
Flag of Philippines image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of l3m0n
l3m0n

ASKER

It is not working. It only simulate click in current mouse position.
hi
Did you try with the SendMessage, please try, and be sure you find the right handle of the background application.
Avatar of Ephraim Wangoya

How do you expect it to click on different coordinates when you don't set them. Manual clicks are also just messages posted to windows.

When you send a message to click the mouse, it happens on the current position of the mouse unless you change it.

Otherwise clicks would just occur randomly any where on the screen.
Avatar of l3m0n

ASKER

Then it is possible to simulate mouse click on background window?

Just post a mouse down message to the handle of that window
You said it yourself "Mouse Click", so it should click where the cursor is pointing at, and hence you tell where the cursor should be before clicking.
Unless you need to do a specific action, click a button for instance, you do not have to pass coordinates. Check this link from Torry's:
function EnumChildProc(Wnd: hWnd; SL: TStrings): BOOL; stdcall;
var
  szFull: array[0..MAX_PATH] of Char; //Buffer for window caption
begin
  Result := Wnd <> 0;
  if Result then 
  begin
    GetWindowText(Wnd, szFull, SizeOf(szFull)); // put window text in buffer
    if (Pos(SL[0], StrPas(szFull)) > 0) // Test for text
      and (SL.IndexOfObject(TObject(Wnd)) < 0) // Test for duplicate handles
      then SL.AddObject(StrPas(szFull), TObject(Wnd)); // Add item to list
    EnumChildWindows(Wnd, @EnumChildProc, Longint(SL)); //Recurse into child windows
  end;
end;

function ClickButton(ParentWindow: Hwnd; ButtonCaption: string): Boolean;
var
  SL: TStringList;
  H:  hWnd;
begin
  SL := TStringList.Create;
  try
    SL.AddObject(ButtonCaption, nil); // First item in list is text to find
    EnumChildWindows(ParentWindow, @EnumChildProc, Longint(SL));
    H := 0;
    case SL.Count of
      1: ShowMessage('Window text not found.');
      2: H := hWnd(SL.Objects[1]);
      else 
        ShowMessage('Ambiguous text detected.');
    end;
  finally
    SL.Free;
  end;
  Result := H <> 0;
  if Result then PostMessage(H, BM_CLICK, 0, 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ClickButton(FindWindow(nil,'Form1'), 'Button1');
end;

Open in new window

1. Are you sure you want to click on a window, not a concrete control on it? (Of course, all controls are windows as long as they have window handles. Just to be sure.)
2. After pressing the button, some programs require that you release it. Send WM_LBUTTONUP after WM_LBUTTONDOWN.
Avatar of l3m0n

ASKER

It is working with delphi application. If i try to use it on windows calculator it is not working. I need to use it on another application what is not wroted in delphi.
To make it "click" on a particular button on a program that is not Delphi, you may have a problem for several reasons.
1. Control coordinates vs. screen coordinates. You will have to get the coordinates using EnumWindows/EnumChildWindows in order to get the control you want to click, this gives you client coordinates. You will have to convert them to screen coords using the ClientToScreen function.
2. What type of control. Different controls handle clicking differently. buttons take BM_CLICK, Combo/ListBoxes take a completely different message.
the WM_LBUTTONxxx messages won't usually work on controls.
3. There may be some cross-boundary issues with access to the controls in Vista or Windows7. I seem to recall that beginning with XP, there were problems getting access to different things in programs that weren't running in your memory space and you had to "inject" your app into theirs.
Avatar of l3m0n

ASKER

i dont get anything. Because i get this message: "Window text not found." Application cant find button in windows calc with caption is "1" or "CE" or "9"? i dont understand. What is with d3d applications?
So the problem is not clicking, but finding the window.
Are you using FindWindowEx to find a child window within main calc window? Post the code.
Also try to explore calc with WinSight (which is bundled with Delphi).
hi
I think he's making an application for a game clicker(in background), the calculator is just a test?
try this in c#,
https://www.experts-exchange.com/questions/21298311/How-to-perform-mouse-click-outside-the-application.html

good luck