protected void UpdateMouseDelta() { // Get current position of mouse NativeMethods.GetCursorPos(out XMInt2 ptCurMousePos); // Calc how far it's moved since last frame XMInt2 ptCurMouseDelta = new XMInt2( ptCurMousePos.X - m_ptLastMousePosition.X, ptCurMousePos.Y - m_ptLastMousePosition.Y); // Record current position for next time m_ptLastMousePosition = ptCurMousePos; if (m_bResetCursorAfterMove && m_isActive) { // Get the center of the current monitor NativeMethods.GetClipCursor(out XMInt4 lpRect); // Set position of camera to center of desktop, // so it always has room to move. This is very useful // if the cursor is hidden. If this isn't done and cursor is hidden, // then invisible cursor will hit the edge of the screen // and the user can't tell what happened XMInt2 ptCenter = new XMInt2( (lpRect.X + lpRect.Z) / 2, (lpRect.Y + lpRect.W) / 2); NativeMethods.SetCursorPos(ptCenter.X, ptCenter.Y); m_ptLastMousePosition = ptCenter; } // Smooth the relative mouse data over a few frames so it isn't // jerky when moving slowly at low frame rates. float fPercentOfNew = 1.0f / m_fFramesToSmoothMouseData; float fPercentOfOld = 1.0f - fPercentOfNew; m_vMouseDelta.X = m_vMouseDelta.X * fPercentOfOld + ptCurMouseDelta.X * fPercentOfNew; m_vMouseDelta.Y = m_vMouseDelta.Y * fPercentOfOld + ptCurMouseDelta.Y * fPercentOfNew; m_vRotVelocity.X = m_vMouseDelta.X * m_fRotationScaler; m_vRotVelocity.Y = m_vMouseDelta.Y * m_fRotationScaler; }
public static extern bool PtInRect(ref XMInt4 lprc, XMInt2 pt);
public static extern bool GetCursorPos(out XMInt2 lpPoint);
public virtual void HandleMessages(IntPtr hWnd, WindowMessageType msg, IntPtr wParam, IntPtr lParam) { // Current mouse position int iMouseX = (short)((ulong)lParam & 0xffffU); int iMouseY = (short)((ulong)lParam >> 16); switch (msg) { case WindowMessageType.ActivateApplication: { m_isActive = wParam.ToInt32() == 1; break; } case WindowMessageType.KeyDown: { // Map this key to a D3DUtil_CameraKeys enum and update the // state of m_aKeys[] by adding the KEY_WAS_DOWN_MASK|KEY_IS_DOWN_MASK mask // only if the key is not down SdkCameraKey mappedKey = MapKey((VirtualKey)wParam); if (mappedKey != SdkCameraKey.Unknown) { if (!IsKeyDown(m_aKeys[(int)mappedKey])) { m_aKeys[(int)mappedKey] = SdkCameraKeyStates.WasDownMask | SdkCameraKeyStates.IsDownMask; m_cKeysDown++; } } break; } case WindowMessageType.KeyUp: { // Map this key to a D3DUtil_CameraKeys enum and update the // state of m_aKeys[] by removing the KEY_IS_DOWN_MASK mask. SdkCameraKey mappedKey = MapKey((VirtualKey)wParam); if (mappedKey != SdkCameraKey.Unknown) { m_aKeys[(int)mappedKey] &= ~SdkCameraKeyStates.IsDownMask; m_cKeysDown--; } break; } case WindowMessageType.RightButtonDown: case WindowMessageType.MiddleButtonDown: case WindowMessageType.LeftButtonDown: case WindowMessageType.RightButtonDoubleClick: case WindowMessageType.MiddleButtonDoubleClick: case WindowMessageType.LeftButtonDoubleClick: { // Compute the drag rectangle in screen coord. XMInt2 ptCursor = new XMInt2(iMouseX, iMouseY); // Update member var state if ((msg == WindowMessageType.LeftButtonDown || msg == WindowMessageType.LeftButtonDoubleClick) && NativeMethods.PtInRect(ref m_rcDrag, ptCursor)) { m_bMouseLButtonDown = true; m_nCurrentButtonMask |= MouseKeys.LeftButton; } if ((msg == WindowMessageType.MiddleButtonDown || msg == WindowMessageType.MiddleButtonDoubleClick) && NativeMethods.PtInRect(ref m_rcDrag, ptCursor)) { m_bMouseMButtonDown = true; m_nCurrentButtonMask |= MouseKeys.MiddleButton; } if ((msg == WindowMessageType.RightButtonDown || msg == WindowMessageType.RightButtonDoubleClick) && NativeMethods.PtInRect(ref m_rcDrag, ptCursor)) { m_bMouseRButtonDown = true; m_nCurrentButtonMask |= MouseKeys.RightButton; } // Capture the mouse, so if the mouse button is // released outside the window, we'll get the WM_LBUTTONUP message NativeMethods.SetCapture(hWnd); NativeMethods.GetCursorPos(out m_ptLastMousePosition); break; } case WindowMessageType.RightButtonUp: case WindowMessageType.MiddleButtonUp: case WindowMessageType.LeftButtonUp: { // Update member var state if (msg == WindowMessageType.LeftButtonUp) { m_bMouseLButtonDown = false; m_nCurrentButtonMask &= ~MouseKeys.LeftButton; } if (msg == WindowMessageType.MiddleButtonUp) { m_bMouseMButtonDown = false; m_nCurrentButtonMask &= ~MouseKeys.MiddleButton; } if (msg == WindowMessageType.RightButtonUp) { m_bMouseRButtonDown = false; m_nCurrentButtonMask &= ~MouseKeys.RightButton; } // Release the capture if no mouse buttons down if (!m_bMouseLButtonDown && !m_bMouseRButtonDown && !m_bMouseMButtonDown) { NativeMethods.ReleaseCapture(); } break; } case WindowMessageType.CaptureChanged: { if (lParam != hWnd) { if ((m_nCurrentButtonMask & MouseKeys.LeftButton) != 0 || (m_nCurrentButtonMask & MouseKeys.MiddleButton) != 0 || (m_nCurrentButtonMask & MouseKeys.RightButton) != 0) { m_bMouseLButtonDown = false; m_bMouseMButtonDown = false; m_bMouseRButtonDown = false; m_nCurrentButtonMask &= ~MouseKeys.LeftButton; m_nCurrentButtonMask &= ~MouseKeys.MiddleButton; m_nCurrentButtonMask &= ~MouseKeys.RightButton; NativeMethods.ReleaseCapture(); } } break; } case WindowMessageType.MouseWheel: { // Update member var state m_nMouseWheelDelta += (short)((uint)wParam >> 16); break; } } }