Beispiel #1
0
        private static void SendMouseInput(int x, int y, int data, SendMouseInputFlags flags)
        {
            PermissionSet permissions = new PermissionSet(PermissionState.Unrestricted);

            permissions.Demand();

            uint intflags = (uint)flags;

            if ((intflags & (int)SendMouseInputFlags.Absolute) != 0)
            {
                // Absolute position requires normalized coordinates.
                NormalizeCoordinates(ref x, ref y);
                intflags |= NativeMethods.MouseeventfVirtualdesk;
            }

            INPUT mouseInput = new INPUT();

            mouseInput.Type                   = NativeMethods.INPUT_MOUSE;
            mouseInput.Data.Mouse.dx          = x;
            mouseInput.Data.Mouse.dy          = y;
            mouseInput.Data.Mouse.mouseData   = data;
            mouseInput.Data.Mouse.dwFlags     = intflags;
            mouseInput.Data.Mouse.time        = 0;
            mouseInput.Data.Mouse.dwExtraInfo = new IntPtr(0);

            if (NativeMethods.SendInput(1, new INPUT[] { mouseInput }, Marshal.SizeOf(mouseInput)) == 0)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
        }
Beispiel #2
0
        /// <summary>
        /// Performs a mouse-up operation for a specified mouse button.
        /// </summary>
        /// <param name="mouseButton">The mouse button to use.</param>
        public static void Up(MouseButton mouseButton)
        {
            int additionalData;
            SendMouseInputFlags inputFlags = GetInputFlags(mouseButton, true, out additionalData);

            SendMouseInput(0, 0, additionalData, inputFlags);
        }
Beispiel #3
0
        private static void SendMouseInput(int x, int y, int data, SendMouseInputFlags flags)
        {
            var permissions = new PermissionSet(PermissionState.Unrestricted);

            permissions.Demand();
            int dX = x, dY = y;

            if (((int)flags & (int)SendMouseInputFlags.Absolute) != 0)
            {
                int vScreenWidth  = GetSystemMetrics(78); // SMCxvirtualscreen
                int vScreenHeight = GetSystemMetrics(79); // SMCyvirtualscreen
                int vScreenLeft   = GetSystemMetrics(76); // SMXvirtualscreen
                int vScreenTop    = GetSystemMetrics(77); // SMYvirtualscreen
                dX = (x - vScreenLeft) * 65536 / vScreenWidth + 65536 / (vScreenWidth * 2);
                dY = (y - vScreenTop) * 65536 / vScreenHeight + 65536 / (vScreenHeight * 2);
            }
            var input = new INPUT()
            {
                Type       = 0,
                MouseInput = new MOUSEINPUT()
                {
                    dX          = dX,
                    dY          = dY,
                    mouseData   = data,
                    dwFlags     = (int)flags,
                    time        = 0,
                    dwExtraInfo = new IntPtr(0)
                }
            };

            SendInput(1, ref input, Marshal.SizeOf(input));
        }
