瀏覽代碼

Enabled mouse capture in Windows when mouse buttons are pressed to fix issues with controls stopping responding when moving the mouse outside the window.
Cleaned up some other code in WNDPROC.

Steve Grenier 13 年之前
父節點
當前提交
f359291334
共有 1 個文件被更改,包括 50 次插入58 次删除
  1. 50 58
      gameplay/src/PlatformWin32.cpp

+ 50 - 58
gameplay/src/PlatformWin32.cpp

@@ -6,6 +6,7 @@
 #include "Game.h"
 #include "Game.h"
 #include "Form.h"
 #include "Form.h"
 #include <GL/wglew.h>
 #include <GL/wglew.h>
+#include <windowsx.h>
 
 
 // Default to 720p
 // Default to 720p
 #define WINDOW_WIDTH    1280
 #define WINDOW_WIDTH    1280
@@ -22,7 +23,6 @@ static HWND __hwnd = 0;
 static HDC __hdc = 0;
 static HDC __hdc = 0;
 static HGLRC __hrc = 0;
 static HGLRC __hrc = 0;
 
 
-
 static gameplay::Keyboard::Key getKey(WPARAM win32KeyCode, bool shiftDown)
 static gameplay::Keyboard::Key getKey(WPARAM win32KeyCode, bool shiftDown)
 {
 {
     switch (win32KeyCode)
     switch (win32KeyCode)
@@ -245,6 +245,14 @@ static gameplay::Keyboard::Key getKey(WPARAM win32KeyCode, bool shiftDown)
     }
     }
 }
 }
 
 
+void UpdateCapture(LPARAM lParam)
+{
+	if ((lParam & MK_LBUTTON) || (lParam & MK_MBUTTON) || (lParam & MK_RBUTTON))
+		SetCapture(__hwnd);
+	else
+		ReleaseCapture();
+}
+
 LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
 {
     if (hwnd != __hwnd)
     if (hwnd != __hwnd)
@@ -257,9 +265,6 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
     static const float ACCELEROMETER_X_FACTOR = 90.0f / WINDOW_WIDTH;
     static const float ACCELEROMETER_X_FACTOR = 90.0f / WINDOW_WIDTH;
     static const float ACCELEROMETER_Y_FACTOR = 90.0f / WINDOW_HEIGHT;
     static const float ACCELEROMETER_Y_FACTOR = 90.0f / WINDOW_HEIGHT;
 
 
-    static bool hasMouse = false;
-    static bool lMouseDown = false;
-    static bool rMouseDown = false;
     static int lx, ly;
     static int lx, ly;
 
 
     static bool shiftDown = false;
     static bool shiftDown = false;
@@ -281,87 +286,74 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         return 0;
         return 0;
 
 
     case WM_LBUTTONDOWN:
     case WM_LBUTTONDOWN:
-        if (!gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_PRESS_LEFT_BUTTON, LOWORD(lParam), HIWORD(lParam), 0))
+		UpdateCapture(wParam);
+        if (!gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_PRESS_LEFT_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0))
         {
         {
-            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, LOWORD(lParam), HIWORD(lParam), 0);
+            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
         }
         }
-        lMouseDown = true;
         return 0;
         return 0;
 
 
     case WM_LBUTTONUP:
     case WM_LBUTTONUP:
-        lMouseDown = false;
-        if (!gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_RELEASE_LEFT_BUTTON, LOWORD(lParam), HIWORD(lParam), 0))
+        if (!gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_RELEASE_LEFT_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0))
         {
         {
-            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, LOWORD(lParam), HIWORD(lParam), 0);
+            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
         }
         }
+		UpdateCapture(wParam);
         return 0;
         return 0;
 
 
     case WM_RBUTTONDOWN:
     case WM_RBUTTONDOWN:
-        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_PRESS_RIGHT_BUTTON, LOWORD(lParam), HIWORD(lParam), 0);
-        rMouseDown = true;
-        lx = LOWORD(lParam);
-        ly = HIWORD(lParam);
+		UpdateCapture(wParam);
+		lx = GET_X_LPARAM(lParam);
+        ly = GET_Y_LPARAM(lParam);
+        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_PRESS_RIGHT_BUTTON, lx, ly, 0);
         break;
         break;
 
 
     case WM_RBUTTONUP:
     case WM_RBUTTONUP:
