aboutsummaryrefslogtreecommitdiffhomepage
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/PlatWin.cxx59
-rw-r--r--win32/PlatWin.h2
-rw-r--r--win32/ScintillaWin.cxx21
3 files changed, 61 insertions, 21 deletions
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index 38fbc733a..df18f928f 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -250,6 +250,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 {};
@@ -421,6 +429,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{};
@@ -432,6 +450,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;
@@ -540,20 +561,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
@@ -565,6 +588,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) {
@@ -602,7 +626,7 @@ void SurfaceGDI::SetFont(const Font &font_) noexcept {
}
int SurfaceGDI::LogPixelsY() {
- return ::GetDeviceCaps(hdc, LOGPIXELSY);
+ return logPixelsY;
}
int SurfaceGDI::DeviceHeightFont(int points) {
@@ -986,8 +1010,6 @@ class SurfaceD2D : public Surface {
ID2D1SolidColorBrush *pBrush;
int logPixelsY;
- float dpiScaleX;
- float dpiScaleY;
void Clear() noexcept;
void SetFont(const Font &font_);
@@ -1001,7 +1023,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;
@@ -1069,8 +1091,6 @@ SurfaceD2D::SurfaceD2D() noexcept :
pBrush = nullptr;
logPixelsY = 72;
- dpiScaleX = 1.0;
- dpiScaleY = 1.0;
}
SurfaceD2D::~SurfaceD2D() {
@@ -1101,12 +1121,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() {
@@ -1117,20 +1133,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);
@@ -2908,6 +2924,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 be99b8e55..440550160 100644
--- a/win32/PlatWin.h
+++ b/win32/PlatWin.h
@@ -48,6 +48,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 695371bf8..97478e872 100644
--- a/win32/ScintillaWin.cxx
+++ b/win32/ScintillaWin.cxx
@@ -95,6 +95,10 @@
#define WM_UNICHAR 0x0109
#endif
+#ifndef WM_DPICHANGED
+#define WM_DPICHANGED 0x02E0
+#endif
+
#ifndef UNICODE_NOCHAR
#define UNICODE_NOCHAR 0xFFFF
#endif
@@ -279,6 +283,8 @@ class ScintillaWin :
unsigned int linesPerScroll; ///< Intellimouse support
int wheelDelta; ///< Wheel delta from roll
+ UINT dpi = 72;
+
HRGN hRgnUpdate;
bool hasOKText;
@@ -335,6 +341,8 @@ class ScintillaWin :
void AddCharUTF16(wchar_t const *wcs, unsigned int wclen, CharacterSource charSource);
Sci::Position EncodedFromUTF8(const char *utf8, char *encoded) const;
+ void CheckDpiChanged();
+
bool PaintDC(HDC hdc);
sptr_t WndPaint();
@@ -825,6 +833,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();
+ }
+}
+
// Add one character from a UTF-16 string, by converting to either UTF-8 or
// the current codepage. Code is similar to HandleCompositionWindowed().
void ScintillaWin::AddCharUTF16(wchar_t const *wcs, unsigned int wclen, CharacterSource charSource) {
@@ -875,6 +891,7 @@ bool ScintillaWin::PaintDC(HDC hdc) {
}
sptr_t ScintillaWin::WndPaint() {
+ CheckDpiChanged();
//ElapsedPeriod ep;
// Redirect assertions to debug output and save current state
@@ -1874,6 +1891,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);