From 2dabb2d723752b9bd9f91e8bf182544690ad2ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=A2=A6=E5=A9=89?= Date: Thu, 27 Aug 2026 18:17:51 +0800 Subject: [PATCH] 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 --- src/LanguageBar/LanguageBar.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/LanguageBar/LanguageBar.cpp b/src/LanguageBar/LanguageBar.cpp index 8e3b5a0f..110e477a 100644 --- a/src/LanguageBar/LanguageBar.cpp +++ b/src/LanguageBar/LanguageBar.cpp @@ -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( - 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(GetProcAddress(shcore, "GetDpiForMonitor")) : nullptr; + }(); if (mon && fnGetDpiForMonitor && SUCCEEDED(fnGetDpiForMonitor(mon, 0 /* MDT_EFFECTIVE_DPI */, &dpiX, &dpiY)) && dpiX > 0) {