Beispiel #4
0
        /// <summary>
        /// Inject pointer input into the system
        /// </summary>
        /// <param name="x">x coordinate of pointer, if Move flag specified</param>
        /// <param name="y">y coordinate of pointer, if Move flag specified</param>
        /// <param name="data">wheel movement, or mouse X button, depending on flags</param>
        /// <param name="flags">flags to indicate which type of input occurred - move, button press/release, wheel move, etc.</param>
        /// <remarks>x, y are in pixels. If Absolute flag used, are relative to desktop origin.</remarks>
        /// <outside_see conditional="false">
        /// This API does not work inside the secure execution environment.
        /// <exception cref="System.Security.Permissions.SecurityPermission"/>
        /// </outside_see>
        private static void SendMouseInput(double x, double y, int data, SendMouseInputFlags flags)
        {
            //CASRemoval:AutomationPermission.Demand( AutomationPermissionFlag.Input );

            int intflags = (int)flags;

            if ((intflags & (int)SendMouseInputFlags.Absolute) != 0)
            {
                int vscreenWidth  = GetSystemMetrics(SM_CXVIRTUALSCREEN);
                int vscreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
                int vscreenLeft   = GetSystemMetrics(SM_XVIRTUALSCREEN);
                int vscreenTop    = GetSystemMetrics(SM_YVIRTUALSCREEN);

                // Absolute input requires that input is in 'normalized' coords - with the entire
                // desktop being (0,0)...(65535,65536). Need to convert input x,y coords to this
                // first.
                //
                // In this normalized world, any pixel on the screen corresponds to a block of values
                // of normalized coords - eg. on a 1024x768 screen,
                // y pixel 0 corresponds to range 0 to 85.333,
                // y pixel 1 corresponds to range 85.333 to 170.666,
                // y pixel 2 correpsonds to range 170.666 to 256 - and so on.
                // Doing basic scaling math - (x-top)*65536/Width - gets us the start of the range.
                // However, because int math is used, this can end up being rounded into the wrong
                // pixel. For example, if we wanted pixel 1, we'd get 85.333, but that comes out as
                // 85 as an int, which falls into pixel 0's range - and that's where the pointer goes.
                // To avoid this, we add on half-a-"screen pixel"'s worth of normalized coords - to
                // push us into the middle of any given pixel's range - that's the 65536/(Width*2)
                // part of the formula. So now pixel 1 maps to 85+42 = 127 - which is comfortably
                // in the middle of that pixel's block.
                // The key ting here is that unlike points in coordinate geometry, pixels take up
                // space, so are often better treated like rectangles - and if you want to target
                // a particular pixel, target its rectangle's midpoint, not its edge.
                x = ((x - vscreenLeft) * 65536) / vscreenWidth + 65536 / (vscreenWidth * 2);
                y = ((y - vscreenTop) * 65536) / vscreenHeight + 65536 / (vscreenHeight * 2);

                intflags |= MOUSEEVENTF_VIRTUALDESK;
            }

            INPUT mi = new INPUT();

            mi.type = Const.INPUT_MOUSE;
            mi.union.mouseInput.dx          = (int)x;
            mi.union.mouseInput.dy          = (int)y;
            mi.union.mouseInput.mouseData   = data;
            mi.union.mouseInput.dwFlags     = intflags;
            mi.union.mouseInput.time        = 0;
            mi.union.mouseInput.dwExtraInfo = new IntPtr(0);
            //Console.WriteLine("Sending");
            if (SendInput(1, ref mi, Marshal.SizeOf(mi)) == 0)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
        }
Beispiel #5
0
        /// <summary>
        /// Does a mouse down at the center of the FrameworkElement with the specified button.
        /// </summary>
        /// <param name="elem">The FrameworkElement.</param>
        /// <param name="strButton">The FrameworkElement value of the mouse button to use.</param>
        public static void MouseButtonCenter(FrameworkElement elem, string strButton)
        {
            UIElement uie = elem as UIElement;

            System.Drawing.Rectangle rc = Microsoft.Test.RenderingVerification.ImageUtility.GetScreenBoundingRectangle(uie);

            SendMouseInputFlags pointerInputFlags = (SendMouseInputFlags)Enum.Parse(typeof(SendMouseInputFlags), strButton);

            Input.SendMouseInput((rc.Left + rc.Right) / 2, (rc.Top + rc.Bottom) / 2, 0, SendMouseInputFlags.Move | SendMouseInputFlags.Absolute);

            Input.SendMouseInput((rc.Left + rc.Right) / 2, (rc.Top + rc.Bottom) / 2, 0, pointerInputFlags | SendMouseInputFlags.Absolute);
        }