-        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_RELEASE_RIGHT_BUTTON, LOWORD(lParam), HIWORD(lParam), 0);
-        rMouseDown = false;
+        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_RELEASE_RIGHT_BUTTON,  GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
+		UpdateCapture(wParam);
         break;
         break;
 
 
     case WM_MBUTTONDOWN:
     case WM_MBUTTONDOWN:
-        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_PRESS_MIDDLE_BUTTON, LOWORD(lParam), HIWORD(lParam), 0);
+		UpdateCapture(wParam);
+        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_PRESS_MIDDLE_BUTTON,  GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
         break;
         break;
 
 
     case WM_MBUTTONUP:
     case WM_MBUTTONUP:
-        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_RELEASE_MIDDLE_BUTTON, LOWORD(lParam), HIWORD(lParam), 0);
+        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_RELEASE_MIDDLE_BUTTON,  GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
+		UpdateCapture(wParam);
         break;
         break;
 
 
     case WM_MOUSEMOVE:
     case WM_MOUSEMOVE:
     {
     {
-        if (!hasMouse)
-        {
-            hasMouse = true;
-
-            // Call TrackMouseEvent to detect the next WM_MOUSE_LEAVE.
-            TRACKMOUSEEVENT tme;
-            tme.cbSize = sizeof(TRACKMOUSEEVENT);
-            tme.dwFlags = TME_LEAVE;
-            tme.hwndTrack = __hwnd;
-            TrackMouseEvent(&tme);
-        }
-
-        bool consumed = gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_MOVE, LOWORD(lParam), HIWORD(lParam), 0);
-        if (lMouseDown && !consumed)
-        {
-            // Mouse move events should be interpreted as touch move only if left mouse is held and the game did not consume the mouse event.
-            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, LOWORD(lParam), HIWORD(lParam), 0);
-            return 0;
-        }
-        else if (rMouseDown)
-        {
-            // Update the pitch and roll by adding the scaled deltas.
-            __roll += -(float)(LOWORD(lParam) - lx) * ACCELEROMETER_X_FACTOR;
-            __pitch += (float)(HIWORD(lParam) - ly) * ACCELEROMETER_Y_FACTOR;
-
-            // Clamp the values to the valid range.
-            __roll = max(min(__roll, 90.0f), -90.0f);
-            __pitch = max(min(__pitch, 90.0f), -90.0f);
-
-            // Update the last X/Y values.
-            lx = LOWORD(lParam);
-            ly = HIWORD(lParam);
-        }
+		// Allow Game::mouseEvent a chance to handle (and possibly consume) the event.
+		if (!gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_MOVE, GET_X_LPARAM(lParam),  GET_Y_LPARAM(lParam), 0))
+		{
+			if ((wParam & MK_LBUTTON) == MK_LBUTTON)
+			{
+				// Mouse move events should be interpreted as touch move only if left mouse is held and the game did not consume the mouse event.
+				gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0);
+				return 0;
+			}
+			else if ((wParam & MK_RBUTTON) == MK_RBUTTON)
+			{
+				// Update the pitch and roll by adding the scaled deltas.
+				__roll += -(float)(GET_X_LPARAM(lParam) - lx) * ACCELEROMETER_X_FACTOR;
+				__pitch += (float)(GET_Y_LPARAM(lParam) - ly) * ACCELEROMETER_Y_FACTOR;
+
+				// Clamp the values to the valid range.
+				__roll = max(min(__roll, 90.0f), -90.0f);
+				__pitch = max(min(__pitch, 90.0f), -90.0f);
+
+				// Update the last X/Y values.
+				lx = GET_X_LPARAM(lParam);
+				ly = GET_Y_LPARAM(lParam);
+			}
+		}
         break;
         break;
     }
     }
 
 
-    case WM_MOUSELEAVE:
-        hasMouse = false;
-        lMouseDown = false;
-        rMouseDown = false;
-        break;
-
     case WM_MOUSEWHEEL:
     case WM_MOUSEWHEEL:
-        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_WHEEL, LOWORD(lParam), HIWORD(lParam), GET_WHEEL_DELTA_WPARAM(wParam) / 120);
+        gameplay::Game::getInstance()->mouseEvent(gameplay::Mouse::MOUSE_WHEEL, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), GET_WHEEL_DELTA_WPARAM(wParam) / 120);
         break;
         break;
 
 
     case WM_KEYDOWN:
     case WM_KEYDOWN: