Simulate mouse click using SendInput

We have learned how to simulate a mouse click using the SendMessage function. In fact, there are quite a few methods you can use to simulate mouse events. SendInput is one of them. The differences between SendInput and SendMessage in simulating mouse events are:1) SendInput actually moves the mouse pointer while SendMessage does not; 2) SendInput is at a lower level than SendMessage. SendInput does not have an HWND parameter as SendMessage, which means it delivers the events in the application’s(not a window’s) message queue.  The SendInput function is a little hard to use. If you used SendMessage before but this is the fist time you use SendInput, you probably write the following codes in order to simulate a mouse click:

INPUT    Input={0};

::ZeroMemory(&Input,sizeof(INPUT));
Input.type      = INPUT_MOUSE;
Input.mi.dwFlags  = MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_ABSOLUTE;
Input.mi.dx=x;
Input.mi.dy=y;
::SendInput(1,&Input,sizeof(INPUT));

::ZeroMemory(&Input,sizeof(INPUT));
Input.type      = INPUT_MOUSE;
Input.mi.dwFlags  = MOUSEEVENTF_LEFTUP|MOUSEEVENTF_ABSOLUTE;
Input.mi.dx=x;
Input.mi.dy=y;
::SendInput(1,&Input,sizeof(INPUT));

 

You think Input.mi.dx and Input.mi.dy indicate the click point as one of the SendMessage parameters. However, this is not true. If  dwFlags is MOUSEEVENTF_LEFTUP or MOUSEEVENTF_LEFTDOWN, the Input.mi has no meanings and is ignored. SendInput will click at the current mouse cursor. The correct way to simulate the click is moving the mouse to the specified position then sending the click event, as follows:

INPUT    Input={0};

double fScreenWidth = ::GetSystemMetrics(SM_CXSCREEN) - 1;
double fScreenHeight = ::GetSystemMetrics(SM_CYSCREEN) - 1;
double fx = x*(65535.0f / fScreenWidth);
double fy = y*(65535.0f / fScreenHeight);
INPUT  Input = { 0 };
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
Input.mi.dx = fx;
Input.mi.dy = fy;
SendInput(1, &Input, sizeof(INPUT));

::ZeroMemory(&Input,sizeof(INPUT));
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));

 

Note that x,y are screen coordinates, not client coordinates.

Comments are closed, but trackbacks and pingbacks are open.