locked
Difference between SendInput and mouse_event functions of user32.dll? RRS feed

  • Question

  • Hi,

    What is the difference between SendInput and mouse_event functions ? How we can send mouse actions using SendInput function? Please provide me the C# example program for sending mouse actions using SendInput function.

    Thanks Advance,

    Regards,

    Bala Balaji P

     
    Thursday, May 28, 2020 5:15 AM

Answers

  • No difference : mouse_event calls SendInput internally

    For example, this test clicks on the "Start"  button on windows 10 =>

    IntPtr hWndTray = FindWindow("Shell_TrayWnd", null);
    IntPtr hWndStart = FindWindowEx(hWndTray, IntPtr.Zero, "Start", null);
    if (hWndStart != IntPtr.Zero)
    {
        RECT rc = new RECT();
        GetWindowRect(hWndStart, out rc);
    
        int nScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
        int nScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
        int nScreenLeft = GetSystemMetrics(SM_XVIRTUALSCREEN);
        int nScreenTop = GetSystemMetrics(SM_YVIRTUALSCREEN);
    
        int nXMove = rc.left + (rc.right - rc.left) / 2;
        int nYMove = rc.top + (rc.bottom - rc.top) / 2;
        int nX = (int)((((double)(nXMove) - nScreenLeft) * 65536) / nScreenWidth + 65536 / (nScreenWidth));
        int nY = (int)((((double)(nYMove) - nScreenTop) * 65536) / nScreenHeight + 65536 / (nScreenHeight));
    
        INPUT[] mi = new INPUT[3];
        mi[0].type = INPUT_MOUSE;
        mi[0].inputUnion.mi.dx = nX;
        mi[0].inputUnion.mi.dy = nY;
        mi[0].inputUnion.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
        mi[1].inputUnion.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN;
        mi[2].inputUnion.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP;
    
        SendInput(3, mi, Marshal.SizeOf(mi[0]));
    } 

    Declarations :

            [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
            [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
            
            [DllImport("User32.dll", SetLastError = true)]
            public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
            
            [StructLayout(LayoutKind.Sequential)]
            public struct RECT
            {
                public int left;
                public int top;
                public int right;
                public int bottom;
                public RECT(int Left, int Top, int Right, int Bottom)
                {
                    left = Left;
                    top = Top;
                    right = Right;
                    bottom = Bottom;
                }
            }
            
            [DllImport("User32.dll", SetLastError = true)]
            public static extern int SendInput(int nInputs, [MarshalAs(UnmanagedType.LPArray)] INPUT[] pInput, int cbSize);
    
            public const int INPUT_MOUSE = 0;
            public const int INPUT_KEYBOARD = 1;
            public const int INPUT_HARDWARE = 2;
    
            public const int KEYEVENTF_EXTENDEDKEY = 0x0001;
            public const int KEYEVENTF_KEYUP = 0x0002;
            public const int KEYEVENTF_UNICODE = 0x0004;
    
            [StructLayout(LayoutKind.Sequential)]
            public struct MOUSEINPUT
            {
                public int dx;
                public int dy;
                public int mouseData;
                public int dwFlags;
                public int time;
                public IntPtr dwExtraInfo;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct KEYBDINPUT
            {
                public short wVk;
                public short wScan;
                public int dwFlags;
                public int time;
                public IntPtr dwExtraInfo;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct HARDWAREINPUT
            {
                public int uMsg;
                public short wParamL;
                public short wParamH;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct INPUT
            {
                public int type;
                public INPUTUNION inputUnion;
            }
    
            [StructLayout(LayoutKind.Explicit)]
            public struct INPUTUNION
            {
                [FieldOffset(0)]
                public MOUSEINPUT mi;
                [FieldOffset(0)]
                public KEYBDINPUT ki;
                [FieldOffset(0)]
                public HARDWAREINPUT hi;
            }
    
            public const int MOUSEEVENTF_MOVE = 0x0001; /* mouse move */
            public const int MOUSEEVENTF_LEFTDOWN = 0x0002; /* left button down */
            public const int MOUSEEVENTF_LEFTUP = 0x0004; /* left button up */
            public const int MOUSEEVENTF_RIGHTDOWN = 0x0008; /* right button down */
            public const int MOUSEEVENTF_RIGHTUP = 0x0010; /* right button up */
            public const int MOUSEEVENTF_MIDDLEDOWN = 0x0020; /* middle button down */
            public const int MOUSEEVENTF_MIDDLEUP = 0x0040; /* middle button up */
            public const int MOUSEEVENTF_XDOWN = 0x0080; /* x button down */
            public const int MOUSEEVENTF_XUP = 0x0100; /* x button down */
            public const int MOUSEEVENTF_WHEEL = 0x0800; /* wheel button rolled */
            public const int MOUSEEVENTF_HWHEEL = 0x01000; /* hwheel button rolled */
            public const int MOUSEEVENTF_MOVE_NOCOALESCE = 0x2000; /* do not coalesce mouse moves */
            public const int MOUSEEVENTF_VIRTUALDESK = 0x4000; /* map to entire virtual desktop */
            public const int MOUSEEVENTF_ABSOLUTE = 0x8000; /* absolute move */
    
            public const int SM_XVIRTUALSCREEN = 76;
            public const int SM_YVIRTUALSCREEN = 77;
            public const int SM_CXVIRTUALSCREEN = 78;
            public const int SM_CYVIRTUALSCREEN = 79;
    
            [DllImport("User32.dll", SetLastError = true)]
            public static extern int GetSystemMetrics(int nIndex);

    Thursday, May 28, 2020 6:43 AM

All replies

  • No difference : mouse_event calls SendInput internally

    For example, this test clicks on the "Start"  button on windows 10 =>

    IntPtr hWndTray = FindWindow("Shell_TrayWnd", null);
    IntPtr hWndStart = FindWindowEx(hWndTray, IntPtr.Zero, "Start", null);
    if (hWndStart != IntPtr.Zero)
    {
        RECT rc = new RECT();
        GetWindowRect(hWndStart, out rc);
    
        int nScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
        int nScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
        int nScreenLeft = GetSystemMetrics(SM_XVIRTUALSCREEN);
        int nScreenTop = GetSystemMetrics(SM_YVIRTUALSCREEN);
    
        int nXMove = rc.left + (rc.right - rc.left) / 2;
        int nYMove = rc.top + (rc.bottom - rc.top) / 2;
        int nX = (int)((((double)(nXMove) - nScreenLeft) * 65536) / nScreenWidth + 65536 / (nScreenWidth));
        int nY = (int)((((double)(nYMove) - nScreenTop) * 65536) / nScreenHeight + 65536 / (nScreenHeight));
    
        INPUT[] mi = new INPUT[3];
        mi[0].type = INPUT_MOUSE;
        mi[0].inputUnion.mi.dx = nX;
        mi[0].inputUnion.mi.dy = nY;
        mi[0].inputUnion.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
        mi[1].inputUnion.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN;
        mi[2].inputUnion.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP;
    
        SendInput(3, mi, Marshal.SizeOf(mi[0]));
    } 

    Declarations :

            [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
            [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
            
            [DllImport("User32.dll", SetLastError = true)]
            public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
            
            [StructLayout(LayoutKind.Sequential)]
            public struct RECT
            {
                public int left;
                public int top;
                public int right;
                public int bottom;
                public RECT(int Left, int Top, int Right, int Bottom)
                {
                    left = Left;
                    top = Top;
                    right = Right;
                    bottom = Bottom;
                }
            }
            
            [DllImport("User32.dll", SetLastError = true)]
            public static extern int SendInput(int nInputs, [MarshalAs(UnmanagedType.LPArray)] INPUT[] pInput, int cbSize);
    
            public const int INPUT_MOUSE = 0;
            public const int INPUT_KEYBOARD = 1;
            public const int INPUT_HARDWARE = 2;
    
            public const int KEYEVENTF_EXTENDEDKEY = 0x0001;
            public const int KEYEVENTF_KEYUP = 0x0002;
            public const int KEYEVENTF_UNICODE = 0x0004;
    
            [StructLayout(LayoutKind.Sequential)]
            public struct MOUSEINPUT
            {
                public int dx;
                public int dy;
                public int mouseData;
                public int dwFlags;
                public int time;
                public IntPtr dwExtraInfo;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct KEYBDINPUT
            {
                public short wVk;
                public short wScan;
                public int dwFlags;
                public int time;
                public IntPtr dwExtraInfo;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct HARDWAREINPUT
            {
                public int uMsg;
                public short wParamL;
                public short wParamH;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct INPUT
            {
                public int type;
                public INPUTUNION inputUnion;
            }
    
            [StructLayout(LayoutKind.Explicit)]
            public struct INPUTUNION
            {
                [FieldOffset(0)]
                public MOUSEINPUT mi;
                [FieldOffset(0)]
                public KEYBDINPUT ki;
                [FieldOffset(0)]
                public HARDWAREINPUT hi;
            }
    
            public const int MOUSEEVENTF_MOVE = 0x0001; /* mouse move */
            public const int MOUSEEVENTF_LEFTDOWN = 0x0002; /* left button down */
            public const int MOUSEEVENTF_LEFTUP = 0x0004; /* left button up */
            public const int MOUSEEVENTF_RIGHTDOWN = 0x0008; /* right button down */
            public const int MOUSEEVENTF_RIGHTUP = 0x0010; /* right button up */
            public const int MOUSEEVENTF_MIDDLEDOWN = 0x0020; /* middle button down */
            public const int MOUSEEVENTF_MIDDLEUP = 0x0040; /* middle button up */
            public const int MOUSEEVENTF_XDOWN = 0x0080; /* x button down */
            public const int MOUSEEVENTF_XUP = 0x0100; /* x button down */
            public const int MOUSEEVENTF_WHEEL = 0x0800; /* wheel button rolled */
            public const int MOUSEEVENTF_HWHEEL = 0x01000; /* hwheel button rolled */
            public const int MOUSEEVENTF_MOVE_NOCOALESCE = 0x2000; /* do not coalesce mouse moves */
            public const int MOUSEEVENTF_VIRTUALDESK = 0x4000; /* map to entire virtual desktop */
            public const int MOUSEEVENTF_ABSOLUTE = 0x8000; /* absolute move */
    
            public const int SM_XVIRTUALSCREEN = 76;
            public const int SM_YVIRTUALSCREEN = 77;
            public const int SM_CXVIRTUALSCREEN = 78;
            public const int SM_CYVIRTUALSCREEN = 79;
    
            [DllImport("User32.dll", SetLastError = true)]
            public static extern int GetSystemMetrics(int nIndex);

    Thursday, May 28, 2020 6:43 AM
  • Thank you so much for reply

    Thanks & Regards,

    Bala Balaji P

    Friday, June 12, 2020 7:29 AM