예제 #1
0
        void HandleMouseMove(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
        {
            unsafe
            {
                Point point = new Point(
                    (short)((uint)lParam.ToInt32() & 0x0000FFFF),
                    (short)(((uint)lParam.ToInt32() & 0xFFFF0000) >> 16));

                // GetMouseMovePointsEx works with screen coordinates
                Point screenPoint = point;
                Functions.ClientToScreen(handle, ref screenPoint);
                int timestamp = Functions.GetMessageTime();

                // & 0xFFFF to handle multiple monitors http://support.microsoft.com/kb/269743 
                MouseMovePoint movePoint = new MouseMovePoint()
                {
                    X = screenPoint.X & 0xFFFF,
                    Y = screenPoint.Y & 0xFFFF,
                    Time = timestamp,
                };

                // Max points GetMouseMovePointsEx can return is 64.
                const int numPoints = 64;
                MouseMovePoint* movePoints = stackalloc MouseMovePoint[numPoints];

                // GetMouseMovePointsEx fills in movePoints so that the most 
                // recent events are at low indices in the array.
                int points = Functions.GetMouseMovePointsEx(
                    (uint)MouseMovePoint.SizeInBytes,
                    &movePoint, movePoints, numPoints,
                    Constants.GMMP_USE_DISPLAY_POINTS);

                int lastError = Marshal.GetLastWin32Error();

                // No points returned or search point not found
                if (points == 0 || (points == -1 && lastError == Constants.ERROR_POINT_NOT_FOUND))
                {
                    // Just use the mouse move position
                    OnMouseMove(point.X, point.Y);
                }
                else if (points == -1)
                {
                    throw new System.ComponentModel.Win32Exception(lastError);
                }
                else
                {
                    // Exclude the current position. 
                    Point currentScreenPosition = new Point(MouseState.X, MouseState.Y);
                    Functions.ClientToScreen(handle, ref currentScreenPosition);

                    // Find the first move point we've already seen.
                    int i = 0;
                    for (i = 0; i < points; ++i)
                    {
                        if (movePoints[i].Time < mouse_last_timestamp)
                            break;
                        if (movePoints[i].Time == mouse_last_timestamp &&
                            movePoints[i].X == currentScreenPosition.X &&
                            movePoints[i].Y == currentScreenPosition.Y)
                            break;
                    }

                    // Now move the mouse to each point before the one just found.
                    while (--i >= 0)
                    {
                        Point position = new Point(movePoints[i].X, movePoints[i].Y);
                        // Handle multiple monitors http://support.microsoft.com/kb/269743 
                        if (position.X > 32767)
                        {
                            position.X -= 65536;
                        }
                        if (position.Y > 32767)
                        {
                            position.Y -= 65536;
                        }
                        Functions.ScreenToClient(handle, ref position);
                        OnMouseMove(position.X, position.Y);
                    }
                }
                mouse_last_timestamp = timestamp;
            }

            if (mouse_outside_window)
            {
                // Once we receive a mouse move event, it means that the mouse has
                // re-entered the window.
                mouse_outside_window = false;
                EnableMouseTracking();

                OnMouseEnter(EventArgs.Empty);
            }
        }
예제 #2
0
 unsafe internal static extern int GetMouseMovePointsEx(
     uint cbSize, MouseMovePoint* pointsIn, 
     MouseMovePoint* pointsBufferOut, int nBufPoints, uint resolution);