@joebigelow / wix-1 / commits / f6512683

Add DpiuSetProcessDpiAwareness.

Sean Hall committed Jul 7, 2020 at 14:04 UTC f651268309263fa67fa84caf9fb6dbebb5c900d9
2 files changed +104
src/dutil/dpiutil.cpp
+78
@@ -18,6 +18,9 @@
18 static PFN_ADJUSTWINDOWRECTEXFORDPI vpfnAdjustWindowRectExForDpi = NULL;
19 static PFN_GETDPIFORMONITOR vpfnGetDpiForMonitor = NULL;
20 static PFN_GETDPIFORWINDOW vpfnGetDpiForWindow = NULL;
21 +static PFN_SETPROCESSDPIAWARE vpfnSetProcessDPIAware = NULL;
22 +static PFN_SETPROCESSDPIAWARENESS vpfnSetProcessDpiAwareness = NULL;
23 +static PFN_SETPROCESSDPIAWARENESSCONTEXT vpfnSetProcessDpiAwarenessContext = NULL;
24
25 static HMODULE vhShcoreDll = NULL;
26 static HMODULE vhUser32Dll = NULL;
@@ -32,6 +35,7 @@ DAPI_(void) DpiuInitialize()
35 {
36 // Ignore failures.
37 vpfnGetDpiForMonitor = reinterpret_cast<PFN_GETDPIFORMONITOR>(::GetProcAddress(vhShcoreDll, "GetDpiForMonitor"));
38 + vpfnSetProcessDpiAwareness = reinterpret_cast<PFN_SETPROCESSDPIAWARENESS>(::GetProcAddress(vhShcoreDll, "SetProcessDpiAwareness"));
39 }
40
41 hr = LoadSystemLibrary(L"User32.dll", &vhUser32Dll);
@@ -40,6 +44,8 @@ DAPI_(void) DpiuInitialize()
44 // Ignore failures.
45 vpfnAdjustWindowRectExForDpi = reinterpret_cast<PFN_ADJUSTWINDOWRECTEXFORDPI>(::GetProcAddress(vhUser32Dll, "AdjustWindowRectExForDpi"));
46 vpfnGetDpiForWindow = reinterpret_cast<PFN_GETDPIFORWINDOW>(::GetProcAddress(vhUser32Dll, "GetDpiForWindow"));
47 + vpfnSetProcessDPIAware = reinterpret_cast<PFN_SETPROCESSDPIAWARE>(::GetProcAddress(vhUser32Dll, "SetProcessDPIAware"));
48 + vpfnSetProcessDpiAwarenessContext = reinterpret_cast<PFN_SETPROCESSDPIAWARENESSCONTEXT>(::GetProcAddress(vhUser32Dll, "SetProcessDpiAwarenessContext"));
49 }
50
51 vfDpiuInitialized = TRUE;
@@ -194,3 +200,75 @@ DAPI_(int) DpiuScaleValue(
200 {
201 return ::MulDiv(nDefaultDpiValue, nTargetDpi, USER_DEFAULT_SCREEN_DPI);
202 }
203 +
204 +DAPI_(HRESULT) DpiuSetProcessDpiAwareness(
205 + __in DPIU_AWARENESS supportedAwareness,
206 + __in_opt DPIU_AWARENESS* pSelectedAwareness
207 + )
208 +{
209 + HRESULT hr = S_OK;
210 + DPIU_AWARENESS selectedAwareness = DPIU_AWARENESS_NONE;
211 + DPI_AWARENESS_CONTEXT awarenessContext = DPI_AWARENESS_CONTEXT_UNAWARE;
212 + PROCESS_DPI_AWARENESS awareness = PROCESS_DPI_UNAWARE;
213 +
214 + if (vpfnSetProcessDpiAwarenessContext)
215 + {
216 + if (DPIU_AWARENESS_PERMONITORV2 & supportedAwareness)
217 + {
218 + awarenessContext = DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2;
219 + selectedAwareness = DPIU_AWARENESS_PERMONITORV2;
220 + }
221 + else if (DPIU_AWARENESS_PERMONITOR & supportedAwareness)
222 + {
223 + awarenessContext = DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE;
224 + selectedAwareness = DPIU_AWARENESS_PERMONITOR;
225 + }
226 + else if (DPIU_AWARENESS_SYSTEM & supportedAwareness)
227 + {
228 + awarenessContext = DPI_AWARENESS_CONTEXT_SYSTEM_AWARE;
229 + selectedAwareness = DPIU_AWARENESS_SYSTEM;
230 + }
231 + else if (DPIU_AWARENESS_GDISCALED & supportedAwareness)
232 + {
233 + awarenessContext = DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED;
234 + selectedAwareness = DPIU_AWARENESS_GDISCALED;
235 + }
236 +
237 + if (!vpfnSetProcessDpiAwarenessContext(awarenessContext))
238 + {
239 + DpiuExitOnLastError(hr, "Failed to set process DPI awareness context.");
240 + }
241 + }
242 + else if (vpfnSetProcessDpiAwareness)
243 + {
244 + if (DPIU_AWARENESS_PERMONITOR & supportedAwareness)
245 + {
246 + awareness = PROCESS_PER_MONITOR_DPI_AWARE;
247 + selectedAwareness = DPIU_AWARENESS_PERMONITOR;
248 + }
249 + else if (DPIU_AWARENESS_SYSTEM & supportedAwareness)
250 + {
251 + awareness = PROCESS_SYSTEM_DPI_AWARE;
252 + selectedAwareness = DPIU_AWARENESS_SYSTEM;
253 + }
254 +
255 + hr = vpfnSetProcessDpiAwareness(awareness);
256 + DpiuExitOnFailure(hr, "Failed to set process DPI awareness.");
257 + }
258 + else if (vpfnSetProcessDPIAware && (DPIU_AWARENESS_SYSTEM & supportedAwareness))
259 + {
260 + selectedAwareness = DPIU_AWARENESS_SYSTEM;
261 + if (!vpfnSetProcessDPIAware())
262 + {
263 + DpiuExitOnLastError(hr, "Failed to set process DPI aware.");
264 + }
265 + }
266 +
267 +LExit:
268 + if (pSelectedAwareness)
269 + {
270 + *pSelectedAwareness = selectedAwareness;
271 + }
272 +
273 + return hr;
274 +}
src/dutil/inc/dpiutil.h
+26
@@ -14,6 +14,15 @@ extern "C" {
14 #define USER_DEFAULT_SCREEN_DPI 96
15 #endif
16
17 +typedef enum DPIU_AWARENESS
18 +{
19 + DPIU_AWARENESS_NONE = 0x0,
20 + DPIU_AWARENESS_SYSTEM = 0x1,
21 + DPIU_AWARENESS_PERMONITOR = 0x2,
22 + DPIU_AWARENESS_PERMONITORV2 = 0x4,
23 + DPIU_AWARENESS_GDISCALED = 0x8,
24 +} DPIU_PROCESS_AWARENESS;
25 +
26 typedef struct _DPIU_MONITOR_CONTEXT
27 {
28 UINT nDpi;
@@ -41,6 +50,13 @@ typedef HRESULT (APIENTRY *PFN_GETDPIFORMONITOR)(
50 typedef UINT (APIENTRY *PFN_GETDPIFORWINDOW)(
51 __in HWND hwnd
52 );
53 +typedef BOOL (APIENTRY* PFN_SETPROCESSDPIAWARE)();
54 +typedef HRESULT (APIENTRY* PFN_SETPROCESSDPIAWARENESS)(
55 + __in PROCESS_DPI_AWARENESS value
56 + );
57 +typedef BOOL (APIENTRY* PFN_SETPROCESSDPIAWARENESSCONTEXT)(
58 + __in DPI_AWARENESS_CONTEXT value
59 + );
60
61 void DAPI DpiuInitialize();
62 void DAPI DpiuUninitialize();
@@ -86,6 +102,16 @@ int DAPI DpiuScaleValue(
102 __in UINT nTargetDpi
103 );
104
105 +/********************************************************************
106 + DpiuSetProcessDpiAwareness - set the process DPI awareness. The ranking is
107 + PERMONITORV2 > PERMONITOR > SYSTEM > GDISCALED > NONE.
108 +
109 +*******************************************************************/
110 +HRESULT DAPI DpiuSetProcessDpiAwareness(
111 + __in DPIU_AWARENESS supportedAwareness,
112 + __in_opt DPIU_AWARENESS* pSelectedAwareness
113 + );
114 +
115 #ifdef __cplusplus
116 }
117 #endif