Beispiel #6
0
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        // Inject pointer input into the system
        // x, y are in pixels. If Absolute flag used, are relative to desktop origin.
        internal static void SendMouseInput( double x, double y, int data, SendMouseInputFlags flags )
        {
            int intflags = (int) flags;

            if( ( intflags & (int)SendMouseInputFlags.Absolute ) != 0 )
            {
                int vscreenWidth = UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_CXVIRTUALSCREEN);
                int vscreenHeight = UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_CYVIRTUALSCREEN);
                int vscreenLeft = UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_XVIRTUALSCREEN);
                int vscreenTop = UnsafeNativeMethods.GetSystemMetrics( NativeMethods.SM_YVIRTUALSCREEN );

                // Absolute input requires that input is in 'normalized' coords - with the entire
                // desktop being (0,0)...(65535,65536). Need to convert input x,y coords to this
                // first.
                //
                // In this normalized world, any pixel on the screen corresponds to a block of values
                // of normalized coords - eg. on a 1024x768 screen,
                // y pixel 0 corresponds to range 0 to 85.333,
                // y pixel 1 corresponds to range 85.333 to 170.666,
                // y pixel 2 correpsonds to range 170.666 to 256 - and so on.
                // Doing basic scaling math - (x-top)*65536/Width - gets us the start of the range.
                // However, because int math is used, this can end up being rounded into the wrong
                // pixel. For example, if we wanted pixel 1, we'd get 85.333, but that comes out as
                // 85 as an int, which falls into pixel 0's range - and that's where the pointer goes.
                // To avoid this, we add on half-a-"screen pixel"'s worth of normalized coords - to
                // push us into the middle of any given pixel's range - that's the 65536/(Width*2)
                // part of the formula. So now pixel 1 maps to 85+42 = 127 - which is comfortably
                // in the middle of that pixel's block.
                // The key ting here is that unlike points in coordinate geometry, pixels take up
                // space, so are often better treated like rectangles - and if you want to target
                // a particular pixel, target its rectangle's midpoint, not its edge.
                x = ( ( x - vscreenLeft ) * 65536 ) / vscreenWidth + 65536 / ( vscreenWidth * 2 );
                y = ( ( y - vscreenTop ) * 65536 ) / vscreenHeight + 65536 / ( vscreenHeight * 2 );

                intflags |= NativeMethods.MOUSEEVENTF_VIRTUALDESK;
            }

            NativeMethods.INPUT mi = new NativeMethods.INPUT();
            mi.type = NativeMethods.INPUT_MOUSE;
            mi.union.mouseInput.dx = (int) x;
            mi.union.mouseInput.dy = (int)y;
            mi.union.mouseInput.mouseData = data;
            mi.union.mouseInput.dwFlags = intflags;
            mi.union.mouseInput.time = 0;
            mi.union.mouseInput.dwExtraInfo = new IntPtr( 0 );
            if( UnsafeNativeMethods.SendInput( 1, ref mi, Marshal.SizeOf(mi) ) == 0 )
                throw new Win32Exception(Marshal.GetLastWin32Error());
        }
Beispiel #7
0
        /// <summary>
        /// Does a mouse down at x,y on the FrameworkElement with the specified button.
        /// </summary>
        /// <param name="elem">The FrameworkElement that x,y values are offset from.</param>
        /// <param name="x">X position in logical pixels.</param>
        /// <param name="y">Y position in logical pixels.</param>
        /// <param name="strButton">The FrameworkElement value of the mouse button to use.</param>
        public static void MouseButton(FrameworkElement elem, int x, int y, string strButton)
        {
            UIElement uie = elem as UIElement;

            System.Drawing.Rectangle rc = Microsoft.Test.RenderingVerification.ImageUtility.GetScreenBoundingRectangle(uie);


            SendMouseInputFlags pointerInputFlags = (SendMouseInputFlags)Enum.Parse(typeof(SendMouseInputFlags), strButton);

            // Convert logical pixel offset to screen pixels
            x = (int)Monitor.ConvertLogicalToScreen(Dimension.Width, x);
            y = (int)Monitor.ConvertLogicalToScreen(Dimension.Height, y);

            Input.SendMouseInput(rc.Left + x, rc.Top + y, 0, SendMouseInputFlags.Move | SendMouseInputFlags.Absolute);

            Input.SendMouseInput(rc.Left + x, rc.Top + y, 0, pointerInputFlags | SendMouseInputFlags.Absolute);
        }
