diff options
| author | Zufu Liu <unknown> | 2020-05-27 09:19:45 +1000 |
|---|---|---|
| committer | Zufu Liu <unknown> | 2020-05-27 09:19:45 +1000 |
| commit | ca0c453005807c8c0ca7aea0ee7cc766aa761770 (patch) | |
| tree | 16fb7a3374fc109bc9188372ec2b9af29b810224 | |
| parent | e5055a92d553f312bfde092f518e7fe75f134d82 (diff) | |
| download | scintilla-mirror-ca0c453005807c8c0ca7aea0ee7cc766aa761770.tar.gz | |
Backport: Bug [#2063]. Make reverse arrow cursor scale with DPI.
Backport of changeset 8265:01940b16fb7e.
| -rw-r--r-- | win32/PlatWin.cxx | 30 | ||||
| -rw-r--r-- | win32/PlatWin.h | 2 | ||||
| -rw-r--r-- | win32/ScintillaWin.cxx | 44 |
3 files changed, 67 insertions, 9 deletions
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index b125bd86d..7854966d1 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -277,8 +277,6 @@ void LoadDpiForWindow() noexcept { HINSTANCE hinstPlatformRes {}; -HCURSOR reverseArrowCursor {}; - FormatAndMetrics *FamFromFontID(void *fid) noexcept { return static_cast<FormatAndMetrics *>(fid); } @@ -1857,8 +1855,24 @@ void FlipBitmap(HBITMAP bitmap, int width, int height) noexcept { } } -void LoadReverseArrowCursor() noexcept { +} + +HCURSOR LoadReverseArrowCursor(UINT dpi) noexcept { + HCURSOR reverseArrowCursor {}; + + bool created = false; HCURSOR cursor = ::LoadCursor({}, IDC_ARROW); + + if (dpi != uSystemDPI) { + const int width = SystemMetricsForDpi(SM_CXCURSOR, dpi); + const int height = SystemMetricsForDpi(SM_CYCURSOR, dpi); + HCURSOR copy = static_cast<HCURSOR>(::CopyImage(cursor, IMAGE_CURSOR, width, height, LR_COPYFROMRESOURCE | LR_COPYRETURNORG)); + if (copy) { + created = copy != cursor; + cursor = copy; + } + } + ICONINFO info; if (::GetIconInfo(cursor, &info)) { BITMAP bmp; @@ -1875,8 +1889,11 @@ void LoadReverseArrowCursor() noexcept { if (info.hbmColor) ::DeleteObject(info.hbmColor); } -} + if (created) { + ::DestroyCursor(cursor); + } + return reverseArrowCursor; } void Window::SetCursor(Cursor curs) { @@ -1900,8 +1917,6 @@ void Window::SetCursor(Cursor curs) { ::SetCursor(::LoadCursor(NULL,IDC_HAND)); break; case cursorReverseArrow: - ::SetCursor(reverseArrowCursor); - break; case cursorArrow: case cursorInvalid: // Should not occur, but just in case. ::SetCursor(::LoadCursor(NULL,IDC_ARROW)); @@ -2950,7 +2965,6 @@ 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(); } @@ -2983,8 +2997,6 @@ void Platform_Finalise(bool fromDllMain) { } } #endif - if (reverseArrowCursor) - ::DestroyCursor(reverseArrowCursor); ListBoxX_Unregister(); } diff --git a/win32/PlatWin.h b/win32/PlatWin.h index cce68f43c..2555daac0 100644 --- a/win32/PlatWin.h +++ b/win32/PlatWin.h @@ -56,6 +56,8 @@ UINT DpiForWindow(WindowID wid) noexcept; int SystemMetricsForDpi(int nIndex, UINT dpi) noexcept; +HCURSOR LoadReverseArrowCursor(UINT dpi) noexcept; + #if defined(USE_D2D) extern bool LoadD2D(); extern ID2D1Factory *pD2DFactory; diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index a850812c7..dcae50140 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -266,6 +266,37 @@ public: } }; +class ReverseArrowCursor { + UINT dpi = USER_DEFAULT_SCREEN_DPI; + HCURSOR cursor {}; + +public: + ReverseArrowCursor() noexcept {} + // Deleted so ReverseArrowCursor objects can not be copied. + ReverseArrowCursor(const ReverseArrowCursor &) = delete; + ReverseArrowCursor(ReverseArrowCursor &&) = delete; + ReverseArrowCursor &operator=(const ReverseArrowCursor &) = delete; + ReverseArrowCursor &operator=(ReverseArrowCursor &&) = delete; + ~ReverseArrowCursor() { + if (cursor) { + ::DestroyCursor(cursor); + } + } + + HCURSOR Load(UINT dpi_) noexcept { + if (cursor) { + if (dpi == dpi_) { + return cursor; + } + ::DestroyCursor(cursor); + } + + dpi = dpi_; + cursor = LoadReverseArrowCursor(dpi_); + return cursor ? cursor : ::LoadCursor({}, IDC_ARROW); + } +}; + } /** @@ -284,6 +315,7 @@ class ScintillaWin : int wheelDelta; ///< Wheel delta from roll UINT dpi = USER_DEFAULT_SCREEN_DPI; + ReverseArrowCursor reverseArrowCursor; HRGN hRgnUpdate; @@ -333,6 +365,7 @@ class ScintillaWin : enum : UINT_PTR { invalidTimerID, standardTimerID, idleTimerID, fineTimerStart }; + void DisplayCursor(Window::Cursor c) override; bool DragThreshold(Point ptStart, Point ptNow) override; void StartDrag() override; static int MouseModifiers(uptr_t wParam) noexcept; @@ -650,6 +683,17 @@ HWND ScintillaWin::MainHWND() const noexcept { return HwndFromWindow(wMain); } +void ScintillaWin::DisplayCursor(Window::Cursor c) { + if (cursorMode != SC_CURSORNORMAL) { + c = static_cast<Window::Cursor>(cursorMode); + } + if (c == Window::cursorReverseArrow) { + ::SetCursor(reverseArrowCursor.Load(dpi)); + } else { + wMain.SetCursor(c); + } +} + bool ScintillaWin::DragThreshold(Point ptStart, Point ptNow) { const Point ptDifference = ptStart - ptNow; const XYPOSITION xMove = std::trunc(std::abs(ptDifference.x)); |
