Simulate a perfect click effect

Hello !


Well, I was wondering if we could simulate a click effect without putting the target window at the foreground.

Acutually, when I use this following win API,

1
2
3
4
LPARAM lParam = jeton.x | (jeton.y << 16);

SendMessage(ctrl_handle, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
SendMessage(ctrl_handle, WM_LBUTTONUP, 0, lParam);


I first have to SetForegroundWindow(win_handle); and I' like to not have to, in order to not be disturbed at all.

I'm quite sure there exist alternative methods, and some of them may do what I'm looking for.


Could you introduce me one of them ? Thanks in advance.
If you are trying to automate a user interface element, such as a dialog box or similar, your best shot is UI Automation. Google it up.
Thanks for your answer, but unfortunately that's not what I'm looking for.


I'd like to have a little program able to perform a left click anywhere inside of a defined maximized window avaible, without taking control, even a few seconds, over the user's cursor, and without setting the target window at the foreground. That's why I talk about a "click effect".

And I want it to work with all the windows possible.

So, it is launched with the following command-line : click_simulation.exe "Title of the target window", "the absolute coord.x of the click", "absolute coord.y".

The problem is that depending of the target window, my program works very good, a little or not at all, and I, I'd like to have some generic solution that always works, that can make an invisible click inside of each and every kind of window, as long as its title is input in the command-line.

This is my code, could you give me a piece of advice to improve it ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <windows.h>
#include <windef.h>

using namespace std;

/* The program must be launched with the following command-line :
----------------------------------------------------------------------------------------------------------------
click_simulation.exe "Target window title" "coord.x relative to the desktop" "coord.y relative to the desktop"
----------------------------------------------------------------------------------------------------------------
*/

int main(int argc, char* argv[])
{
    // Recuperating the command-line params
    char* win_title = argv[1];
    POINT win_coords = {atoi(argv[2]), atoi(argv[3])};
    POINT ctrl_coords = win_coords;

    // Getting the target window handle, from its name
    HWND win_handle = FindWindow(NULL, win_title);

    // Setting coords relative to the target window
    ScreenToClient(win_handle, &win_coords);

    // Getting the handle of the control to click, from the target window handle and the coordinates relative to it
    HWND ctrl_handle = ChildWindowFromPoint(win_handle, win_coords);

    // Setting the final click coords, relative to the target control
    ScreenToClient(ctrl_handle, &ctrl_coords);

    // Clicking using Win32 APIs, with the control handle and the coordinates relative to it as params
    LPARAM lParam = MAKELPARAM(ctrl_coords.x, ctrl_coords.y);
    SendMessage(ctrl_handle, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
    SendMessage(ctrl_handle, WM_LBUTTONUP, 0, lParam);

    return 0;
}


I use default Code::Blocks as IDE and I've got a 64-bit version of Windows7, no Service Pack. If ever these infos had a link with my problem...


Thanks a lot !
Last edited on
So you want to simulate a left mouse click on a control even if the control is not the active window? What about overlapping windows? Instead of the mechanism please describe the desired result?
The first parameter of the command line, "Target window title", solves the overlapping windows problem. In fact, giving a window name narrows the number of possibilities to one, as each window generally have a different name from the others also avaible for clicking at the same position.

Well, the result of calling my application with the appropriate parameters is the simulation of a left click effect inside of the target window at the mentionned absolute coordinates without taking control over the user's mouse nor setting the window of the clicked control at the foreground.

As you can imagine, this little program will be called by another application, my main software written in AutoIt.

Thanks in advance !
Last edited on
I think your problem relies in the fact that you think ChildWindowFromPoint() works recursively working out the child of the child of the child, etc. etc. It doesn't. If you find the first child, that doesn't necessarily mean that it is that child the one that is going to receive the click (if done with the mouse by a human). You have to continue calling ChildWindowFromPoint() recursively or iteratively until no other child is found. Then you use that control handle.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Have a POINT variable that holds the unmodified absolute screen coords:
POINT screen_coords = {atoi(argv[2]), atoi(argv[3])};
...
//Now use win_coords in the iteration:

HWND curParent;
HWND ctrl_handle = win_handle;
do
{
    curParent = ctrl_handle;
    win_coords = screen_coords;
    ScreenToClient(curParent, &win_coords);
    ctrl_handle = ChildWindowFromPoint(curParent, win_coords);
} while (ctrl_handle != NULL);
//Now you have the ultimate child in curParent and the coords in win_coords.
ScreenToClient(curParent, &win_coords);
...
//The rest here. 


I cannot be sure this is your problem, but I guess it is worth a shot.

Thank you webJose, your idea improved my code !
Some windows I couldn't click before are now all right !



But I still have a probrem.


In some windows, to perform a click, I have to copy several times in my source code this formula :

1
2
SendMessage(handle, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
SendMessage(handle, WM_LBUTTONUP, 0, lParam);

... Despite the fact that only one click is normally required to activate the control !


Finally, that's what I may have in order to perform a single click, an arbitrary number of SendMessage :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
LPARAM lParam = MAKELPARAM(click_coords.x, click_coords.y);

SendMessage(handle, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
SendMessage(handle, WM_LBUTTONUP, 0, lParam);

SendMessage(handle, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
SendMessage(handle, WM_LBUTTONUP, 0, lParam);

SendMessage(handle, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
SendMessage(handle, WM_LBUTTONUP, 0, lParam);

SendMessage(handle, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
SendMessage(handle, WM_LBUTTONUP, 0, lParam);

SendMessage(handle, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
SendMessage(handle, WM_LBUTTONUP, 0, lParam);


So, how can I be understood at the first time by these windows ?
Last edited on
Give information about those windows.
Flash windows, using activeX.
Hello !

That's OK, I finally managed to solve that problem by myself.

Now, I'm wondering if it is possible to set and keep the target window hidden (something like SW_HIDE) as while as we are sending it some efficient click messages.

Thanks in advance !
Up please ^^

Merci !
I supposed that you tried ShowWindow(hWnd, SW_HIDE) already? If it didn't work, then I don't see a way of hiding that will work. I only know about ShowWindow(). I don't know about other techniques to hide a window.
Thanks for all webJose, you solved my problem !
Topic archived. No new replies allowed.