diff options
Diffstat (limited to 'win32')
-rw-r--r-- | win32/PlatWin.cxx | 59 | ||||
-rw-r--r-- | win32/PlatWin.h | 2 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 21 |
3 files changed, 61 insertions, 21 deletions
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index f09cdfcf1..d4d7b8026 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -243,6 +243,14 @@ void SetWindowPointer(HWND hWnd, void *ptr) noexcept { namespace { +using GetDpiForWindowSig = UINT(WINAPI *)(HWND hwnd); +GetDpiForWindowSig fnGetDpiForWindow = nullptr; + +void LoadDpiForWindow() noexcept { + HMODULE user32 = ::GetModuleHandleW(L"user32.dll"); + fnGetDpiForWindow = DLLFunction<GetDpiForWindowSig>(user32, "GetDpiForWindow"); +} + HINSTANCE hinstPlatformRes {}; HCURSOR reverseArrowCursor {}; @@ -415,6 +423,16 @@ public: }; typedef VarBuffer<XYPOSITION, stackBufferLength> TextPositions; +UINT DpiForWindow(WindowID wid) noexcept { + if (fnGetDpiForWindow) { + return fnGetDpiForWindow(HwndFromWindowID(wid)); + } + HDC hdcMeasure = ::CreateCompatibleDC({}); + const UINT scale = ::GetDeviceCaps(hdcMeasure, LOGPIXELSY); + ::DeleteDC(hdcMeasure); + return scale; +} + class SurfaceGDI : public Surface { bool unicodeMode=false; HDC hdc{}; @@ -426,6 +444,9 @@ class SurfaceGDI : public Surface { HFONT fontOld{}; HBITMAP bitmap{}; HBITMAP bitmapOld{}; + + int logPixelsY = 72; + int maxWidthMeasure = INT_MAX; // There appears to be a 16 bit string length limit in GDI on NT. int maxLenText = 65535; @@ -537,20 +558,22 @@ bool SurfaceGDI::Initialised() { return hdc != 0; } -void SurfaceGDI::Init(WindowID) { +void SurfaceGDI::Init(WindowID wid) { Release(); hdc = ::CreateCompatibleDC({}); hdcOwned = true; ::SetTextAlign(hdc, TA_BASELINE); + logPixelsY = DpiForWindow(wid); } -void SurfaceGDI::Init(SurfaceID sid, WindowID) { +void SurfaceGDI::Init(SurfaceID sid, WindowID wid) { Release(); hdc = static_cast<HDC>(sid); ::SetTextAlign(hdc, TA_BASELINE); + logPixelsY = DpiForWindow(wid); } -void SurfaceGDI::InitPixMap(int width, int height, Surface *surface_, WindowID) { +void SurfaceGDI::InitPixMap(int width, int height, Surface *surface_, WindowID wid) { Release(); SurfaceGDI *psurfOther = dynamic_cast<SurfaceGDI *>(surface_); // Should only ever be called with a SurfaceGDI, not a SurfaceD2D @@ -562,6 +585,7 @@ void SurfaceGDI::InitPixMap(int width, int height, Surface *surface_, WindowID) ::SetTextAlign(hdc, TA_BASELINE); SetUnicodeMode(psurfOther->unicodeMode); SetDBCSMode(psurfOther->codePage); + logPixelsY = DpiForWindow(wid); } void SurfaceGDI::PenColour(ColourDesired fore) { @@ -599,7 +623,7 @@ void SurfaceGDI::SetFont(const Font &font_) noexcept { } int SurfaceGDI::LogPixelsY() { - return ::GetDeviceCaps(hdc, LOGPIXELSY); + return logPixelsY; } int SurfaceGDI::DeviceHeightFont(int points) { @@ -992,8 +1016,6 @@ class SurfaceD2D : public Surface { ID2D1SolidColorBrush *pBrush; int logPixelsY; - float dpiScaleX; - float dpiScaleY; void Clear() noexcept; void SetFont(const Font &font_); @@ -1007,7 +1029,7 @@ public: SurfaceD2D &operator=(SurfaceD2D &&) = delete; ~SurfaceD2D() override; - void SetScale(); + void SetScale(WindowID wid); void Init(WindowID wid) override; void Init(SurfaceID sid, WindowID wid) override; void InitPixMap(int width, int height, Surface *surface_, WindowID wid) override; @@ -1078,8 +1100,6 @@ SurfaceD2D::SurfaceD2D() noexcept : pBrush = nullptr; logPixelsY = 72; - dpiScaleX = 1.0; - dpiScaleY = 1.0; } SurfaceD2D::~SurfaceD2D() { @@ -1110,12 +1130,8 @@ void SurfaceD2D::Release() { Clear(); } -void SurfaceD2D::SetScale() { - HDC hdcMeasure = ::CreateCompatibleDC({}); - logPixelsY = ::GetDeviceCaps(hdcMeasure, LOGPIXELSY); - dpiScaleX = ::GetDeviceCaps(hdcMeasure, LOGPIXELSX) / 96.0f; - dpiScaleY = logPixelsY / 96.0f; - ::DeleteDC(hdcMeasure); +void SurfaceD2D::SetScale(WindowID wid) { + logPixelsY = DpiForWindow(wid); } bool SurfaceD2D::Initialised() { @@ -1126,20 +1142,20 @@ HRESULT SurfaceD2D::FlushDrawing() { return pRenderTarget->Flush(); } -void SurfaceD2D::Init(WindowID /* wid */) { +void SurfaceD2D::Init(WindowID wid) { Release(); - SetScale(); + SetScale(wid); } -void SurfaceD2D::Init(SurfaceID sid, WindowID) { +void SurfaceD2D::Init(SurfaceID sid, WindowID wid) { Release(); - SetScale(); + SetScale(wid); pRenderTarget = static_cast<ID2D1RenderTarget *>(sid); } -void SurfaceD2D::InitPixMap(int width, int height, Surface *surface_, WindowID) { +void SurfaceD2D::InitPixMap(int width, int height, Surface *surface_, WindowID wid) { Release(); - SetScale(); + SetScale(wid); SurfaceD2D *psurfOther = dynamic_cast<SurfaceD2D *>(surface_); // Should only ever be called with a SurfaceD2D, not a SurfaceGDI PLATFORM_ASSERT(psurfOther); @@ -3312,6 +3328,7 @@ void Platform::Assert(const char *c, const char *file, int line) { void Platform_Initialise(void *hInstance) { hinstPlatformRes = static_cast<HINSTANCE>(hInstance); + LoadDpiForWindow(); LoadReverseArrowCursor(); ListBoxX_Register(); } diff --git a/win32/PlatWin.h b/win32/PlatWin.h index 9d17dff69..5ce12b6c0 100644 --- a/win32/PlatWin.h +++ b/win32/PlatWin.h @@ -52,6 +52,8 @@ T DLLFunction(HMODULE hModule, LPCSTR lpProcName) noexcept { return fp; } +UINT DpiForWindow(WindowID wid) noexcept; + #if defined(USE_D2D) extern bool LoadD2D(); extern ID2D1Factory *pD2DFactory; diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 01ffcbe76..046ff7f10 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -96,6 +96,10 @@ #define WM_UNICHAR 0x0109 #endif +#ifndef WM_DPICHANGED +#define WM_DPICHANGED 0x02E0 +#endif + #ifndef UNICODE_NOCHAR #define UNICODE_NOCHAR 0xFFFF #endif @@ -282,6 +286,8 @@ class ScintillaWin : unsigned int linesPerScroll; ///< Intellimouse support int wheelDelta; ///< Wheel delta from roll + UINT dpi = 72; + HRGN hRgnUpdate; bool hasOKText; @@ -337,6 +343,8 @@ class ScintillaWin : Sci::Position TargetAsUTF8(char *text) const; Sci::Position EncodedFromUTF8(const char *utf8, char *encoded) const; + void CheckDpiChanged(); + bool PaintDC(HDC hdc); sptr_t WndPaint(); @@ -847,6 +855,14 @@ Sci::Position ScintillaWin::EncodedFromUTF8(const char *utf8, char *encoded) con } } +void ScintillaWin::CheckDpiChanged() { + const UINT dpiNow = DpiForWindow(wMain.GetID()); + if (dpi != dpiNow) { + dpi = dpiNow; + InvalidateStyleData(); + } +} + bool ScintillaWin::PaintDC(HDC hdc) { if (technology == SC_TECHNOLOGY_DEFAULT) { AutoSurface surfaceWindow(hdc, this); @@ -877,6 +893,7 @@ bool ScintillaWin::PaintDC(HDC hdc) { } sptr_t ScintillaWin::WndPaint() { + CheckDpiChanged(); //ElapsedPeriod ep; // Redirect assertions to debug output and save current state @@ -1897,6 +1914,10 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam InvalidateStyleData(); break; + case WM_DPICHANGED: + InvalidateStyleRedraw(); + break; + case WM_CONTEXTMENU: return ShowContextMenu(iMessage, wParam, lParam); |