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 | dc3e136484d12520b15eb60a525b9c9a0b3b3853 (patch) | |
tree | 2d6a2ab9089a835f797d864fa6b690bf2eb93ab7 | |
parent | 24501ccaa7e7e9e66cafbe0d1e2cc27c32af9e73 (diff) | |
download | scintilla-mirror-dc3e136484d12520b15eb60a525b9c9a0b3b3853.tar.gz |
Bug [#2063]. Make reverse arrow cursor scale with DPI.
-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 0dd7cc549..e367037e1 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -270,8 +270,6 @@ void LoadDpiForWindow() noexcept { HINSTANCE hinstPlatformRes {}; -HCURSOR reverseArrowCursor {}; - FormatAndMetrics *FamFromFontID(void *fid) noexcept { return static_cast<FormatAndMetrics *>(fid); } @@ -2261,8 +2259,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; @@ -2279,8 +2293,11 @@ void LoadReverseArrowCursor() noexcept { if (info.hbmColor) ::DeleteObject(info.hbmColor); } -} + if (created) { + ::DestroyCursor(cursor); + } + return reverseArrowCursor; } void Window::SetCursor(Cursor curs) { @@ -2304,8 +2321,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)); @@ -3354,7 +3369,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(); } @@ -3387,8 +3401,6 @@ void Platform_Finalise(bool fromDllMain) { } } #endif - if (reverseArrowCursor) - ::DestroyCursor(reverseArrowCursor); ListBoxX_Unregister(); } diff --git a/win32/PlatWin.h b/win32/PlatWin.h index f8a7ba98a..d88ee6324 100644 --- a/win32/PlatWin.h +++ b/win32/PlatWin.h @@ -60,6 +60,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 cd56105d0..28b6e950c 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -269,6 +269,37 @@ public: class GlobalMemory; +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); + } +}; + } /** @@ -287,6 +318,7 @@ class ScintillaWin : int wheelDelta; ///< Wheel delta from roll UINT dpi = USER_DEFAULT_SCREEN_DPI; + ReverseArrowCursor reverseArrowCursor; HRGN hRgnUpdate; @@ -336,6 +368,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; @@ -654,6 +687,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)); |