aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2020-07-07 14:04:39 +1000
committerSean Hall <r.sean.hall@gmail.com>2020-07-10 21:40:29 +1000
commitf651268309263fa67fa84caf9fb6dbebb5c900d9 (patch)
treedd65a9c20bbc417e0123782fc1a22efd76a0db2e
parent171b886bc5652da63b5ed549c755aa3fa3337eab (diff)
downloadwix-f651268309263fa67fa84caf9fb6dbebb5c900d9.tar.gz
wix-f651268309263fa67fa84caf9fb6dbebb5c900d9.tar.bz2
wix-f651268309263fa67fa84caf9fb6dbebb5c900d9.zip
Add DpiuSetProcessDpiAwareness.
-rw-r--r--src/dutil/dpiutil.cpp78
-rw-r--r--src/dutil/inc/dpiutil.h26
2 files changed, 104 insertions, 0 deletions
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 @@
18static PFN_ADJUSTWINDOWRECTEXFORDPI vpfnAdjustWindowRectExForDpi = NULL; 18static PFN_ADJUSTWINDOWRECTEXFORDPI vpfnAdjustWindowRectExForDpi = NULL;
19static PFN_GETDPIFORMONITOR vpfnGetDpiForMonitor = NULL; 19static PFN_GETDPIFORMONITOR vpfnGetDpiForMonitor = NULL;
20static PFN_GETDPIFORWINDOW vpfnGetDpiForWindow = NULL; 20static PFN_GETDPIFORWINDOW vpfnGetDpiForWindow = NULL;
21static PFN_SETPROCESSDPIAWARE vpfnSetProcessDPIAware = NULL;
22static PFN_SETPROCESSDPIAWARENESS vpfnSetProcessDpiAwareness = NULL;
23static PFN_SETPROCESSDPIAWARENESSCONTEXT vpfnSetProcessDpiAwarenessContext = NULL;
21 24
22static HMODULE vhShcoreDll = NULL; 25static HMODULE vhShcoreDll = NULL;
23static HMODULE vhUser32Dll = NULL; 26static HMODULE vhUser32Dll = NULL;
@@ -32,6 +35,7 @@ DAPI_(void) DpiuInitialize()
32 { 35 {
33 // Ignore failures. 36 // Ignore failures.
34 vpfnGetDpiForMonitor = reinterpret_cast<PFN_GETDPIFORMONITOR>(::GetProcAddress(vhShcoreDll, "GetDpiForMonitor")); 37 vpfnGetDpiForMonitor = reinterpret_cast<PFN_GETDPIFORMONITOR>(::GetProcAddress(vhShcoreDll, "GetDpiForMonitor"));
38 vpfnSetProcessDpiAwareness = reinterpret_cast<PFN_SETPROCESSDPIAWARENESS>(::GetProcAddress(vhShcoreDll, "SetProcessDpiAwareness"));
35 } 39 }
36 40
37 hr = LoadSystemLibrary(L"User32.dll", &vhUser32Dll); 41 hr = LoadSystemLibrary(L"User32.dll", &vhUser32Dll);
@@ -40,6 +44,8 @@ DAPI_(void) DpiuInitialize()
40 // Ignore failures. 44 // Ignore failures.
41 vpfnAdjustWindowRectExForDpi = reinterpret_cast<PFN_ADJUSTWINDOWRECTEXFORDPI>(::GetProcAddress(vhUser32Dll, "AdjustWindowRectExForDpi")); 45 vpfnAdjustWindowRectExForDpi = reinterpret_cast<PFN_ADJUSTWINDOWRECTEXFORDPI>(::GetProcAddress(vhUser32Dll, "AdjustWindowRectExForDpi"));
42 vpfnGetDpiForWindow = reinterpret_cast<PFN_GETDPIFORWINDOW>(::GetProcAddress(vhUser32Dll, "GetDpiForWindow")); 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"));
43 } 49 }
44 50
45 vfDpiuInitialized = TRUE; 51 vfDpiuInitialized = TRUE;
@@ -194,3 +200,75 @@ DAPI_(int) DpiuScaleValue(
194{ 200{
195 return ::MulDiv(nDefaultDpiValue, nTargetDpi, USER_DEFAULT_SCREEN_DPI); 201 return ::MulDiv(nDefaultDpiValue, nTargetDpi, USER_DEFAULT_SCREEN_DPI);
196} 202}
203
204DAPI_(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
267LExit:
268 if (pSelectedAwareness)
269 {
270 *pSelectedAwareness = selectedAwareness;
271 }
272
273 return hr;
274}
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" {
14#define USER_DEFAULT_SCREEN_DPI 96 14#define USER_DEFAULT_SCREEN_DPI 96
15#endif 15#endif
16 16
17typedef 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
17typedef struct _DPIU_MONITOR_CONTEXT 26typedef struct _DPIU_MONITOR_CONTEXT
18{ 27{
19 UINT nDpi; 28 UINT nDpi;
@@ -41,6 +50,13 @@ typedef HRESULT (APIENTRY *PFN_GETDPIFORMONITOR)(
41typedef UINT (APIENTRY *PFN_GETDPIFORWINDOW)( 50typedef UINT (APIENTRY *PFN_GETDPIFORWINDOW)(
42 __in HWND hwnd 51 __in HWND hwnd
43 ); 52 );
53typedef BOOL (APIENTRY* PFN_SETPROCESSDPIAWARE)();
54typedef HRESULT (APIENTRY* PFN_SETPROCESSDPIAWARENESS)(
55 __in PROCESS_DPI_AWARENESS value
56 );
57typedef BOOL (APIENTRY* PFN_SETPROCESSDPIAWARENESSCONTEXT)(
58 __in DPI_AWARENESS_CONTEXT value
59 );
44 60
45void DAPI DpiuInitialize(); 61void DAPI DpiuInitialize();
46void DAPI DpiuUninitialize(); 62void DAPI DpiuUninitialize();
@@ -86,6 +102,16 @@ int DAPI DpiuScaleValue(
86 __in UINT nTargetDpi 102 __in UINT nTargetDpi
87 ); 103 );
88 104
105/********************************************************************
106 DpiuSetProcessDpiAwareness - set the process DPI awareness. The ranking is
107 PERMONITORV2 > PERMONITOR > SYSTEM > GDISCALED > NONE.
108
109*******************************************************************/
110HRESULT DAPI DpiuSetProcessDpiAwareness(
111 __in DPIU_AWARENESS supportedAwareness,
112 __in_opt DPIU_AWARENESS* pSelectedAwareness
113 );
114
89#ifdef __cplusplus 115#ifdef __cplusplus
90} 116}
91#endif 117#endif