Browse Source

Examples: DirectX10, DirectX11: Using SetCapture/ReleaseCapture to get correct behavior (#1375)
ps: DirectX 12 example (#302) may want to adopt that as well.

omar 7 years ago
parent
commit
a96f095deb

+ 22 - 7
examples/directx10_example/imgui_impl_dx10.cpp

@@ -225,28 +225,43 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data)
     ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
     ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
 }
 }
 
 
-IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
+static bool IsAnyMouseButtonDown()
+{
+    ImGuiIO& io = ImGui::GetIO();
+    for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++)
+        if (io.MouseDown[n])
+            return true;
+    return false;
+}
+
+IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
 {
     ImGuiIO& io = ImGui::GetIO();
     ImGuiIO& io = ImGui::GetIO();
     switch (msg)
     switch (msg)
     {
     {
     case WM_LBUTTONDOWN:
     case WM_LBUTTONDOWN:
+        if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd);
         io.MouseDown[0] = true;
         io.MouseDown[0] = true;
         return true;
         return true;
-    case WM_LBUTTONUP:
-        io.MouseDown[0] = false;
-        return true;
     case WM_RBUTTONDOWN:
     case WM_RBUTTONDOWN:
+        if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd);
         io.MouseDown[1] = true;
         io.MouseDown[1] = true;
         return true;
         return true;
-    case WM_RBUTTONUP:
-        io.MouseDown[1] = false;
-        return true;
     case WM_MBUTTONDOWN:
     case WM_MBUTTONDOWN:
+        if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd);
         io.MouseDown[2] = true;
         io.MouseDown[2] = true;
         return true;
         return true;
+    case WM_LBUTTONUP:
+        io.MouseDown[0] = false;
+        if (!IsAnyMouseButtonDown()) ::ReleaseCapture();
+        return true;
+    case WM_RBUTTONUP:
+        io.MouseDown[1] = false;
+        if (!IsAnyMouseButtonDown()) ::ReleaseCapture();
+        return true;
     case WM_MBUTTONUP:
     case WM_MBUTTONUP:
         io.MouseDown[2] = false;
         io.MouseDown[2] = false;
+        if (!IsAnyMouseButtonDown()) ::ReleaseCapture();
         return true;
         return true;
     case WM_MOUSEWHEEL:
     case WM_MOUSEWHEEL:
         io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f;
         io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f;

+ 22 - 7
examples/directx11_example/imgui_impl_dx11.cpp

@@ -232,28 +232,43 @@ void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data)
     ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
     ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
 }
 }
 
 
-IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
+static bool IsAnyMouseButtonDown()
+{
+    ImGuiIO& io = ImGui::GetIO();
+    for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++)
+        if (io.MouseDown[n])
+            return true;
+    return false;
+}
+
+IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
 {
     ImGuiIO& io = ImGui::GetIO();
     ImGuiIO& io = ImGui::GetIO();
     switch (msg)
     switch (msg)
     {
     {
     case WM_LBUTTONDOWN:
     case WM_LBUTTONDOWN:
+        if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd);
         io.MouseDown[0] = true;
         io.MouseDown[0] = true;
         return true;
         return true;
-    case WM_LBUTTONUP:
-        io.MouseDown[0] = false;
-        return true;
     case WM_RBUTTONDOWN:
     case WM_RBUTTONDOWN:
+        if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd);
         io.MouseDown[1] = true;
         io.MouseDown[1] = true;
         return true;
         return true;
-    case WM_RBUTTONUP:
-        io.MouseDown[1] = false;
-        return true;
     case WM_MBUTTONDOWN:
     case WM_MBUTTONDOWN:
+        if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd);
         io.MouseDown[2] = true;
         io.MouseDown[2] = true;
         return true;
         return true;
+    case WM_LBUTTONUP:
+        io.MouseDown[0] = false;
+        if (!IsAnyMouseButtonDown()) ::ReleaseCapture();
+        return true;
+    case WM_RBUTTONUP:
+        io.MouseDown[1] = false;
+        if (!IsAnyMouseButtonDown()) ::ReleaseCapture();
+        return true;
     case WM_MBUTTONUP:
     case WM_MBUTTONUP:
         io.MouseDown[2] = false;
         io.MouseDown[2] = false;
+        if (!IsAnyMouseButtonDown()) ::ReleaseCapture();
         return true;
         return true;
     case WM_MOUSEWHEEL:
     case WM_MOUSEWHEEL:
         io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f;
         io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f;