Beispiel #8
0
        /// <summary>
        /// Sends mouse input.
        /// </summary>
        /// <param name="x">x coordinate</param>
        /// <param name="y">y coordinate</param>
        /// <param name="data">scroll wheel amount</param>
        /// <param name="flags">SendMouseInputFlags flags</param>
        private static void SendMouseInput(int x, int y, int data, SendMouseInputFlags flags)
        {
            uint intflags = (uint)flags;

            if ((intflags & (int)SendMouseInputFlags.Absolute) != 0)
            {
                // Absolute position requires normalized coordinates.
                NormalizeCoordinates(ref x, ref y);
                intflags |= NativeMethods.MouseeventfVirtualdesk;
            }

            // don't coalesce mouse moves - tests expect to see the results immediately
            if ((intflags & (int)SendMouseInputFlags.Move) != 0)
            {
                intflags |= NativeMethods.MOUSEEVENTF_MOVE_NOCOALESCE;
            }

            var mi = new NativeMethods.INPUT();

            mi.Type                   = NativeMethods.INPUT_MOUSE;
            mi.Data.Mouse.dx          = x;
            mi.Data.Mouse.dy          = y;
            mi.Data.Mouse.mouseData   = data;
            mi.Data.Mouse.dwFlags     = intflags;
            mi.Data.Mouse.time        = 0;
            mi.Data.Mouse.dwExtraInfo = new IntPtr(0);

            if (NativeMethods.SendInput(1, new NativeMethods.INPUT[] { mi }, Marshal.SizeOf(mi)) == 0)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            if ((intflags & (int)SendMouseInputFlags.Wheel) != 0)
            {
                // MouseWheel input seems to be getting coalesced by the OS, similar to mouse-move.
                // There isn't a NOCOALESCE flag to turn this off, so instead just sleep for
                // a short time, hopefully enough to avoid the coalescing.
                System.Threading.Thread.Sleep(50);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Inject pointer input into the system
        /// </summary>
        /// <param name="x">x coordinate of pointer, if Move flag specified</param>
        /// <param name="y">y coordinate of pointer, if Move flag specified</param>
        /// <param name="data">wheel movement, or mouse X button, depending on flags</param>
        /// <param name="flags">flags to indicate which type of input occurred - move, button press/release, wheel move, etc.</param>
        /// <remarks>x, y are in pixels. If Absolute flag used, are relative to desktop origin.</remarks>
        ///
        /// <outside_see conditional="false">
        /// This API does not work inside the secure execution environment.
        /// <exception cref="System.Security.Permissions.SecurityPermission"/>
        /// </outside_see>
        internal static void SendMouseInputInternal(double x, double y, int data, SendMouseInputFlags flags)
        {
            //CASRemoval:AutomationPermission.Demand( AutomationPermissionFlag.Input );

            int intflags = (int)flags;

            switch (MouseMoveMethod)
            {
            case MouseMoveMethod.WinForms:          // this is the code used in .NET 4.0(?)--4.8 timeframe
            case MouseMoveMethod.SetCursorPos:      // like above, except calls SetCursorPos directly
                if ((intflags & (int)SendMouseInputFlags.Absolute) != 0)
                {
                    switch (MouseMoveMethod)
                    {
                    case MouseMoveMethod.WinForms:
                        // this method of moving the cursor appears to be more reliable than the previous code,
                        // at least in the case on Vista where the DPI was changed but we haven't rebooted yet.
                        UseWinFormsToMoveMouse(x, y);
                        break;

                    case MouseMoveMethod.SetCursorPos:
                        // WinForms Cursor.set_Position just wraps SetCursorPos.
                        // Why not call it directly.
                        SetCursorPos((int)(x + 0.5), (int)(y + 0.5));
                        break;
                    }

                    //now clear the absolute flag
                    intflags &= ~(int)SendMouseInputFlags.Absolute;

                    //and set our x and y to zero so we don't move
                    x = y = 0;

                    intflags |= UnsafeNativeMethods.MOUSEEVENTF_VIRTUALDESK;
                }
                break;

            case MouseMoveMethod.SendInput:
            case MouseMoveMethod.SendInputImpliedMove:
                // (Microsoft 4/30/2019) I'm seeing problems where tests don't see
                // the mouse moves they asked for, because the OS coalesces them.
                // This is fixed by using the no-coalesce flag in SendInput.  That
                // flag is not supported on Vista/2000, but we don't support those
                // any more (which also renders moot the DPI-change remark above).

                // normalize coordinates in absolute moves
                if ((intflags & (int)SendMouseInputFlags.Absolute) != 0)
                {
                    intflags |= UnsafeNativeMethods.MOUSEEVENTF_VIRTUALDESK;
                    NormalizeAbsoluteCoordinates(ref x, ref y);

                    if (MouseMoveMethod == MouseMoveMethod.SendInputImpliedMove)
                    {
                        // the old code moved the mouse whenever Absolute was
                        // set, even if Move was not.  That's a


                        intflags |= (int)SendMouseInputFlags.Move;
                    }
                }

                // don't coalesce mouse moves - tests expect to see the results immediately
                if ((intflags & (int)SendMouseInputFlags.Move) != 0)
                {
                    intflags |= UnsafeNativeMethods.MOUSEEVENTF_MOVE_NOCOALESCE;
                }
                break;

            default:
                throw new InvalidOperationException("Test bug - unknown MouseMoveMethod");
            }

            UnsafeNativeMethods.INPUT mi = new UnsafeNativeMethods.INPUT();
            mi.type = UnsafeNativeMethods.INPUT_MOUSE;
            mi.union.mouseInput.dx          = (int)x;
            mi.union.mouseInput.dy          = (int)y;
            mi.union.mouseInput.mouseData   = data;
            mi.union.mouseInput.dwFlags     = intflags;
            mi.union.mouseInput.time        = 0;
            mi.union.mouseInput.dwExtraInfo = new IntPtr(0);
            //Console.WriteLine("Sending");
            if (UnsafeNativeMethods.SendInput(1, ref mi, Marshal.SizeOf(mi)) == 0)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            if ((intflags & (int)SendMouseInputFlags.Wheel) != 0)
            {
                // MouseWheel input seems to be getting coalesced by the OS, similar to mouse-move.
                // There isn't a NOCOALESCE flag to turn this off, so instead just sleep for
                // a short time, hopefully enough to avoid the coalescing.
                System.Threading.Thread.Sleep(50);
            }
        }
Beispiel #10
0
 /// <summary>
 /// Inject pointer input into the system
 /// </summary>
 /// <param name="x">x coordinate of pointer, if Move flag specified</param>
 /// <param name="y">y coordinate of pointer, if Move flag specified</param>
 /// <param name="data">wheel movement, or mouse X button, depending on flags</param>
 /// <param name="flags">flags to indicate which type of input occurred - move, button press/release, wheel move, etc.</param>
 /// <remarks>x, y are in pixels. If Absolute flag used, are relative to desktop origin.</remarks>
 ///
 /// <outside_see conditional="false">
 /// This API does not work inside the secure execution environment.
 /// <exception cref="System.Security.Permissions.SecurityPermission"/>
 /// </outside_see>
 public static void SendMouseInput(double x, double y, int data, SendMouseInputFlags flags)
 {
     SendMouseInputInternal(x, y, data, flags);
 }
Beispiel #11
0
 public static void SendMouseInput(int x, int y, int data, SendMouseInputFlags flags)
 {
     SendMouseInput((double)x, (double)y, data, flags);
 }