4
votes

What I need

Simulate messages (mouse mainly, but keyboard too) without moving the cursor. The message goes to the focused window (at first, I want for minimized windows, but I didn't find how to do it, so I use SetForegroundWindowto focus it).

What I've found

On this question, I've figured out I need to use pInvoked from user32.dll. Also I found a small code sample, but it didn't work.

I also found this similar question. The guy uses mouse_event, but it is deprecated. This function takes the X and Y cordinates in mickeys. I tried to convert my coordinates (using SendMessage), but I failed.

Icanhaz an example?

Sure. The notepad.exe is opened and I need to peform a right click on a button located at (1210, 460).

What I've tried

Based on the sample that I've found here, I did this code:

IntPtr hWnd = (IntPtr)FindWindow("notepad.exe", null);
SetForegroundWindow(hWnd);

var screenPoint = this.PointToScreen(new Point(1210, 460));
var handle = WindowFromPoint(screenPoint);

if (handle != IntPtr.Zero)
{
    //Right Button Down
    SendMessage(handle, 0x0204, IntPtr.Zero, IntPtr.Zero);
    //Right Button Up
    SendMessage(handle, 0x0205, IntPtr.Zero, IntPtr.Zero);
}

I also tried using my previous handle hWnd in SendMessage, but didn't work as well. The whole code you can find here.

Thank you in advance.

3
But it does move the cursor. I tried this answer stackoverflow.com/a/8022534/1488993, it works, but moves the cursorDoon
Even using UIAutomation moves the cursor...user7116

3 Answers

4
votes

If I corectly understand, you want to inject a click event inside an application without having to move the mouse, like a game bot, so the user don't see sumthing is using his mouse and keyboard...

If im right, then look at the reply at this link, it may be what you want...

its in c++ but well not a big matter I guess...

http://social.msdn.microsoft.com/Forums/en-SG/vcgeneral/thread/e0071733-286a-4b4d-b294-685f8a788fb8

3
votes

Raymond Chen wrote a blog post just for you: You can't simulate keyboard input with PostMessage. I know you want mouse, not keys, and you use Send not Post, but exactly the same problems apply to you. Read the link. Fortunately, it also contains the solution: use SendInput function.

Synthesizes keystrokes, mouse motions, and button clicks.

3
votes

This is some mouse and keyboard handler ive made when I was younger to find a color on a game screen and click ||right click+option :P

Maybe some of the code may help you even if it's in french...

        using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Abyte0
    {
        public partial class ClavierVirtuel
        {
            [DllImport("user32.dll", EntryPoint = "FindWindow")]
            private static extern int FindWindow(string _ClassName, string _WindowName);

            [DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
            private static extern int SetForegroundWindow(int hwnd);

            //int handle = FindWindow(null, "Facebook - Windows Internet Explorer");

            //Give focus to the screen with the wanted name
            public static void DonnerFocus(string pNomFenetre)


    {
            //Get the handle of the app you want to send keys to
            int handle = FindWindow(null, pNomFenetre);

            //Set it to the foreground
            SetForegroundWindow(handle);
        }

        //write the string
        public static void Ecrire(string pPhrase)
        {
            //Send the keys on over
            SendKeys.SendWait(pPhrase);
        }

        //write a string and press enter
        public static void ecrire_Enter(string pPhrase)
        {
            foreach (char lettre in pPhrase)
            {
                SendKeys.SendWait(lettre.ToString());
            }
            System.Threading.Thread.Sleep(10);
            SendKeys.SendWait("{ENTER}");
        }
    }
}

And

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;

namespace Abyte0
{
    static class MouseHandler
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool SetCursorPos(int X, int Y);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);

        private const int MOUSEEVENTF_LEFTDOWN = 0x02;
        private const int MOUSEEVENTF_LEFTUP = 0x04;
        private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
        private const int MOUSEEVENTF_RIGHTUP = 0x10;


        public static void moveMouse(ref int currentx, ref int currenty, string whattodo, int pNombre)
        {
            switch (whattodo)
            {
                case "addX":
                    for (int i = 0; i < pNombre; i++)
                    {
                        currentx++;
                        SetCursorPos(currentx + Form1.m_Border_x, currenty + Form1.m_Border_y);
                    }
                    break;
                case "addY":
                    for (int i = 0; i < pNombre; i++)
                    {
                        currenty++;
                        SetCursorPos(currentx + Form1.m_Border_x, currenty + Form1.m_Border_y);
                    }
                    break;
                case "remX":
                    for (int i = 0; i < pNombre; i++)
                    {
                        currentx--;
                        SetCursorPos(currentx + Form1.m_Border_x, currenty + Form1.m_Border_y);
                    }
                    break;
                case "remY":
                    for (int i = 0; i < pNombre; i++)
                    {
                        currenty--;
                        SetCursorPos(currentx + Form1.m_Border_x, currenty + Form1.m_Border_y);
                    }
                    break;
                default:
                    break;
            }
        }
        #region Mouse Left, Right1, Right2 Clicks
        public static void DoMouseLeftClick(int nx, int ny)
        {
            Random objRandom = new Random();
            SetCursorPos(nx + Form1.m_Border_x, ny + Form1.m_Border_y);
            mouse_event(MOUSEEVENTF_LEFTDOWN, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
            Thread.Sleep(objRandom.Next(1, 332));
            mouse_event(MOUSEEVENTF_LEFTUP, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
           // Thread.Sleep(objRandom.Next(objRandom.Next(10, objRandom.Next(180, 600)), objRandom.Next(objRandom.Next(666, 4000), 5102)));
            Handler.getFocus();
        }

        public static void DoMouseLeftClick(int[] pTab)
        {
            int nx = pTab[0];
            int ny = pTab[1];
            Random objRandom = new Random();
            SetCursorPos(nx + Form1.m_Border_x, ny + Form1.m_Border_y);
            mouse_event(MOUSEEVENTF_LEFTDOWN, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
            Thread.Sleep(objRandom.Next(1, 332));
            mouse_event(MOUSEEVENTF_LEFTUP, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
          //  Thread.Sleep(objRandom.Next(objRandom.Next(10, objRandom.Next(180, 600)), objRandom.Next(objRandom.Next(666, 4000), 5102)));
            Handler.getFocus();
        }

        public static void DoMouseRightClickOp1(int nx, int ny)
        {
            Random objRandom = new Random();
            SetCursorPos(nx + Form1.m_Border_x, ny + Form1.m_Border_y);
            mouse_event(MOUSEEVENTF_RIGHTDOWN, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
            Thread.Sleep(objRandom.Next(6, 237));
            mouse_event(MOUSEEVENTF_RIGHTUP, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
            Handler.getFocus();
            Thread.Sleep(objRandom.Next(1, 332));
            moveMouse(ref nx, ref ny, "addY", 20);
            DoMouseLeftClick(nx, ny);
        }


        public static void DoMouseRightClickOp2(int nx, int ny)
        {
            Random objRandom = new Random();
            SetCursorPos(nx + Form1.m_Border_x, ny + Form1.m_Border_y);
            mouse_event(MOUSEEVENTF_RIGHTDOWN, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
            Thread.Sleep(objRandom.Next(6, 237));
            mouse_event(MOUSEEVENTF_RIGHTUP, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
            Handler.getFocus();
            Thread.Sleep(objRandom.Next(1, 332));
            moveMouse(ref nx, ref ny, "addY", 25);
            DoMouseLeftClick(nx, ny);
        }
        #endregion


        public static void DoSimpleClickNoFocus(int x,int y)
        {
            Random objRandom = new Random();
            SetCursorPos(x,y);
            mouse_event(MOUSEEVENTF_RIGHTDOWN, x, y, 0, 0);
            Thread.Sleep(objRandom.Next(7, 258));
            mouse_event(MOUSEEVENTF_LEFTUP, x,y, 0, 0);
        }

    }
}