diff --git a/src/modules/ZoomIt/ZoomIt/ZoomIt.rc b/src/modules/ZoomIt/ZoomIt/ZoomIt.rc
index 5bad5e7670..99bdb66b58 100644
--- a/src/modules/ZoomIt/ZoomIt/ZoomIt.rc
+++ b/src/modules/ZoomIt/ZoomIt/ZoomIt.rc
@@ -122,7 +122,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,166,306,50,14
PUSHBUTTON "Cancel",IDCANCEL,223,306,50,14
LTEXT "ZoomIt v9.20",IDC_VERSION,42,7,73,10
- LTEXT "Copyright 2006-2025 Mark Russinovich",IDC_COPYRIGHT,42,17,231,8
+ LTEXT "Copyright 2006-2025 Mark Russinovich",IDC_COPYRIGHT,42,17,231,8
CONTROL "Sysinternals - www.sysinternals.com",IDC_LINK,
"SysLink",WS_TABSTOP,42,26,150,9
ICON "APPICON",IDC_STATIC,12,9,20,20
diff --git a/src/modules/ZoomIt/ZoomIt/Zoomit.cpp b/src/modules/ZoomIt/ZoomIt/Zoomit.cpp
index 12faf50fd4..cf0824ada2 100644
--- a/src/modules/ZoomIt/ZoomIt/Zoomit.cpp
+++ b/src/modules/ZoomIt/ZoomIt/Zoomit.cpp
@@ -3906,6 +3906,7 @@ LRESULT APIENTRY MainWndProc(
OPENFILENAME openFileName;
static TCHAR filePath[MAX_PATH] = {L"zoomit"};
NOTIFYICONDATA tNotifyIconData;
+ static DWORD64 g_TelescopingZoomLastTick = 0ull;
const auto drawAllRightJustifiedLines = [&rc]( long lineHeight, bool doPop = false ) {
rc.top = textPt.y - static_cast(g_TextBufferPreviousLines.size()) * lineHeight;
@@ -3932,6 +3933,97 @@ LRESULT APIENTRY MainWndProc(
}
};
+ const auto doTelescopingZoomTimer = [hWnd, wParam, lParam, &x, &y]( bool invalidate = true ) {
+ if( zoomTelescopeStep != 0.0f )
+ {
+ zoomLevel *= zoomTelescopeStep;
+ g_TelescopingZoomLastTick = GetTickCount64();
+ if( (zoomTelescopeStep > 1 && zoomLevel >= zoomTelescopeTarget) ||
+ (zoomTelescopeStep < 1 && zoomLevel <= zoomTelescopeTarget) )
+ {
+ zoomLevel = zoomTelescopeTarget;
+
+ g_TelescopingZoomLastTick = 0ull;
+ KillTimer( hWnd, wParam );
+ OutputDebug( L"SETCURSOR mon_left: %x mon_top: %x x: %d y: %d\n",
+ monInfo.rcMonitor.left,
+ monInfo.rcMonitor.top,
+ cursorPos.x,
+ cursorPos.y );
+ SetCursorPos( monInfo.rcMonitor.left + cursorPos.x,
+ monInfo.rcMonitor.top + cursorPos.y );
+ }
+ }
+ else
+ {
+ // Case where we didn't zoom at all
+ g_TelescopingZoomLastTick = 0ull;
+ KillTimer( hWnd, wParam );
+ }
+ if( wParam == 2 && zoomLevel == 1 )
+ {
+ g_Zoomed = FALSE;
+ if( g_ZoomOnLiveZoom )
+ {
+ GetCursorPos( &cursorPos );
+ cursorPos = ScalePointInRects( cursorPos, monInfo.rcMonitor, g_LiveZoomSourceRect );
+ SetCursorPos( cursorPos.x, cursorPos.y );
+ SendMessage( hWnd, WM_HOTKEY, LIVE_HOTKEY, 0 );
+ }
+ else if( lParam != SHALLOW_ZOOM )
+ {
+ // Figure out where final unzoomed cursor should be
+ if( g_Drawing )
+ {
+ cursorPos = prevPt;
+ }
+ OutputDebug( L"FINAL MOUSE: x: %d y: %d\n", cursorPos.x, cursorPos.y );
+ GetZoomedTopLeftCoordinates( zoomLevel, &cursorPos, &x, width, &y, height );
+ cursorPos.x = monInfo.rcMonitor.left + x + static_cast((cursorPos.x - x) * zoomLevel);
+ cursorPos.y = monInfo.rcMonitor.top + y + static_cast((cursorPos.y - y) * zoomLevel);
+ SetCursorPos( cursorPos.x, cursorPos.y );
+ }
+ if( hTargetWindow )
+ {
+ SetWindowPos( hTargetWindow, HWND_BOTTOM, rcTargetWindow.left, rcTargetWindow.top, rcTargetWindow.right - rcTargetWindow.left, rcTargetWindow.bottom - rcTargetWindow.top, 0 );
+ hTargetWindow = NULL;
+ }
+ DeleteDrawUndoList( &drawUndoList );
+
+ // Restore live zoom if we came from that mode
+ if( g_ZoomOnLiveZoom )
+ {
+ SendMessage( g_hWndLiveZoom, WM_USER_SET_ZOOM, static_cast(g_LiveZoomLevel), reinterpret_cast(&g_LiveZoomSourceRect) );
+ g_ZoomOnLiveZoom = FALSE;
+ forcePenResize = TRUE;
+ }
+
+ SetForegroundWindow( g_ActiveWindow );
+ ClipCursor( NULL );
+ g_HaveDrawn = FALSE;
+ g_TypeMode = TypeModeOff;
+ g_HaveTyped = FALSE;
+ g_Drawing = FALSE;
+ EnableDisableStickyKeys( TRUE );
+ DeleteObject( hTypingFont );
+ DeleteDC( hdcScreen );
+ DeleteDC( hdcScreenCompat );
+ DeleteDC( hdcScreenCursorCompat );
+ DeleteDC( hdcScreenSaveCompat );
+ DeleteObject( hbmpCompat );
+ DeleteObject (hbmpCursorCompat );
+ DeleteObject( hbmpDrawingCompat );
+ DeleteObject( hDrawingPen );
+
+ SetFocus( g_ActiveWindow );
+ ShowWindow( hWnd, SW_HIDE );
+ }
+ if( invalidate )
+ {
+ InvalidateRect( hWnd, NULL, FALSE );
+ }
+ };
+
switch (message) {
case WM_CREATE:
@@ -4776,7 +4868,10 @@ LRESULT APIENTRY MainWndProc(
zoomTelescopeStep = ZOOM_LEVEL_STEP_IN;
zoomTelescopeTarget = g_ZoomLevels[g_SliderZoomLevel];
if( g_AnimateZoom )
+ {
zoomLevel = static_cast(1.0) * zoomTelescopeStep;
+ g_TelescopingZoomLastTick = GetTickCount64();
+ }
else
zoomLevel = zoomTelescopeTarget;
SetTimer( hWnd, 1, ZOOM_LEVEL_STEP_TIME, NULL );
@@ -4794,6 +4889,7 @@ LRESULT APIENTRY MainWndProc(
// Start telescoping zoom.
zoomTelescopeStep = ZOOM_LEVEL_STEP_OUT;
zoomTelescopeTarget = 1.0;
+ g_TelescopingZoomLastTick = GetTickCount64();
SetTimer( hWnd, 2, ZOOM_LEVEL_STEP_TIME, NULL );
} else {
@@ -5470,6 +5566,14 @@ LRESULT APIENTRY MainWndProc(
g_Zoomed, g_Drawing, g_Tracing);
OutputDebug(L"Window visible: %d Topmost: %d\n", IsWindowVisible(hWnd), GetWindowLong(hWnd, GWL_EXSTYLE)& WS_EX_TOPMOST);
+ if( g_Zoomed && g_TelescopingZoomLastTick != 0ull && !g_Drawing && !g_Tracing )
+ {
+ ULONG64 now = GetTickCount64();
+ if( now - g_TelescopingZoomLastTick >= ZOOM_LEVEL_STEP_TIME )
+ {
+ doTelescopingZoomTimer( false );
+ }
+ }
if( g_Zoomed && (g_TypeMode == TypeModeOff) && !g_bSaveInProgress ) {
@@ -6735,88 +6839,7 @@ LRESULT APIENTRY MainWndProc(
case 2:
case 1:
- //
- // Telescoping zoom timer
- //
- if( zoomTelescopeStep ) {
-
- zoomLevel *= zoomTelescopeStep;
- if( (zoomTelescopeStep > 1 && zoomLevel >= zoomTelescopeTarget ) ||
- (zoomTelescopeStep < 1 && zoomLevel <= zoomTelescopeTarget )) {
-
- zoomLevel = zoomTelescopeTarget;
- KillTimer( hWnd, wParam );
- OutputDebug( L"SETCURSOR mon_left: %x mon_top: %x x: %d y: %d\n",
- monInfo.rcMonitor.left, monInfo.rcMonitor.top, cursorPos.x, cursorPos.y );
- SetCursorPos( monInfo.rcMonitor.left + cursorPos.x,
- monInfo.rcMonitor.top + cursorPos.y );
- }
-
- } else {
-
- // Case where we didn't zoom at all
- KillTimer( hWnd, wParam );
- }
- if( wParam == 2 && zoomLevel == 1 ) {
-
- g_Zoomed = FALSE;
- if( g_ZoomOnLiveZoom )
- {
- GetCursorPos( &cursorPos );
- cursorPos = ScalePointInRects( cursorPos, monInfo.rcMonitor, g_LiveZoomSourceRect );
- SetCursorPos( cursorPos.x, cursorPos.y );
- SendMessage(hWnd, WM_HOTKEY, LIVE_HOTKEY, 0);
- }
- else if( lParam != SHALLOW_ZOOM )
- {
- // Figure out where final unzoomed cursor should be
- if (g_Drawing) {
- cursorPos = prevPt;
- }
- OutputDebug(L"FINAL MOUSE: x: %d y: %d\n", cursorPos.x, cursorPos.y );
- GetZoomedTopLeftCoordinates(zoomLevel, &cursorPos, &x, width, &y, height);
- cursorPos.x = monInfo.rcMonitor.left + x + static_cast((cursorPos.x - x) * zoomLevel);
- cursorPos.y = monInfo.rcMonitor.top + y + static_cast((cursorPos.y - y) * zoomLevel);
- SetCursorPos(cursorPos.x, cursorPos.y);
- }
- if( hTargetWindow ) {
-
- SetWindowPos( hTargetWindow, HWND_BOTTOM, rcTargetWindow.left, rcTargetWindow.top,
- rcTargetWindow.right - rcTargetWindow.left,
- rcTargetWindow.bottom - rcTargetWindow.top, 0 );
- hTargetWindow = NULL;
- }
- DeleteDrawUndoList( &drawUndoList );
-
- // Restore live zoom if we came from that mode
- if( g_ZoomOnLiveZoom ) {
-
- SendMessage( g_hWndLiveZoom, WM_USER_SET_ZOOM, static_cast(g_LiveZoomLevel), reinterpret_cast(&g_LiveZoomSourceRect) );
- g_ZoomOnLiveZoom = FALSE;
- forcePenResize = TRUE;
- }
-
- SetForegroundWindow( g_ActiveWindow );
- ClipCursor( NULL );
- g_HaveDrawn = FALSE;
- g_TypeMode = TypeModeOff;
- g_HaveTyped = FALSE;
- g_Drawing = FALSE;
- EnableDisableStickyKeys( TRUE );
- DeleteObject( hTypingFont );
- DeleteDC( hdcScreen );
- DeleteDC( hdcScreenCompat );
- DeleteDC( hdcScreenCursorCompat );
- DeleteDC( hdcScreenSaveCompat );
- DeleteObject( hbmpCompat );
- DeleteObject( hbmpCursorCompat );
- DeleteObject( hbmpDrawingCompat );
- DeleteObject( hDrawingPen );
-
- SetFocus( g_ActiveWindow );
- ShowWindow( hWnd, SW_HIDE );
- }
- InvalidateRect( hWnd, NULL, FALSE );
+ doTelescopingZoomTimer();
break;
case 3: