1

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?

OscarRyz
  • 196,001
  • 113
  • 385
  • 569
VbN
  • 36
  • 1
  • 7
  • Some more information here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645606(v=vs.85).aspx – mellamokb May 18 '12 at 22:18
  • 2
    This sounds like a problem to which there is a better solution than the one you have started upon... why do you want to do this? – J... May 18 '12 at 22:21

5 Answers5

3

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.

mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • If you did this "just recently", why did you use the obsolete [`mouse_event` function](http://msdn.microsoft.com/en-us/library/windows/desktop/ms646260.aspx) instead of the recommended [`SendInput` function](http://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx)? – Cody Gray - on strike May 19 '12 at 00:57
  • 1
    @CodyGray: I couldn't get SendInput to work. This OTOH worked perfectly. If you have a C# example using SendInput to send mouse clicks in screen coordinates in pixels... I'd like to see it. – mpen May 19 '12 at 23:27
0

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

Chad
  • 422
  • 1
  • 3
  • 17
0

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.

Dave
  • 14,618
  • 13
  • 91
  • 145
  • Okey. I feel that I have to clarify this a bit. I What I want is not multiple mouse click on the same IntPtr intptr. What I want is to have multiple click event to different IntPtr intptr. Without interfering with each other. My first try on this was to move the mouse pointer and preform a click. This works well when you only have one process that preforms this. When multiple threads tries to click on different locations it fails. – VbN May 18 '12 at 22:55
0

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.

Community
  • 1
  • 1
igofed
  • 1,402
  • 1
  • 9
  • 15
0

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));
        }
    }
Rad
  • 1