Lazily load shcore.dll for the effective-DPI query

Processes that never loaded shcore.dll would silently fall back to SM_CXSMICON and keep the old sizing. Resolve the entry point via GetModuleHandleW first, with LoadLibraryW as a fallback, so the monitor-DPI query works in every host.

Refs #50
This commit is contained in:
柳梦婉 committed 2026-08-27 18:17:51 +08:00
1 parent 50eb0b4b43
commit 2dabb2d723
1 file changed
+13 -2
+13 -2
View File
@@ -538,8 +538,19 @@ STDAPI CLangBarItemButton::GetIcon(_Out_ HICON *phIcon)
HMONITOR mon = MonitorFromPoint({0, 0}, MONITOR_DEFAULTTOPRIMARY);
UINT dpiX = 0, dpiY = 0;
using GetDpiForMonitorFn = HRESULT(WINAPI *)(HMONITOR, int, UINT *, UINT *);
static const auto fnGetDpiForMonitor = reinterpret_cast<GetDpiForMonitorFn>(
GetProcAddress(GetModuleHandleW(L"shcore.dll"), "GetDpiForMonitor"));
// shcore.dll ships with Windows 8.1+ and is usually already loaded by the
// host; resolve it on demand so processes that never touched DPI APIs
// still get the real slot size instead of dropping to SM_CXSMICON.
static const auto fnGetDpiForMonitor =
[]() -> GetDpiForMonitorFn
{
HMODULE shcore = GetModuleHandleW(L"shcore.dll");
if (!shcore)
{
shcore = LoadLibraryW(L"shcore.dll"); // system DLL; freed at process exit
}
return shcore ? reinterpret_cast<GetDpiForMonitorFn>(GetProcAddress(shcore, "GetDpiForMonitor")) : nullptr;
}();
if (mon && fnGetDpiForMonitor &&
SUCCEEDED(fnGetDpiForMonitor(mon, 0 /* MDT_EFFECTIVE_DPI */, &dpiX, &dpiY)) && dpiX > 0)
{