mouse emulation using keyboard

My mouse is broken and until I get a new one I decided to write something to do my job using the keyboard. I am able to move the mouse using the arrow keys and I can get a handle to the target window but I seem to have a problem posting a mouse click message to the target window's message queue... Neither SendMessage nor PostMessage seem to work... I checked the documentation at msdn and I don't think I'm setting the params wrong... Does anyone know what might be the problem?

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <windows.h>
#include <iostream>
using namespace std;

bool IsPressed(int vk)
{
    return GetAsyncKeyState(vk)>>15;
}

void MoveMouse(int dx, int dy)
{
    POINT p;

    GetCursorPos(&p);

    p.x+=dx;
    p.y+=dy;

    SetCursorPos(p.x,p.y);
}

void LeftClick()
{
    HWND window;
    RECT rect;

    window=GetForegroundWindow();
    GetWindowRect(window,&rect);

    char str[200];
    GetWindowText(window,str,200);
    cout << str << endl;

    POINT p;

    GetCursorPos(&p);

    p.x-=rect.left;
    p.y-=rect.top;

    WPARAM wp=0;
    LPARAM lp=p.x|(p.y<<16);

    cout << PostMessage(window,WM_LBUTTONDOWN,0,lp) << endl;
    cout << PostMessage(window,WM_LBUTTONUP,0,lp) << endl;
}

int main()
{
    bool control;
    bool shift;
    int amount;

    while (true)
    {
        if (IsPressed(VK_ESCAPE)) break;

        control=false;
        shift=false;
        amount=10;

        if (IsPressed(VK_CONTROL)) control=true;
        if (IsPressed(VK_SHIFT)) shift=true;

        if (control) amount=100;
        if (shift) amount=1;

        if (IsPressed(VK_UP)) MoveMouse(0,-amount);
        if (IsPressed(VK_DOWN)) MoveMouse(0,amount);
        if (IsPressed(VK_LEFT)) MoveMouse(-amount,0);
        if (IsPressed(VK_RIGHT)) MoveMouse(amount,0);

        if (IsPressed(VK_SPACE)) LeftClick();

        Sleep(100);
    }

    return 0;
}

EDIT: Hmmm... I wonder if I have to send the message to the specific control (button, textbox etc...) under the mouse... I guess I'll try to EnumChildWindows for the target window and use SendMessage/PostMessage on the ones that contain the mouse cursor (I can check that with GetWindowRect and GetCursorPos). Meanwhile, if anyone has a better idea I'd like to know it.
Last edited on
closed account (z05DSL3A)
How about something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
void LeftClick()
{  
    INPUT    Input={0};	

    Input.type        = INPUT_MOUSE;	
    Input.mi.dwFlags  = MOUSEEVENTF_LEFTDOWN;
    SendInput( 1, &Input, sizeof(INPUT) )

    ZeroMemory(&Input,sizeof(INPUT));
    Input.type        = INPUT_MOUSE;
    Input.mi.dwFlags  = MOUSEEVENTF_LEFTUP;	
    SendInput( 1, &Input, sizeof(INPUT) );
}

NB: Untested code
Last edited on
Excellent! I did manage to (kind of) make it work with clicks on the child windows but this is cleaner.

Note: I had to #define _WIN32_WINNT 0x0500 in order to get it to compile.
Topic archived. No new replies allowed.