From f651268309263fa67fa84caf9fb6dbebb5c900d9 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Tue, 7 Jul 2020 14:04:39 +1000 Subject: Add DpiuSetProcessDpiAwareness. --- src/dutil/dpiutil.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ src/dutil/inc/dpiutil.h | 26 +++++++++++++++++ 2 files changed, 104 insertions(+) (limited to 'src') diff --git a/src/dutil/dpiutil.cpp b/src/dutil/dpiutil.cpp index 02a9580c..4096c8d3 100644 --- a/src/dutil/dpiutil.cpp +++ b/src/dutil/dpiutil.cpp @@ -18,6 +18,9 @@ static PFN_ADJUSTWINDOWRECTEXFORDPI vpfnAdjustWindowRectExForDpi = NULL; static PFN_GETDPIFORMONITOR vpfnGetDpiForMonitor = NULL; static PFN_GETDPIFORWINDOW vpfnGetDpiForWindow = NULL; +static PFN_SETPROCESSDPIAWARE vpfnSetProcessDPIAware = NULL; +static PFN_SETPROCESSDPIAWARENESS vpfnSetProcessDpiAwareness = NULL; +static PFN_SETPROCESSDPIAWARENESSCONTEXT vpfnSetProcessDpiAwarenessContext = NULL; static HMODULE vhShcoreDll = NULL; static HMODULE vhUser32Dll = NULL; @@ -32,6 +35,7 @@ DAPI_(void) DpiuInitialize() { // Ignore failures. vpfnGetDpiForMonitor = reinterpret_cast(::GetProcAddress(vhShcoreDll, "GetDpiForMonitor")); + vpfnSetProcessDpiAwareness = reinterpret_cast(::GetProcAddress(vhShcoreDll, "SetProcessDpiAwareness")); } hr = LoadSystemLibrary(L"User32.dll", &vhUser32Dll); @@ -40,6 +44,8 @@ DAPI_(void) DpiuInitialize() // Ignore failures. vpfnAdjustWindowRectExForDpi = reinterpret_cast(::GetProcAddress(vhUser32Dll, "AdjustWindowRectExForDpi")); vpfnGetDpiForWindow = reinterpret_cast(::GetProcAddress(vhUser32Dll, "GetDpiForWindow")); + vpfnSetProcessDPIAware = reinterpret_cast(::GetProcAddress(vhUser32Dll, "SetProcessDPIAware")); + vpfnSetProcessDpiAwarenessContext = reinterpret_cast(::GetProcAddress(vhUser32Dll, "SetProcessDpiAwarenessContext")); } vfDpiuInitialized = TRUE; @@ -194,3 +200,75 @@ DAPI_(int) DpiuScaleValue( { return ::MulDiv(nDefaultDpiValue, nTargetDpi, USER_DEFAULT_SCREEN_DPI); } + +DAPI_(HRESULT) DpiuSetProcessDpiAwareness( + __in DPIU_AWARENESS supportedAwareness, + __in_opt DPIU_AWARENESS* pSelectedAwareness + ) +{ + HRESULT hr = S_OK; + DPIU_AWARENESS selectedAwareness = DPIU_AWARENESS_NONE; + DPI_AWARENESS_CONTEXT awarenessContext = DPI_AWARENESS_CONTEXT_UNAWARE; + PROCESS_DPI_AWARENESS awareness = PROCESS_DPI_UNAWARE; + + if (vpfnSetProcessDpiAwarenessContext) + { + if (DPIU_AWARENESS_PERMONITORV2 & supportedAwareness) + { + awarenessContext = DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2; + selectedAwareness = DPIU_AWARENESS_PERMONITORV2; + } + else if (DPIU_AWARENESS_PERMONITOR & supportedAwareness) + { + awarenessContext = DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE; + selectedAwareness = DPIU_AWARENESS_PERMONITOR; + } + else if (DPIU_AWARENESS_SYSTEM & supportedAwareness) + { + awarenessContext = DPI_AWARENESS_CONTEXT_SYSTEM_AWARE; + selectedAwareness = DPIU_AWARENESS_SYSTEM; + } + else if (DPIU_AWARENESS_GDISCALED & supportedAwareness) + { + awarenessContext = DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED; + selectedAwareness = DPIU_AWARENESS_GDISCALED; + } + + if (!vpfnSetProcessDpiAwarenessContext(awarenessContext)) + { + DpiuExitOnLastError(hr, "Failed to set process DPI awareness context."); + } + } + else if (vpfnSetProcessDpiAwareness) + { + if (DPIU_AWARENESS_PERMONITOR & supportedAwareness) + { + awareness = PROCESS_PER_MONITOR_DPI_AWARE; + selectedAwareness = DPIU_AWARENESS_PERMONITOR; + } + else if (DPIU_AWARENESS_SYSTEM & supportedAwareness) + { + awareness = PROCESS_SYSTEM_DPI_AWARE; + selectedAwareness = DPIU_AWARENESS_SYSTEM; + } + + hr = vpfnSetProcessDpiAwareness(awareness); + DpiuExitOnFailure(hr, "Failed to set process DPI awareness."); + } + else if (vpfnSetProcessDPIAware && (DPIU_AWARENESS_SYSTEM & supportedAwareness)) + { + selectedAwareness = DPIU_AWARENESS_SYSTEM; + if (!vpfnSetProcessDPIAware()) + { + DpiuExitOnLastError(hr, "Failed to set process DPI aware."); + } + } + +LExit: + if (pSelectedAwareness) + { + *pSelectedAwareness = selectedAwareness; + } + + return hr; +} diff --git a/src/dutil/inc/dpiutil.h b/src/dutil/inc/dpiutil.h index 4ea689c5..216d3dc6 100644 --- a/src/dutil/inc/dpiutil.h +++ b/src/dutil/inc/dpiutil.h @@ -14,6 +14,15 @@ extern "C" { #define USER_DEFAULT_SCREEN_DPI 96 #endif +typedef enum DPIU_AWARENESS +{ + DPIU_AWARENESS_NONE = 0x0, + DPIU_AWARENESS_SYSTEM = 0x1, + DPIU_AWARENESS_PERMONITOR = 0x2, + DPIU_AWARENESS_PERMONITORV2 = 0x4, + DPIU_AWARENESS_GDISCALED = 0x8, +} DPIU_PROCESS_AWARENESS; + typedef struct _DPIU_MONITOR_CONTEXT { UINT nDpi; @@ -41,6 +50,13 @@ typedef HRESULT (APIENTRY *PFN_GETDPIFORMONITOR)( typedef UINT (APIENTRY *PFN_GETDPIFORWINDOW)( __in HWND hwnd ); +typedef BOOL (APIENTRY* PFN_SETPROCESSDPIAWARE)(); +typedef HRESULT (APIENTRY* PFN_SETPROCESSDPIAWARENESS)( + __in PROCESS_DPI_AWARENESS value + ); +typedef BOOL (APIENTRY* PFN_SETPROCESSDPIAWARENESSCONTEXT)( + __in DPI_AWARENESS_CONTEXT value + ); void DAPI DpiuInitialize(); void DAPI DpiuUninitialize(); @@ -86,6 +102,16 @@ int DAPI DpiuScaleValue( __in UINT nTargetDpi ); +/******************************************************************** + DpiuSetProcessDpiAwareness - set the process DPI awareness. The ranking is + PERMONITORV2 > PERMONITOR > SYSTEM > GDISCALED > NONE. + +*******************************************************************/ +HRESULT DAPI DpiuSetProcessDpiAwareness( + __in DPIU_AWARENESS supportedAwareness, + __in_opt DPIU_AWARENESS* pSelectedAwareness + ); + #ifdef __cplusplus } #endif -- cgit v1.2.3-55-g6feb