简体   繁体   中英

Virtual mouse click c#

I have an multithreaded application that needs to be able to preform multiple mouse click at the same time.

I have an IntPtr intptr to a process on which i need to send a mouse click to. I have tried to find this information on the web and there are some examples which i have tried. But I have not got any of them to work.

As I understand the correct way to solv my issue is to use the function SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

hWnd is the IntPtr to the process. Msg is the wanted action, which I want a left click, int WM_LBUTTONDBLCLK = 0x0203; IntPtr wParam is of no intrest to this problem ( as I understand) And the coordinates to the click is in lParam. I construct lParam like,

Int32 word = MakeLParam(x, y);

private int MakeLParam(int LoWord, int HiWord)
     {
         return ((HiWord << 16) | (LoWord & 0xffff));
     }

But as you might understand, I cant get this to work. My first question is, the coordinates are they within the window of this process or are the absolut screen coordinates? And my second question, what am I doing wrong?

I was trying to simulate mouse clicks in C# just recently, I wrote this little helper class to do the trick:

public static class SimInput
{
    [DllImport("user32.dll")]
    static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, UIntPtr dwExtraInfo);

    [Flags]
    public enum MouseEventFlags : uint
    {
        Move = 0x0001,
        LeftDown = 0x0002,
        LeftUp = 0x0004,
        RightDown = 0x0008,
        RightUp = 0x0010,
        MiddleDown = 0x0020,
        MiddleUp = 0x0040,
        Absolute = 0x8000
    }

    public static void MouseEvent(MouseEventFlags e, uint x, uint y)
    {
        mouse_event((uint)e, x, y, 0, UIntPtr.Zero);
    }

    public static void LeftClick(Point p)
    {
        LeftClick((double)p.X, (double)p.Y);
    }

    public static void LeftClick(double x, double y)
    {
        var scr = Screen.PrimaryScreen.Bounds;
        MouseEvent(MouseEventFlags.LeftDown | MouseEventFlags.LeftUp | MouseEventFlags.Move | MouseEventFlags.Absolute,
            (uint)Math.Round(x / scr.Width * 65535),
            (uint)Math.Round(y / scr.Height * 65535));
    }

    public static void LeftClick(int x, int y)
    {
        LeftClick((double)x, (double)y);
    }
}

The coordinates are a fraction of 65535, which is a bit odd, but this class will handle that for you.

I'm not 100% sure I understand what you're trying to accomplish. But if you want to simulate mouse input then I'd recommend using the SendInput API.

You can provide an array of inputs to be inserted into the input stream.

See also: PInvoke reference

I don't understand why anyone would want to send multiple mouse clicks simultaneously. If it's to test your GUI, it's the wrong test. No one can physically click something multiple times in the same time space.

But going back to your question, using SendMessage won't help you, because it is basically a blocking call. Even if you tried to use PostMessage, you won't be able to accomplish simultaneous clicks, because the message queue is getting pumped from the UI thread and has messages popped off and handled sequentially.

I used this code to click left button in handle

public static void MouseLeftClick(Point p, int handle = 0)
{
    //build coordinates
    int coordinates = p.X | (p.Y << 16);
    //send left button down
    SendMessage(handle, 0x201, 0x1, coordinates);
    //send left button up
    SendMessage(handle, 0x202, 0x1, coordinates);
}

If you set no handle with calling - then it sends click to Desktop, so coordinates should be for whole screen, if you will set handle, then message will be sent to handle's window and you should set coordinates for window.

How about just using VirtualMouse? I use it in C# and it works great.

    public partial class Form1 : Form
    {
        private VirtualMouse vm = new VirtualMouse();
        public Form1()
        {
            InitializeComponent();
        }
        private void MouseClickHere(Point myPoint)
        {
            vm.ClickIt(myPoint, 150);
        }
        private void Clicker()
        {
             MouseClickHere(new Point(250,350));
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM