supported High-DPI

This commit is contained in:
hyzboy 2021-12-28 15:45:44 +08:00
parent c1a4276533
commit bb671a9674
3 changed files with 92 additions and 1 deletions

View File

@ -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<const CREATESTRUCTW *>(lParam);
auto createParams = static_cast<const WindowCreateExteraParams *>(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);

View File

@ -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);

View File

@ -3,6 +3,12 @@
#include<Windows.h>
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();