|
@@ -950,11 +950,12 @@ void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
|
|
|
struct ImGui_ImplWin32_ViewportData
|
|
|
{
|
|
|
HWND Hwnd;
|
|
|
+ HWND HwndParent;
|
|
|
bool HwndOwned;
|
|
|
DWORD DwStyle;
|
|
|
DWORD DwExStyle;
|
|
|
|
|
|
- ImGui_ImplWin32_ViewportData() { Hwnd = nullptr; HwndOwned = false; DwStyle = DwExStyle = 0; }
|
|
|
+ ImGui_ImplWin32_ViewportData() { Hwnd = HwndParent = nullptr; HwndOwned = false; DwStyle = DwExStyle = 0; }
|
|
|
~ImGui_ImplWin32_ViewportData() { IM_ASSERT(Hwnd == nullptr); }
|
|
|
};
|
|
|
|
|
@@ -974,6 +975,14 @@ static void ImGui_ImplWin32_GetWin32StyleFromViewportFlags(ImGuiViewportFlags fl
|
|
|
*out_ex_style |= WS_EX_TOPMOST;
|
|
|
}
|
|
|
|
|
|
+static HWND ImGui_ImplWin32_GetHwndFromViewportID(ImGuiID viewport_id)
|
|
|
+{
|
|
|
+ if (viewport_id != 0)
|
|
|
+ if (ImGuiViewport* viewport = ImGui::FindViewportByID(viewport_id))
|
|
|
+ return (HWND)viewport->PlatformHandle;
|
|
|
+ return nullptr;
|
|
|
+}
|
|
|
+
|
|
|
static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
|
|
|
{
|
|
|
ImGui_ImplWin32_ViewportData* vd = IM_NEW(ImGui_ImplWin32_ViewportData)();
|
|
@@ -981,10 +990,7 @@ static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
|
|
|
|
|
|
// Select style and parent window
|
|
|
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &vd->DwStyle, &vd->DwExStyle);
|
|
|
- HWND parent_window = nullptr;
|
|
|
- if (viewport->ParentViewportId != 0)
|
|
|
- if (ImGuiViewport* parent_viewport = ImGui::FindViewportByID(viewport->ParentViewportId))
|
|
|
- parent_window = (HWND)parent_viewport->PlatformHandle;
|
|
|
+ vd->HwndParent = ImGui_ImplWin32_GetHwndFromViewportID(viewport->ParentViewportId);
|
|
|
|
|
|
// Create window
|
|
|
RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) };
|
|
@@ -992,7 +998,7 @@ static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
|
|
|
vd->Hwnd = ::CreateWindowEx(
|
|
|
vd->DwExStyle, _T("ImGui Platform"), _T("Untitled"), vd->DwStyle, // Style, class name, window name
|
|
|
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area
|
|
|
- parent_window, nullptr, ::GetModuleHandle(nullptr), nullptr); // Parent window, Menu, Instance, Param
|
|
|
+ vd->HwndParent, nullptr, ::GetModuleHandle(nullptr), nullptr); // Owner window, Menu, Instance, Param
|
|
|
vd->HwndOwned = true;
|
|
|
viewport->PlatformRequestResize = false;
|
|
|
viewport->PlatformHandle = viewport->PlatformHandleRaw = vd->Hwnd;
|
|
@@ -1029,10 +1035,26 @@ static void ImGui_ImplWin32_ShowWindow(ImGuiViewport* viewport)
|
|
|
|
|
|
static void ImGui_ImplWin32_UpdateWindow(ImGuiViewport* viewport)
|
|
|
{
|
|
|
- // (Optional) Update Win32 style if it changed _after_ creation.
|
|
|
- // Generally they won't change unless configuration flags are changed, but advanced uses (such as manually rewriting viewport flags) make this useful.
|
|
|
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
|
IM_ASSERT(vd->Hwnd != 0);
|
|
|
+
|
|
|
+ // Update Win32 parent if it changed _after_ creation
|
|
|
+ // Unlike style settings derived from configuration flags, this is more likely to change for advanced apps that are manipulating ParentViewportID manually.
|
|
|
+ HWND new_parent = ImGui_ImplWin32_GetHwndFromViewportID(viewport->ParentViewportId);
|
|
|
+ if (new_parent != vd->HwndParent)
|
|
|
+ {
|
|
|
+ // Win32 windows can either have a "Parent" (for WS_CHILD window) or an "Owner" (which among other thing keeps window above its owner).
|
|
|
+ // Our Dear Imgui-side concept of parenting only mostly care about what Win32 call "Owner".
|
|
|
+ // The parent parameter of CreateWindowEx() sets up Parent OR Owner depending on WS_CHILD flag. In our case an Owner as we never use WS_CHILD.
|
|
|
+ // Calling ::SetParent() here would be incorrect: it will create a full child relation, alter coordinate system and clipping.
|
|
|
+ // Calling ::SetWindowLongPtr() with GWLP_HWNDPARENT seems correct although poorly documented.
|
|
|
+ // https://devblogs.microsoft.com/oldnewthing/20100315-00/?p=14613
|
|
|
+ vd->HwndParent = new_parent;
|
|
|
+ ::SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)vd->HwndParent);
|
|
|
+ }
|
|
|
+
|
|
|
+ // (Optional) Update Win32 style if it changed _after_ creation.
|
|
|
+ // Generally they won't change unless configuration flags are changed, but advanced uses (such as manually rewriting viewport flags) make this useful.
|
|
|
DWORD new_style;
|
|
|
DWORD new_ex_style;
|
|
|
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &new_style, &new_ex_style);
|