diff options
-rw-r--r-- | doc/ScintillaHistory.html | 5 | ||||
-rw-r--r-- | win32/PlatWin.cxx | 23 | ||||
-rw-r--r-- | win32/PlatWin.h | 2 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 3 |
4 files changed, 32 insertions, 1 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 5df65cad7..467b3a492 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -597,6 +597,11 @@ triggering insertion because of SCI_AUTOCSETCHOOSESINGLE mode. <a href="https://sourceforge.net/p/scintilla/feature-requests/1459/">Feature #1459</a>. </li> + <li> + On Win32, use the top-level window to find the monitor for DirectWrite rendering parameters. + Temporarily switch DPI awareness to find correct monitor in GDI scaling mode. + <a href="https://sourceforge.net/p/scintilla/bugs/2344/">Bug #2344</a>. + </li> </ul> <h3> <a href="https://www.scintilla.org/scintilla531.zip">Release 5.3.1</a> diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index bb808b4e7..c97b9283b 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -157,11 +157,15 @@ GetSystemMetricsForDpiSig fnGetSystemMetricsForDpi = nullptr; using AdjustWindowRectExForDpiSig = BOOL(WINAPI *)(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi); AdjustWindowRectExForDpiSig fnAdjustWindowRectExForDpi = nullptr; +using SetThreadDpiAwarenessContextSig = DPI_AWARENESS_CONTEXT(WINAPI *)(DPI_AWARENESS_CONTEXT); +SetThreadDpiAwarenessContextSig fnSetThreadDpiAwarenessContext = nullptr; + void LoadDpiForWindow() noexcept { HMODULE user32 = ::GetModuleHandleW(L"user32.dll"); fnGetDpiForWindow = DLLFunction<GetDpiForWindowSig>(user32, "GetDpiForWindow"); fnGetSystemMetricsForDpi = DLLFunction<GetSystemMetricsForDpiSig>(user32, "GetSystemMetricsForDpi"); fnAdjustWindowRectExForDpi = DLLFunction<AdjustWindowRectExForDpiSig>(user32, "AdjustWindowRectExForDpi"); + fnSetThreadDpiAwarenessContext = DLLFunction<SetThreadDpiAwarenessContextSig>(user32, "SetThreadDpiAwarenessContext"); using GetDpiForSystemSig = UINT(WINAPI *)(void); GetDpiForSystemSig fnGetDpiForSystem = DLLFunction<GetDpiForSystemSig>(user32, "GetDpiForSystem"); @@ -358,6 +362,25 @@ struct FontDirectWrite : public FontWin { } +HMONITOR MonitorFromWindow(HWND hWnd) noexcept { + constexpr DWORD monitorFlags = MONITOR_DEFAULTTONEAREST; + + if (!fnSetThreadDpiAwarenessContext) { + return ::MonitorFromWindow(hWnd, monitorFlags); + } + + // Temporarily switching to PerMonitorV2 to retrieve correct monitor via MonitorFromRect() in case of active GDI scaling. + const DPI_AWARENESS_CONTEXT oldContext = fnSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + PLATFORM_ASSERT(oldContext != nullptr); + + RECT rect; + ::GetWindowRect(hWnd, &rect); + const HMONITOR monitor = ::MonitorFromRect(&rect, monitorFlags); + + fnSetThreadDpiAwarenessContext(oldContext); + return monitor; +} + std::shared_ptr<Font> Font::Allocate(const FontParameters &fp) { #if defined(USE_D2D) if (fp.technology != Technology::Default) { diff --git a/win32/PlatWin.h b/win32/PlatWin.h index 68098f9c7..8261aeb2d 100644 --- a/win32/PlatWin.h +++ b/win32/PlatWin.h @@ -43,6 +43,8 @@ inline HWND HwndFromWindow(const Window &w) noexcept { void *PointerFromWindow(HWND hWnd) noexcept; void SetWindowPointer(HWND hWnd, void *ptr) noexcept; +HMONITOR MonitorFromWindow(HWND hWnd) noexcept; + UINT DpiForWindow(WindowID wid) noexcept; int SystemMetricsForDpi(int nIndex, UINT dpi) noexcept; diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index c405ed8d1..d3c1b87a5 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -603,7 +603,8 @@ bool ScintillaWin::UpdateRenderingParams(bool force) noexcept { return false; } } - HMONITOR monitor = ::MonitorFromWindow(MainHWND(), MONITOR_DEFAULTTONEAREST); + const HWND hRootWnd = ::GetAncestor(MainHWND(), GA_ROOT); + const HMONITOR monitor = Internal::MonitorFromWindow(hRootWnd); if (!force && monitor == hCurrentMonitor && renderingParams->defaultRenderingParams) { return false; } |