Skip to content

Commit

Permalink
Backends: Win32: Secondary viewports WndProc handler retrieve/set img…
Browse files Browse the repository at this point in the history
…ui context from the HWND.

Allowing WndProc dispatch to work in multi-context setups.
  • Loading branch information
ocornut committed Jun 21, 2024
1 parent 3acb869 commit 416cfdb
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 7 deletions.
26 changes: 19 additions & 7 deletions backends/imgui_impl_win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,9 @@ static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
vd->HwndOwned = true;
viewport->PlatformRequestResize = false;
viewport->PlatformHandle = viewport->PlatformHandleRaw = vd->Hwnd;

// Secondary viewports store their imgui context
::SetPropA(vd->Hwnd, "IMGUI_CONTEXT", ImGui::GetCurrentContext());
}

static void ImGui_ImplWin32_DestroyWindow(ImGuiViewport* viewport)
Expand Down Expand Up @@ -1256,10 +1259,16 @@ static void ImGui_ImplWin32_OnChangedViewport(ImGuiViewport* viewport)

static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
return true;
// Allow secondary viewport WndProc to be called regardless of current context
ImGuiContext* hwnd_ctx = (ImGuiContext*)::GetPropA(hWnd, "IMGUI_CONTEXT");
ImGuiContext* prev_ctx = ImGui::GetCurrentContext();
if (hwnd_ctx != prev_ctx && hwnd_ctx != NULL)
ImGui::SetCurrentContext(hwnd_ctx);

if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hWnd))
LRESULT result = 0;
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
result = true;
else if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hWnd))
{
switch (msg)
{
Expand All @@ -1274,20 +1283,23 @@ static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd,
break;
case WM_MOUSEACTIVATE:
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnClick)
return MA_NOACTIVATE;
result = MA_NOACTIVATE;
break;
case WM_NCHITTEST:
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() correctly. (which is optional).
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
if (viewport->Flags & ImGuiViewportFlags_NoInputs)
return HTTRANSPARENT;
result = HTTRANSPARENT;
break;
}
}

return DefWindowProc(hWnd, msg, wParam, lParam);
if (result == 0)
result = DefWindowProc(hWnd, msg, wParam, lParam);
if (hwnd_ctx != prev_ctx && hwnd_ctx != NULL)
ImGui::SetCurrentContext(prev_ctx);
return result;
}

static void ImGui_ImplWin32_InitPlatformInterface(bool platform_has_own_dc)
Expand Down
2 changes: 2 additions & 0 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ Docking+Viewports Branch:

- Backends: SDL3: Update for introduction of SDL_GLContext from void*. (#7701, #7702)
[@bcsanches]
- Backends: Win32: Secondary viewports WndProc handler retrieve/set imgui context from
the HWND, allowing WndProc dispatch to work in multi-context setups.


-----------------------------------------------------------------------
Expand Down

0 comments on commit 416cfdb

Please sign in to comment.