@@ -39,32 +39,30 @@ public static class QuickSwitch
3939
4040 private static readonly Settings _settings = Ioc . Default . GetRequiredService < Settings > ( ) ;
4141
42+ private static IWebBrowser2 _lastExplorerView = null ;
4243 private static readonly object _lastExplorerViewLock = new ( ) ;
4344
44- private static readonly object _dialogWindowHandleLock = new ( ) ;
45+ private static HWND _mainWindowHandle = HWND . Null ;
4546
46- private static IWebBrowser2 _lastExplorerView = null ;
47+ private static HWND _dialogWindowHandle = HWND . Null ;
48+ private static readonly object _dialogWindowHandleLock = new ( ) ;
4749
4850 private static HWINEVENTHOOK _foregroundChangeHook = HWINEVENTHOOK . Null ;
49-
5051 private static HWINEVENTHOOK _locationChangeHook = HWINEVENTHOOK . Null ;
51-
52- /*private static HWINEVENTHOOK _moveSizeHook = HWINEVENTHOOK.Null;*/
53-
5452 private static HWINEVENTHOOK _destroyChangeHook = HWINEVENTHOOK . Null ;
5553
5654 private static DispatcherTimer _dragMoveTimer = null ;
5755
5856 // A list of all file dialog windows that are auto switched already
5957 private static readonly List < HWND > _autoSwitchedDialogs = new ( ) ;
60-
6158 private static readonly object _autoSwitchedDialogsLock = new ( ) ;
6259
6360 private static readonly SemaphoreSlim _navigationLock = new ( 1 , 1 ) ;
6461
65- private static HWND _mainWindowHandle = HWND . Null ;
62+ private static HWINEVENTHOOK _moveSizeHook = HWINEVENTHOOK . Null ;
6663
67- private static HWND _dialogWindowHandle = HWND . Null ;
64+ private static HWND _hookedDialogWindowHandle = HWND . Null ;
65+ private static readonly object _hookedDialogWindowHandleLock = new ( ) ;
6866
6967 private static bool _isInitialized = false ;
7068
@@ -124,16 +122,6 @@ public static void Initialize()
124122 0 ,
125123 PInvoke . WINEVENT_OUTOFCONTEXT ) ;
126124
127- // Call MoveSizeCallBack when the window is moved or resized
128- /*_moveSizeHook = PInvoke.SetWinEventHook(
129- PInvoke.EVENT_SYSTEM_MOVESIZESTART,
130- PInvoke.EVENT_SYSTEM_MOVESIZEEND,
131- PInvoke.GetModuleHandle((PCWSTR)null),
132- MoveSizeCallBack,
133- 0,
134- 0,
135- PInvoke.WINEVENT_OUTOFCONTEXT);*/
136-
137125 // Call DestroyChange when the window is destroyed
138126 _destroyChangeHook = PInvoke . SetWinEventHook (
139127 PInvoke . EVENT_OBJECT_DESTROY ,
@@ -146,7 +134,6 @@ public static void Initialize()
146134
147135 if ( _foregroundChangeHook . IsNull ||
148136 _locationChangeHook . IsNull ||
149- /*_moveSizeHook.IsNull ||*/
150137 _destroyChangeHook . IsNull )
151138 {
152139 Log . Error ( ClassName , "Failed to initialize QuickSwitch" ) ;
@@ -170,13 +157,41 @@ public static void Initialize()
170157
171158 #region Invoke Property Events
172159
173- private static void InvokeShowQuickSwitchWindow ( )
160+ private static unsafe void InvokeShowQuickSwitchWindow ( )
174161 {
175162 // Show quick switch window
176163 if ( _settings . ShowQuickSwitchWindow )
177164 {
178165 ShowQuickSwitchWindow ? . Invoke ( _dialogWindowHandle . Value ) ;
179- _dragMoveTimer ? . Start ( ) ;
166+
167+ lock ( _hookedDialogWindowHandleLock )
168+ {
169+ var needHook = _hookedDialogWindowHandle == HWND . Null ||
170+ _hookedDialogWindowHandle != _dialogWindowHandle ;
171+
172+ if ( needHook )
173+ {
174+ if ( ! _moveSizeHook . IsNull )
175+ {
176+ PInvoke . UnhookWinEvent ( _moveSizeHook ) ;
177+ _moveSizeHook = HWINEVENTHOOK . Null ;
178+ }
179+
180+ // Call MoveSizeCallBack when the window is moved or resized
181+ uint processId ;
182+ var threadId = PInvoke . GetWindowThreadProcessId ( _dialogWindowHandle , & processId ) ;
183+ _moveSizeHook = PInvoke . SetWinEventHook (
184+ PInvoke . EVENT_SYSTEM_MOVESIZESTART ,
185+ PInvoke . EVENT_SYSTEM_MOVESIZEEND ,
186+ PInvoke . GetModuleHandle ( ( PCWSTR ) null ) ,
187+ MoveSizeCallBack ,
188+ processId ,
189+ threadId ,
190+ PInvoke . WINEVENT_OUTOFCONTEXT ) ;
191+ }
192+
193+ _hookedDialogWindowHandle = _dialogWindowHandle ;
194+ }
180195 }
181196 }
182197
@@ -190,15 +205,24 @@ private static void InvokeResetQuickSwitchWindow()
190205 {
191206 // Reset quick switch window
192207 ResetQuickSwitchWindow ? . Invoke ( ) ;
193- _dragMoveTimer ? . Stop ( ) ;
208+
209+ lock ( _hookedDialogWindowHandleLock )
210+ {
211+ if ( ! _moveSizeHook . IsNull )
212+ {
213+ PInvoke . UnhookWinEvent ( _moveSizeHook ) ;
214+ _moveSizeHook = HWINEVENTHOOK . Null ;
215+ }
216+
217+ _hookedDialogWindowHandle = HWND . Null ;
218+ }
194219 }
195220
196221 private static void InvokeHideQuickSwitchWindow ( )
197222 {
198223 // Neither quick switch window nor file dialog window is foreground
199224 // Hide quick switch window until the file dialog window is brought to the foreground
200225 HideQuickSwitchWindow ? . Invoke ( ) ;
201- _dragMoveTimer ? . Stop ( ) ;
202226 }
203227
204228 #endregion
@@ -255,10 +279,7 @@ uint dwmsEventTime
255279 // Show quick switch window after navigating the path
256280 else
257281 {
258- NavigateDialogPath ( hwnd , ( ) =>
259- {
260- InvokeShowQuickSwitchWindow ( ) ;
261- } ) ;
282+ NavigateDialogPath ( hwnd , InvokeShowQuickSwitchWindow ) ;
262283 }
263284 }
264285 else
@@ -333,9 +354,7 @@ uint dwmsEventTime
333354 }
334355 }
335356
336- // Here we do not start & stop the timer beacause the start time is not accurate (more than 1s delay)
337- // So we start & stop the timer when we find a file dialog window
338- /*private static void MoveSizeCallBack(
357+ private static void MoveSizeCallBack (
339358 HWINEVENTHOOK hWinEventHook ,
340359 uint eventType ,
341360 HWND hwnd ,
@@ -346,7 +365,7 @@ uint dwmsEventTime
346365 )
347366 {
348367 // If the dialog window is moved or resized, update the quick switch window position
349- if (_dialogWindowHandle != HWND.Null && _dialogWindowHandle == hwnd && _dragMoveTimer != null)
368+ if ( _dragMoveTimer != null )
350369 {
351370 switch ( eventType )
352371 {
@@ -358,7 +377,7 @@ uint dwmsEventTime
358377 break ;
359378 }
360379 }
361- }*/
380+ }
362381
363382 private static void DestroyChangeCallback (
364383 HWINEVENTHOOK hWinEventHook ,
@@ -600,11 +619,11 @@ public static void Dispose()
600619 PInvoke . UnhookWinEvent ( _locationChangeHook ) ;
601620 _locationChangeHook = HWINEVENTHOOK . Null ;
602621 }
603- /* if (!_moveSizeHook.IsNull)
622+ if ( ! _moveSizeHook . IsNull )
604623 {
605624 PInvoke . UnhookWinEvent ( _moveSizeHook ) ;
606625 _moveSizeHook = HWINEVENTHOOK . Null ;
607- }*/
626+ }
608627 if ( ! _destroyChangeHook . IsNull )
609628 {
610629 PInvoke . UnhookWinEvent ( _destroyChangeHook ) ;
0 commit comments