diff options
Diffstat (limited to 'win32/ScintillaWin.cxx')
| -rw-r--r-- | win32/ScintillaWin.cxx | 65 | 
1 files changed, 46 insertions, 19 deletions
| diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index e7aae8c3b..67fddd1cb 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -103,6 +103,8 @@  #define SC_WIN_IDLE 5001  typedef BOOL (WINAPI *TrackMouseEventSig)(LPTRACKMOUSEEVENT); +typedef UINT_PTR (WINAPI *SetCoalescableTimerSig)(HWND hwnd, UINT_PTR nIDEvent, +	UINT uElapse, TIMERPROC lpTimerFunc, ULONG uToleranceDelay);  // GCC has trouble with the standard COM ABI so do it the old C way with explicit vtables. @@ -183,6 +185,7 @@ class ScintillaWin :  	bool capturedMouse;  	bool trackedMouseLeave;  	TrackMouseEventSig TrackMouseEventFn; +	SetCoalescableTimerSig SetCoalescableTimerFn;  	unsigned int linesPerScroll;	///< Intellimouse support  	int wheelDelta; ///< Wheel delta from roll @@ -227,7 +230,7 @@ class ScintillaWin :  	static sptr_t PASCAL CTWndProc(  		    HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam); -	enum { invalidTimerID, standardTimerID, idleTimerID }; +	enum { invalidTimerID, standardTimerID, idleTimerID, fineTimerStart };  	virtual bool DragThreshold(Point ptStart, Point ptNow);  	virtual void StartDrag(); @@ -237,7 +240,11 @@ class ScintillaWin :  	virtual bool ValidCodePage(int codePage) const;  	virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);  	virtual bool SetIdle(bool on); -	virtual void SetTicking(bool on); +	UINT_PTR timers[tickDwell+1]; +	virtual bool FineTickerAvailable(); +	virtual bool FineTickerRunning(TickReason reason); +	virtual void FineTickerStart(TickReason reason, int millis, int tolerance); +	virtual void FineTickerCancel(TickReason reason);  	virtual void SetMouseCapture(bool on);  	virtual bool HaveMouseCapture();  	virtual void SetTrackMouseLeaveEvent(bool on); @@ -334,6 +341,7 @@ ScintillaWin::ScintillaWin(HWND hwnd) {  	capturedMouse = false;  	trackedMouseLeave = false;  	TrackMouseEventFn = 0; +	SetCoalescableTimerFn = 0;  	linesPerScroll = 0;  	wheelDelta = 0;   // Wheel delta from roll @@ -389,8 +397,10 @@ void ScintillaWin::Initialise() {  	// Find TrackMouseEvent which is available on Windows > 95  	HMODULE user32 = ::GetModuleHandle(TEXT("user32.dll")); -	if (user32) +	if (user32) {  		TrackMouseEventFn = (TrackMouseEventSig)::GetProcAddress(user32, "TrackMouseEvent"); +		SetCoalescableTimerFn = (SetCoalescableTimerSig)::GetProcAddress(user32, "SetCoalescableTimer"); +	}  	if (TrackMouseEventFn == NULL) {  		// Windows 95 has an emulation in comctl32.dll:_TrackMouseEvent  		if (!commctrl32) @@ -400,11 +410,16 @@ void ScintillaWin::Initialise() {  				::GetProcAddress(commctrl32, "_TrackMouseEvent");  		}  	} +	for (TickReason tr = tickCaret; tr <= tickDwell; tr = static_cast<TickReason>(tr + 1)) { +		timers[tr] = 0; +	}  }  void ScintillaWin::Finalise() {  	ScintillaBase::Finalise(); -	SetTicking(false); +	for (TickReason tr = tickCaret; tr <= tickDwell; tr = static_cast<TickReason>(tr + 1)) { +		FineTickerCancel(tr); +	}  	SetIdle(false);  #if defined(USE_D2D)  	DropRenderTarget(); @@ -912,12 +927,10 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam  			return 0;  		case WM_TIMER: -			if (wParam == standardTimerID && timer.ticking) { -				Tick(); -			} else if (wParam == idleTimerID && idler.state) { +			if (wParam == idleTimerID && idler.state) {  				SendMessage(MainHWND(), SC_WIN_IDLE, 0, 1);  			} else { -				return 1; +				TickFor(static_cast<TickReason>(wParam - fineTimerStart));  			}  			break; @@ -1319,20 +1332,34 @@ sptr_t ScintillaWin::DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPa  	return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);  } -void ScintillaWin::SetTicking(bool on) { -	if (timer.ticking != on) { -		timer.ticking = on; -		if (timer.ticking) { -			timer.tickerID = ::SetTimer(MainHWND(), standardTimerID, timer.tickSize, NULL) -				? reinterpret_cast<TickerID>(standardTimerID) : 0; -		} else { -			::KillTimer(MainHWND(), reinterpret_cast<uptr_t>(timer.tickerID)); -			timer.tickerID = 0; -		} +/** +* Report that this Editor subclass has a working implementation of FineTickerStart. +*/ +bool ScintillaWin::FineTickerAvailable() { +	return true; +} + +bool ScintillaWin::FineTickerRunning(TickReason reason) { +	return timers[reason] != 0; +} + +void ScintillaWin::FineTickerStart(TickReason reason, int millis, int tolerance) { +	FineTickerCancel(reason); +	if (SetCoalescableTimerFn && tolerance) { +		timers[reason] = SetCoalescableTimerFn(MainHWND(), fineTimerStart + reason, millis, NULL, tolerance); +	} else { +		timers[reason] = ::SetTimer(MainHWND(), fineTimerStart + reason, millis, NULL);  	} -	timer.ticksToWait = caret.period;  } +void ScintillaWin::FineTickerCancel(TickReason reason) { +	if (timers[reason]) { +		::KillTimer(MainHWND(), timers[reason]); +		timers[reason] = 0; +	} +} + +  bool ScintillaWin::SetIdle(bool on) {  	// On Win32 the Idler is implemented as a Timer on the Scintilla window.  This  	// takes advantage of the fact that WM_TIMER messages are very low priority, | 
