Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send right click to a window

I'm trying to send a right mouse click to a window specified coordinates.

I've tested with 2 codes

Code 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);

Code 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);

It's sending a right click but not to the correct coordinates, seems like it ignores the coordinates I specify in LPARAM, because if I move the mouse around the window, it's clicking everywhere I put the mouse pointer but not in the coordinates that I specify.

I've tested changing this line in code 2:

int lparm = MakeLParam(point.x, point.y);

To this one:

int lparm = (point.x << 16) + point.y;

But doesn't work, I'm getting the same results...

like image 508
kuhi Avatar asked Dec 06 '25 05:12

kuhi


1 Answers

You can use SendMessage or mouse_event or SendInputto 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));
    }
}
like image 86
Reza Aghaei Avatar answered Dec 08 '25 18:12

Reza Aghaei



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!