您可以使用SendMessage
或mouse_event
或SendInput
来执行鼠标操作。这里我将分享关于前两者的一些细节和示例。
使用 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
.
使用mouse_event
mouse_event
在当前光标位置执行鼠标操作。
- 在调用
mouse_event
之前,您需要将光标移动到屏幕上要单击的位置。
- 要获取窗口客户端点的屏幕位置,可以使用
ClientToScreen
方法。
- 要移动光标,可以将
Cursor.Position
设置为屏幕位置。
- 建议使用
SendInput
函数。
示例1 - SendMessage
使用SendMessage
,您可以单击指定窗口的指定相对位置。 在下面的示例中,我找到了notepad
主窗口内部的edit
控件,然后在客户端矩形内的坐标(20,20)
处执行右键单击:
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));
}
}
示例2 - mouse_event
使用mouse_event
可以在当前鼠标位置点击。这意味着您需要将鼠标移动到所需位置。在下面的示例中,我已经找到了notepad
主窗口内的edit
控件,然后在编辑控件的客户区矩形内的(20,20)
坐标处执行了右键单击操作:
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));
}
}
mouse_event
。 - Reza AghaeiSendMessage
,请将窗口屏幕位置转换为其相对位置。 - Reza Aghaei