kuh*_*uhi 3 .net c# right-click sendmessage winforms
我正在尝试将鼠标右键单击发送到窗口指定的坐标。
我用2个代码测试过
代码1:
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("user32.dll")]
static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
public struct POINT
{
public int x;
public int y;
}
var client = Process.GetProcessesByName("client_dx");
var whandle = client.MainWindowHandle;
POINT point = new POINT();
point.x = 1836;
point.y = 325;
ScreenToClient(whandle, ref point);
int lparm = (point.x << 16) + point.y;
int lngResult = SendMessage(whandle, 0x0204, 0, lparm);
int lngResult2 = SendMessage(whandle, 0x0205, 0, lparm);
Run Code Online (Sandbox Code Playgroud)
代码2:
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("user32.dll")]
static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
public struct POINT
{
public int x;
public int y;
}
public int MakeLParam(int LoWord, int HiWord)
{
return (int)((HiWord << 16) | (LoWord & 0xFFFF));
}
var client = Process.GetProcessesByName("client_dx");
var whandle = client.MainWindowHandle;
POINT point = new POINT();
point.x = 1836;
point.y = 325;
ScreenToClient(whandle, ref point);
int lparm = MakeLParam(point.x, point.y);
int lngResult = SendMessage(whandle, 0x0204, 0, lparm);
int lngResult2 = SendMessage(whandle, 0x0205, 0, lparm);
Run Code Online (Sandbox Code Playgroud)
它发送右键单击,但没有发送到正确的坐标,似乎它忽略了我在 LPARAM 中指定的坐标,因为如果我在窗口周围移动鼠标,它会单击我放置鼠标指针的任何位置,但不会单击我指定的坐标。
我已经测试过在代码 2 中更改这一行:
int lparm = MakeLParam(point.x, point.y);
Run Code Online (Sandbox Code Playgroud)
对于这个:
int lparm = (point.x << 16) + point.y;
Run Code Online (Sandbox Code Playgroud)
但不起作用,我得到了相同的结果......
您可以使用SendMessage或mouse_event或SendInput来执行鼠标操作。在这里我将分享有关前两者的一些细节和示例。
使用发送消息
SendMessage无需移动光标即可执行鼠标操作。SendMessage需要窗口句柄来发送消息。SendMessage将鼠标消息发送到窗口内的相对位置。该坐标应相对于窗口客户区的左上角。ScreenToClient。但由于您通常知道要单击的相对位置,因此通常不需要ScreenToClient.将参数传递给MakeLParam低位字指定光标的 x 坐标,高位字指定光标的 y 坐标。为了减少混乱,请使用以下函数:
IntPtr MakeLParam(int x, int y) => (IntPtr)((y << 16) | (x & 0xFFFF));
Run Code Online (Sandbox Code Playgroud)作为旁注,如果您希望将消息发送到窗口并返回而不等待线程处理消息,您可以使用PostMessage.
使用鼠标事件
mouse_event在当前光标位置执行鼠标操作。mouse_event您需要将光标移动到屏幕上要执行单击的位置。ClientToScreen方法。Cursor.Position为屏幕位置。SendInput函数代替。使用SendMessage您可以单击指定窗口的指定相对位置。在下面的示例中,我在主窗口edit内找到了该控件notepad,然后右键单击(20,20)编辑控件的客户端矩形内的坐标:
//using System;
//using System.Diagnostics;
//using System.Drawing;
//using System.Linq;
//using System.Runtime.InteropServices;
//using System.Windows.Forms;
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
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));
}
}
Run Code Online (Sandbox Code Playgroud)
使用mouse_event您可以单击当前鼠标位置。这意味着您需要将鼠标移动到所需的位置。在下面的示例中,我在主窗口edit内找到了该控件notepad,然后右键单击(20,20)编辑控件的客户端矩形内的坐标:
//using System;
//using System.Diagnostics;
//using System.Drawing;
//using System.Linq;
//using System.Runtime.InteropServices;
//using System.Windows.Forms;
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
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));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3355 次 |
| 最近记录: |