You can use SendMessage
or mouse_event
or SendInput
to perform a mouse operation. Here I will share some details and examples about the first two.
Using SendMessage
SendMessage
performs the mouse action without needing to move the cursor.
SendMessage
needs handle of the window to send message.
SendMessage
sends the mouse message to a relative position inside the window. The coordinate should be relative to the upper-left corner of the client area of the window.
- If you know which point in the client coordinate, you want to send click, then just use the client coordinates. It's usually the case.
- If you have a screen position and you want to translate it to client relative position, you can use
ScreenToClient
. But since you usually know the relative position you are going to click, you usually don't need ScreenToClient
.
To pass parameters to MakeLParam
the low-order word specifies the x-coordinate and high-order word specifies the y-coordinate of the cursor. To make it less confusing, use the following function:
IntPtr MakeLParam(int x, int y) => (IntPtr)((y << 16) | (x & 0xFFFF));
And as a side-note, if you want to the send the message to a window and return without waiting for the thread to process the message, you can use PostMessage
.
Using mouse_event
mouse_event
Performs the mouse action on the current cursor position.
- Before calling
mouse_event
you need to move the cursor to the location on screen which you are going to perform click.
- To get screen position of a client point of a window, you can use
ClientToScreen
method.
- To move the cursor you can set
Cursor.Position
to a screen position.
- It's recommended to use
SendInput
function instead.
Example 1 - SendMessage
Using SendMessage
you can click on the specified relative position of a specified window. In the following example, I've found the edit
control inside notepad
main window, then I've performed a right click on (20,20)
coordinate inside the client rectangle of the edit control:
//using System;
//using System.Diagnostics;
//using System.Drawing;
//using System.Linq;
//using System.Runtime.InteropServices;
//using System.Windows.Forms;
const int WM_RBUTTONDOWN = 0x0204;
const int WM_RBUTTONUP = 0x0205;
const int WM_MOUSEMOVE = 0x0200;
[DllImport("User32.DLL")]
static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
IntPtr MakeLParam(int x, int y) => (IntPtr)((y << 16) | (x & 0xFFFF));
[DllImport("user32.dll")]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,
string lpszClass, string lpszWindow);
void PerformRightClick(IntPtr hwnd, Point point)
{
var pointPtr = MakeLParam(point.X, point.Y);
SendMessage(hwnd, WM_MOUSEMOVE, IntPtr.Zero, pointPtr);
SendMessage(hwnd, WM_RBUTTONDOWN, IntPtr.Zero, pointPtr);
SendMessage(hwnd, WM_RBUTTONUP, IntPtr.Zero, pointPtr);
}
void button1_Click(object sender, EventArgs e)
{
var notepad = Process.GetProcessesByName("notepad").FirstOrDefault();
if (notepad != null)
{
var edit = FindWindowEx(notepad.MainWindowHandle, IntPtr.Zero, "Edit", null);
PerformRightClick(edit, new Point(20, 20));
}
}
Example 2 - mouse_event
Using mouse_event
you can click on the current mouse position. It means you need to move the mouse to the desired location. In the following example, I've found the edit
control inside notepad
main window, then I've performed a right click on (20,20)
coordinate inside the client rectangle of the edit control:
//using System;
//using System.Diagnostics;
//using System.Drawing;
//using System.Linq;
//using System.Runtime.InteropServices;
//using System.Windows.Forms;
const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
const int MOUSEEVENTF_RIGHTUP = 0x0010;
[DllImport("user32.dll")]
static extern void mouse_event(uint dwFlags, uint dx, uint dy,
uint cButtons, uint dwExtraInfo);
[DllImport("user32.dll")]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,
string lpszClass, string lpszWindow);
[StructLayout(LayoutKind.Sequential)]
struct POINT { public int X; public int Y; }
[DllImport("user32.dll")]
static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint);
void PerformRightClick(IntPtr hwnd, Point p)
{
POINT point = new POINT() { X = p.X, Y = p.Y };
ClientToScreen(hwnd, ref point);
Cursor.Position = new Point(point.X, point.Y);
uint X = (uint)Cursor.Position.X;
uint Y = (uint)Cursor.Position.Y;
mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, X, Y, 0, 0);
}
void button1_Click(object sender, EventArgs e)
{
var notepad = Process.GetProcessesByName("notepad").FirstOrDefault();
if (notepad != null)
{
var edit = FindWindowEx(notepad.MainWindowHandle, IntPtr.Zero, "Edit", null);
PerformRightClick(edit, new Point(20, 20));
}
}