Skip to content

Instantly share code, notes, and snippets.

@Jimbly
Created June 4, 2024 02:31
Show Gist options
  • Save Jimbly/2b9352a6df06f00d9b48b82927735ff0 to your computer and use it in GitHub Desktop.
Save Jimbly/2b9352a6df06f00d9b48b82927735ff0 to your computer and use it in GitHub Desktop.
setHighDPIAware()
#ifndef DPI_ENUMS_DECLARED
typedef enum PROCESS_DPI_AWARENESS {
PROCESS_DPI_UNAWARE = 0,
PROCESS_SYSTEM_DPI_AWARE = 1,
PROCESS_PER_MONITOR_DPI_AWARE = 2
} PROCESS_DPI_AWARENESS;
#ifndef _DPI_AWARENESS_CONTEXTS_
typedef enum DPI_AWARENESS_CONTEXT {
DPI_AWARENESS_INVALID,
DPI_AWARENESS_UNAWARE,
DPI_AWARENESS_SYSTEM_AWARE,
DPI_AWARENESS_PER_MONITOR_AWARE
} DPI_AWARENESS_CONTEXT;
#endif
#define DPI_AWARENESS_CONTEXT_UNAWARE ((DPI_AWARENESS_CONTEXT)-1)
#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT)-2)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT)-3)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4)
#define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT)-5)
#define DPI_ENUMS_DECLARED
#endif // (DPI_ENUMS_DECLARED)
typedef WINUSERAPI BOOL(WINAPI *pSetProcessDpiAwareness)(PROCESS_DPI_AWARENESS value);
typedef WINUSERAPI BOOL(WINAPI *pSetProcessDPIAware)();
typedef WINUSERAPI BOOL(WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT value);
typedef WINUSERAPI BOOL(WINAPI *pSetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT value);
bool setHighDPIAwareWin10()
{
// This fixes the issue where if you change the OS DPI scale while logged in, the title
// bar is the wrong size.
HMODULE lib = LoadLibrary("User32.dll");
if (!lib) {
return false;
}
bool ret = false;
// Try Win10 build 1703+ method
pSetProcessDpiAwarenessContext pfnSetProc = (pSetProcessDpiAwarenessContext)GetProcAddress(lib, "SetProcessDpiAwarenessContext");
if (pfnSetProc) {
ret = (NULL != pfnSetProc(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2));
// printf("Win10 1703 HighDPI SetProcessDpiAwarenessContext() success=%d\n", ret);
}
if (!ret) {
// Try Win10 build 1607+ method
// Older method, has problems on buggy NVIDIA drivers
pSetThreadDpiAwarenessContext pfnSet = (pSetThreadDpiAwarenessContext)GetProcAddress(lib, "SetThreadDpiAwarenessContext");
if (pfnSet) {
ret = (NULL != pfnSet(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2));
// printf("Win10 1607 HighDPI SetThreadDpiAwarenessContext() success=%d\n", ret);
}
}
FreeLibrary(lib);
return ret;
}
static bool setHighDPIAwareWin81()
{
HMODULE shcore = LoadLibrary("Shcore.dll");
if (!shcore) {
printf("Shcore.dll failed to load\n");
return false;
}
pSetProcessDpiAwareness pfnSetProcessDpiAwareness = (pSetProcessDpiAwareness)GetProcAddress(shcore, "SetProcessDpiAwareness");
bool ret = false;
if (pfnSetProcessDpiAwareness) {
// Note: on Win8, this is returning a bool, not an hresult, to this check is backwards?
ret = (S_OK == pfnSetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE));
// printf("Win81 HighDPI SetProcessDpiAwareness() success=%d\n", ret);
}
FreeLibrary(shcore);
return ret;
}
void setHighDPIAware()
{
static bool doneonce = false;
if (doneonce)
return;
doneonce = true;
if (setHighDPIAwareWin10()) {
return;
}
if (setHighDPIAwareWin81()) {
return;
}
HMODULE user32 = LoadLibrary("user32.dll");
if (!user32)
return;
pSetProcessDPIAware pfnSetProcessDPIAware = (pSetProcessDPIAware)GetProcAddress(user32, "SetProcessDPIAware");
bool ret = false;
if (pfnSetProcessDPIAware) {
ret = !!pfnSetProcessDPIAware();
// printf("HighDPI SetProcessDPIAware() success=%d\n", ret);
}
FreeLibrary(user32);
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment