Skip to content

Commit

Permalink
Message Box Fix 1.5.0: DPI support improvements (#442)
Browse files Browse the repository at this point in the history
* DPI support improvements
  • Loading branch information
aubymori authored Dec 22, 2023
1 parent 955ecfc commit dd8ab13
Showing 1 changed file with 63 additions and 40 deletions.
103 changes: 63 additions & 40 deletions mods/msg-box-font-fix.wh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// @id msg-box-font-fix
// @name Message Box Fix
// @description Fixes the MessageBox font size and background
// @version 1.4.6
// @version 1.5.0
// @author aubymori
// @github https://github.com/aubymori
// @include *
Expand Down Expand Up @@ -34,15 +34,15 @@ This mod fixes both of those things.
*\*Microsoft changed the way the font size was calculator for Per-Monitor V2 DPI awareness. It ALWAYS gets
1pt below the font size, even when on a higher DPI. This is because Microsoft decided to do some weird math
instead of just using `SystemParametersInfoW` like a normal person.*
instead of just using `SystemParametersInfoForDpi` like a normal person.*
*/
// ==/WindhawkModReadme==

// ==WindhawkModSettings==
/*
- font: true
$name: Fix font size
$description: Fix font rendering
$description: Fix the message box font being too small
- background: false
$name: Remove "Window" background
$description: Remove the "Window" color from the background, much like XP and before
Expand All @@ -57,13 +57,17 @@ struct {
} settings;

/* Only available in Windows 10 version 1607 and greater. */
UINT (* WINAPI GetDpiForSystem)(void);
typedef UINT (WINAPI *GetDpiForWindow_t)(HWND);
GetDpiForWindow_t GetDpiForWindow;

typedef BOOL (WINAPI *SystemParametersInfoForDpi_t)(UINT, UINT, PVOID, UINT, UINT);
SystemParametersInfoForDpi_t SystemParametersInfoForDpi;

/* Message box text windows that have been
subclassed for background removal.
See WM_PAINT on MsgBoxTextSubclassProc. */
std::vector<HWND> subclassed;
std::vector<HWND> g_subclassed;

typedef HFONT (__fastcall *GetMessageBoxFontForDpi_t)(UINT);
GetMessageBoxFontForDpi_t GetMessageBoxFontForDpi_orig;
Expand All @@ -81,14 +85,32 @@ HFONT __fastcall GetMessageBoxFontForDpi_hook(
NONCLIENTMETRICSW ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICSW);

SystemParametersInfoW(
SPI_GETNONCLIENTMETRICS,
sizeof(NONCLIENTMETRICSW),
&ncm,
0
);
BOOL bResult;
if (SystemParametersInfoForDpi)
{
bResult = SystemParametersInfoForDpi(
SPI_GETNONCLIENTMETRICS,
sizeof(NONCLIENTMETRICSW),
&ncm,
0,
nDpi
);
}
else
{
bResult = SystemParametersInfoW(
SPI_GETNONCLIENTMETRICS,
sizeof(NONCLIENTMETRICSW),
&ncm,
0
);
}

return CreateFontIndirectW(&(ncm.lfMessageFont));
if (bResult)
{
return CreateFontIndirectW(&ncm.lfMessageFont);
}
return NULL;
}

LRESULT CALLBACK MsgBoxTextSubclassProc(
Expand All @@ -115,27 +137,26 @@ LRESULT CALLBACK MsgBoxTextSubclassProc(
GetClientRect(hWnd, &rcClient);

int len = GetWindowTextLengthW(hWnd) + 1;
LPWSTR szText = (LPWSTR)malloc(sizeof(WCHAR) * len);
LPWSTR szText = new WCHAR[len];
GetWindowTextW(hWnd, szText, len);

HFONT hfMsg;
if (settings.font || !GetDpiForSystem)
if (settings.font || !GetDpiForWindow)
{
hfMsg = GetMessageBoxFontForDpi_hook(
GetDpiForSystem ? GetDpiForSystem() : 96
GetDpiForWindow ? GetDpiForWindow(hWnd) : 96
);
}
else
{
hfMsg = GetMessageBoxFontForDpi_orig(GetDpiForSystem());
hfMsg = GetMessageBoxFontForDpi_orig(GetDpiForWindow(hWnd));
}
HFONT hfOld = (HFONT)SelectObject(hDC, hfMsg);

SetBkMode(hDC, TRANSPARENT);
SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT));

DRAWTEXTPARAMS dtp = { 0 };
dtp.cbSize = sizeof(DRAWTEXTPARAMS);
DRAWTEXTPARAMS dtp = { sizeof(DRAWTEXTPARAMS) };
dtp.uiLengthDrawn = wcslen(szText);

DrawTextExW(
Expand All @@ -149,14 +170,14 @@ LRESULT CALLBACK MsgBoxTextSubclassProc(

SelectObject(hDC, hfOld);
DeleteObject(hfMsg);
free(szText);
delete[] szText;
EndPaint(hWnd, &ps);
return 0;
}
case WM_DESTROY:
subclassed.erase(std::remove_if(
subclassed.begin(),
subclassed.end(),
g_subclassed.erase(std::remove_if(
g_subclassed.begin(),
g_subclassed.end(),
[hWnd](HWND hw)
{
return hw == hWnd;
Expand All @@ -169,9 +190,9 @@ LRESULT CALLBACK MsgBoxTextSubclassProc(
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

typedef INT_PTR (* WINAPI MB_DlgProc_t)(HWND, UINT, WPARAM, LPARAM);
typedef INT_PTR (CALLBACK *MB_DlgProc_t)(HWND, UINT, WPARAM, LPARAM);
MB_DlgProc_t MB_DlgProc_orig;
INT_PTR WINAPI MB_DlgProc_hook(
INT_PTR CALLBACK MB_DlgProc_hook(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
Expand All @@ -185,13 +206,14 @@ INT_PTR WINAPI MB_DlgProc_hook(
case WM_CTLCOLORDLG:
case WM_CTLCOLORSTATIC:
return (INT_PTR)GetSysColorBrush(COLOR_3DFACE);
/* The static window for text itself must handle WM_CTLCOLORSTATIC */
/* The static window used for the text must be subclassed
to completely override painting */
case WM_INITDIALOG:
{
HWND hTxt = GetDlgItem(hWnd, 65535);
HWND hTxt = GetDlgItem(hWnd, 0xFFFF);
if (WindhawkUtils::SetWindowSubclassFromAnyThread(hTxt, MsgBoxTextSubclassProc, NULL))
{
subclassed.push_back(hTxt);
g_subclassed.push_back(hTxt);
}

return MB_DlgProc_orig(hWnd, uMsg, wParam, lParam);
Expand All @@ -209,23 +231,19 @@ INT_PTR WINAPI MB_DlgProc_hook(
return MB_DlgProc_orig(hWnd, uMsg, wParam, lParam);
}

#define LoadIntSetting(NAME) settings.NAME = Wh_GetIntSetting(L ## #NAME)

void LoadSettings(void)
{
settings.font = Wh_GetIntSetting(L"font");
settings.background = Wh_GetIntSetting(L"background");
LoadIntSetting(font);
LoadIntSetting(background);
}

BOOL Wh_ModInit(void)
{
LoadSettings();

HMODULE hUser32 = GetModuleHandleW(L"user32.dll");

if (!hUser32)
{
hUser32 = LoadLibraryW(L"user32.dll");
}

HMODULE hUser32 = LoadLibraryW(L"user32.dll");
if (!hUser32)
{
MessageBoxW(
Expand All @@ -237,7 +255,8 @@ BOOL Wh_ModInit(void)
return FALSE;
}

GetDpiForSystem = (UINT (* WINAPI)(void))GetProcAddress(hUser32, "GetDpiForSystem");
GetDpiForWindow = (GetDpiForWindow_t)GetProcAddress(hUser32, "GetDpiForWindow");
SystemParametersInfoForDpi = (SystemParametersInfoForDpi_t)GetProcAddress(hUser32, "SystemParametersInfoForDpi");

WindhawkUtils::SYMBOL_HOOK hooks[] = {
{
Expand Down Expand Up @@ -268,7 +287,11 @@ BOOL Wh_ModInit(void)
}
};

if (!HookSymbols(hUser32, hooks, ARRAYSIZE(hooks)))
if (!WindhawkUtils::HookSymbols(
hUser32,
hooks,
ARRAYSIZE(hooks)
))
{
Wh_Log(L"Failed to hook one or more symbol functions");
return FALSE;
Expand All @@ -283,11 +306,11 @@ BOOL Wh_ModInit(void)
*/
void Wh_ModUninit(void)
{
size_t len = subclassed.size();
size_t len = g_subclassed.size();
for (size_t i = 0; i < len; i++)
{
WindhawkUtils::RemoveWindowSubclassFromAnyThread(
subclassed[i],
g_subclassed[i],
MsgBoxTextSubclassProc
);
}
Expand Down

0 comments on commit dd8ab13

Please sign in to comment.