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