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));
It is possible to simulate without SetCursorPos? Please help
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
hi
Did you try with the SendMessage, please try, and be sure you find the right handle of the background application.
Did you try with the SendMessage, please try, and be sure you find the right handle of the background application.
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.
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:
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;
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.
2. After pressing the button, some programs require that you release it. Send WM_LBUTTONUP after WM_LBUTTONDOWN.
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/EnumChildWindo ws 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.
1. Control coordinates vs. screen coordinates. You will have to get the coordinates using EnumWindows/EnumChildWindo
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.
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).
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
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
ASKER