diff --git a/src/Win/WinMessage.cpp b/src/Win/WinMessage.cpp index a9424c9..1544d44 100644 --- a/src/Win/WinMessage.cpp +++ b/src/Win/WinMessage.cpp @@ -10,6 +10,8 @@ namespace hgl { namespace { + #define PROP_DPIISOLATION L"PROP_ISOLATION" + static KeyboardButton KeyConvert[256]; static void (*WMProc[2048])(WinWindow *,uint32,uint32); //消息处理队列 @@ -190,6 +192,65 @@ namespace hgl return KeyConvert[key]; } + void WMProcNCCreate(WinWindow *win,uint32 wParam,uint32 lParam) + { + auto createStruct = reinterpret_cast(lParam); + auto createParams = static_cast(createStruct->lpCreateParams); + + if (createParams->bEnableNonClientDpiScaling) + { + EnableNonClientDpiScaling(win->GetWnd()); + } + + // Store a flag on the window to note that it'll run its child in a different awareness + if (createParams->bChildWindowDpiIsolation) + { + SetPropW(win->GetWnd(), PROP_DPIISOLATION, (HANDLE)TRUE); + } + } + + void WMProcCreate(WinWindow *win,uint32 wParam,uint32 lParam) + { + HWND hWnd=win->GetWnd(); + RECT rcWindow = {}; + UINT uDpi = 96; + DPI_AWARENESS dpiAwareness = GetAwarenessFromDpiAwarenessContext(GetThreadDpiAwarenessContext()); + + switch (dpiAwareness) + { + // Scale the window to the system DPI + case DPI_AWARENESS_SYSTEM_AWARE: + uDpi = GetDpiForSystem(); + break; + + // Scale the window to the monitor DPI + case DPI_AWARENESS_PER_MONITOR_AWARE: + uDpi = GetDpiForWindow(hWnd); + break; + } + + GetWindowRect(hWnd, &rcWindow); + rcWindow.right = rcWindow.left + MulDiv(win->GetWidth(), uDpi, 96); + rcWindow.bottom = rcWindow.top + MulDiv(win->GetHeight(), uDpi, 96); + SetWindowPos(hWnd, nullptr, rcWindow.right, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, SWP_NOZORDER | SWP_NOACTIVATE); + + BOOL bDpiIsolation = PtrToInt(GetPropW(hWnd, PROP_DPIISOLATION)); + + DPI_AWARENESS_CONTEXT previousDpiContext = {}; + DPI_HOSTING_BEHAVIOR previousDpiHostingBehavior = {}; + + if (bDpiIsolation) + { + previousDpiHostingBehavior = SetThreadDpiHostingBehavior(DPI_HOSTING_BEHAVIOR_MIXED); + + // For this example, we'll have the external content run with System-DPI awareness + previousDpiContext = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); + + SetThreadDpiAwarenessContext(previousDpiContext); + SetThreadDpiHostingBehavior(previousDpiHostingBehavior); + } + } + void WMProcDestroy(WinWindow *win,uint32,uint32) { win->ProcClose(); @@ -282,6 +343,8 @@ namespace hgl #define WM_MAP(wm,func) WMProc[wm]=func; + WM_MAP(WM_NCCREATE ,WMProcNCCreate); + WM_MAP(WM_CREATE ,WMProcCreate); WM_MAP(WM_CLOSE ,WMProcDestroy); WM_MAP(WM_LBUTTONDOWN ,WMProcMouseLeftPressed); WM_MAP(WM_LBUTTONUP ,WMProcMouseLeftReleased); diff --git a/src/Win/WinWindow.cpp b/src/Win/WinWindow.cpp index 5301fbc..f3012d4 100644 --- a/src/Win/WinWindow.cpp +++ b/src/Win/WinWindow.cpp @@ -63,6 +63,18 @@ namespace hgl win_top = CW_USEDEFAULT; } + WindowCreateExteraParams createParams; + + { + context = DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2; + previousDpiContext = SetThreadDpiAwarenessContext(context); + + createParams.bEnableNonClientDpiScaling = FALSE; + createParams.bChildWindowDpiIsolation = TRUE; + + previousDpiHostingBehavior = SetThreadDpiHostingBehavior(DPI_HOSTING_BEHAVIOR_MIXED); + } + win_hwnd = CreateWindowExW(0, WIN_CLASS_NAME, // class name win_name.c_str(), // app name @@ -73,7 +85,7 @@ namespace hgl nullptr, // handle to parent nullptr, // handle to menu hInstance, // hInstance - nullptr); // no extra parameters + &createParams); // extra parameters if (!win_hwnd) { @@ -149,6 +161,10 @@ namespace hgl void WinWindow::Show() { ShowWindow(win_hwnd, SW_SHOW); + + SetThreadDpiAwarenessContext(previousDpiContext); + SetThreadDpiHostingBehavior(previousDpiHostingBehavior); + SetForegroundWindow(win_hwnd); SetFocus(win_hwnd); diff --git a/src/Win/WinWindow.h b/src/Win/WinWindow.h index 7401847..fe3f52b 100644 --- a/src/Win/WinWindow.h +++ b/src/Win/WinWindow.h @@ -3,6 +3,12 @@ #include namespace hgl { + struct WindowCreateExteraParams + { + BOOL bEnableNonClientDpiScaling; + BOOL bChildWindowDpiIsolation; + }; + /** * Windows平台窗口实现 */ @@ -14,6 +20,12 @@ namespace hgl MSG win_msg; + private: + + DPI_AWARENESS_CONTEXT context; + DPI_AWARENESS_CONTEXT previousDpiContext; + DPI_HOSTING_BEHAVIOR previousDpiHostingBehavior; + protected: bool Create();