diff options
| -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));  | 
