aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--win32/PlatWin.cxx30
-rw-r--r--win32/PlatWin.h2
-rw-r--r--win32/ScintillaWin.cxx44
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));