C# 发送右键单击到窗口

C# 发送右键单击到窗口,c#,.net,winforms,sendmessage,right-click,C#,.net,Winforms,Sendmessage,Right Click,我正在尝试将鼠标右键单击发送到指定坐标的窗口 我用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);

我正在尝试将鼠标右键单击发送到指定坐标的窗口

我用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);
对于这一点:

int lparm = (point.x << 16) + point.y;
intlparm=(point.x您可以使用或来执行鼠标操作。这里我将分享前两个的一些细节和示例

使用SendMessage

  • SendMessage
    执行鼠标操作而无需移动光标
  • SendMessage
    需要窗口句柄才能发送消息
  • SendMessage
    将鼠标消息发送到窗口内的相对位置。坐标应相对于窗口客户区的左上角
  • 如果您知道客户端坐标中的哪一点,您希望发送单击,那么只需使用客户端坐标。通常情况下就是这样
  • 如果您有一个屏幕位置,并且希望将其转换为客户端相对位置,则可以使用
    ScreenToClient
    。但由于您通常知道要单击的相对位置,因此通常不需要
  • 要将参数传递给低阶字,请指定光标的x坐标,高阶字指定光标的y坐标。要减少混淆,请使用以下函数:

    IntPtr MakeLParam(int x, int y) => (IntPtr)((y << 16) | (x & 0xFFFF));
    
    示例2-鼠标事件 使用
    mouse\u event
    可以单击当前鼠标位置。这意味着您需要将鼠标移动到所需位置。在下面的示例中,我在
    记事本
    主窗口中找到了
    编辑
    控件,然后右键单击
    (20,20)
    编辑控件的客户端矩形内的坐标:

    //using System;
    //using System.Diagnostics;
    //using System.Drawing;
    //using System.Linq;
    //using System.Runtime.InteropServices;
    //using System.Windows.Forms;
    
    //using System;
    //using System.Diagnostics;
    //using System.Drawing;
    //using System.Linq;
    //using System.Runtime.InteropServices;
    //using System.Windows.Forms;
    

    您是否测试/检查了ScreenToClient()返回给point结构的坐标(通过ref)?正如@VillageTech所回避的,使用的坐标是相对于您正在寻址的客户端窗口,而不是整个桌面。在WM_RBUTTONDOWN(/UP)的文档中,它说“坐标是相对于客户端区域的左上角。”如您所见,我正在将桌面坐标“转换”为客户端坐标..屏幕到客户端(whandle,参考点);但无论如何,如果是这种情况,它不能解释为什么在我移动鼠标时右键单击区域会发生变化,它忽略了我的协调VillageTech所指的是,你永远不会检查
    ScreenToClient
    返回的bool,以查看呼叫是成功还是失败。使用
    鼠标事件
    你分配了赏金,谢谢。但是dn未接受/投票该答案。该答案似乎有问题?如果我能帮助您,请告诉我:)
    //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));
        }
    }
    
    //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));
        }
    }