@@ -77,10 +77,14 @@ public static class QuickSwitch
7777 private static HWINEVENTHOOK _foregroundChangeHook = HWINEVENTHOOK . Null ;
7878 private static HWINEVENTHOOK _locationChangeHook = HWINEVENTHOOK . Null ;
7979 private static HWINEVENTHOOK _destroyChangeHook = HWINEVENTHOOK . Null ;
80+ private static HWINEVENTHOOK _hideChangeHook = HWINEVENTHOOK . Null ;
81+ private static HWINEVENTHOOK _dialogEndChangeHook = HWINEVENTHOOK . Null ;
8082
8183 private static readonly WINEVENTPROC _fgProc = ForegroundChangeCallback ;
8284 private static readonly WINEVENTPROC _locProc = LocationChangeCallback ;
8385 private static readonly WINEVENTPROC _desProc = DestroyChangeCallback ;
86+ private static readonly WINEVENTPROC _hideProc = HideChangeCallback ;
87+ private static readonly WINEVENTPROC _dialogEndProc = DialogEndChangeCallback ;
8488
8589 private static DispatcherTimer _dragMoveTimer = null ;
8690
@@ -166,6 +170,16 @@ public static void SetupQuickSwitch(bool enabled)
166170 PInvoke . UnhookWinEvent ( _destroyChangeHook ) ;
167171 _destroyChangeHook = HWINEVENTHOOK . Null ;
168172 }
173+ if ( ! _hideChangeHook . IsNull )
174+ {
175+ PInvoke . UnhookWinEvent ( _hideChangeHook ) ;
176+ _hideChangeHook = HWINEVENTHOOK . Null ;
177+ }
178+ if ( ! _dialogEndChangeHook . IsNull )
179+ {
180+ PInvoke . UnhookWinEvent ( _dialogEndChangeHook ) ;
181+ _dialogEndChangeHook = HWINEVENTHOOK . Null ;
182+ }
169183
170184 // Hook events
171185 _foregroundChangeHook = PInvoke . SetWinEventHook (
@@ -192,10 +206,28 @@ public static void SetupQuickSwitch(bool enabled)
192206 0 ,
193207 0 ,
194208 PInvoke . WINEVENT_OUTOFCONTEXT ) ;
209+ _hideChangeHook = PInvoke . SetWinEventHook (
210+ PInvoke . EVENT_OBJECT_HIDE ,
211+ PInvoke . EVENT_OBJECT_HIDE ,
212+ PInvoke . GetModuleHandle ( ( PCWSTR ) null ) ,
213+ _hideProc ,
214+ 0 ,
215+ 0 ,
216+ PInvoke . WINEVENT_OUTOFCONTEXT ) ;
217+ _dialogEndChangeHook = PInvoke . SetWinEventHook (
218+ PInvoke . EVENT_SYSTEM_DIALOGEND ,
219+ PInvoke . EVENT_SYSTEM_DIALOGEND ,
220+ PInvoke . GetModuleHandle ( ( PCWSTR ) null ) ,
221+ _dialogEndProc ,
222+ 0 ,
223+ 0 ,
224+ PInvoke . WINEVENT_OUTOFCONTEXT ) ;
195225
196226 if ( _foregroundChangeHook . IsNull ||
197227 _locationChangeHook . IsNull ||
198- _destroyChangeHook . IsNull )
228+ _destroyChangeHook . IsNull ||
229+ _hideChangeHook . IsNull ||
230+ _dialogEndChangeHook . IsNull )
199231 {
200232 Log . Error ( ClassName , "Failed to enable QuickSwitch" ) ;
201233 return ;
@@ -248,6 +280,16 @@ public static void SetupQuickSwitch(bool enabled)
248280 PInvoke . UnhookWinEvent ( _destroyChangeHook ) ;
249281 _destroyChangeHook = HWINEVENTHOOK . Null ;
250282 }
283+ if ( ! _hideChangeHook . IsNull )
284+ {
285+ PInvoke . UnhookWinEvent ( _hideChangeHook ) ;
286+ _hideChangeHook = HWINEVENTHOOK . Null ;
287+ }
288+ if ( ! _dialogEndChangeHook . IsNull )
289+ {
290+ PInvoke . UnhookWinEvent ( _dialogEndChangeHook ) ;
291+ _dialogEndChangeHook = HWINEVENTHOOK . Null ;
292+ }
251293
252294 // Stop drag move timer
253295 _dragMoveTimer ? . Stop ( ) ;
@@ -640,6 +682,68 @@ uint dwmsEventTime
640682 }
641683 }
642684
685+ private static void HideChangeCallback (
686+ HWINEVENTHOOK hWinEventHook ,
687+ uint eventType ,
688+ HWND hwnd ,
689+ int idObject ,
690+ int idChild ,
691+ uint dwEventThread ,
692+ uint dwmsEventTime
693+ )
694+ {
695+ // If the dialog window is hidden, set _dialogWindowHandle to null
696+ var dialogWindowExist = false ;
697+ lock ( _dialogWindowLock )
698+ {
699+ if ( _dialogWindow != null && _dialogWindow . Handle == hwnd )
700+ {
701+ Log . Debug ( ClassName , $ "Hide dialog: { hwnd } ") ;
702+ _dialogWindow = null ;
703+ dialogWindowExist = true ;
704+ }
705+ }
706+ if ( dialogWindowExist )
707+ {
708+ lock ( _autoSwitchedDialogsLock )
709+ {
710+ _autoSwitchedDialogs . Remove ( hwnd ) ;
711+ }
712+ InvokeResetQuickSwitchWindow ( ) ;
713+ }
714+ }
715+
716+ private static void DialogEndChangeCallback (
717+ HWINEVENTHOOK hWinEventHook ,
718+ uint eventType ,
719+ HWND hwnd ,
720+ int idObject ,
721+ int idChild ,
722+ uint dwEventThread ,
723+ uint dwmsEventTime
724+ )
725+ {
726+ // If the dialog window is ended, set _dialogWindowHandle to null
727+ var dialogWindowExist = false ;
728+ lock ( _dialogWindowLock )
729+ {
730+ if ( _dialogWindow != null && _dialogWindow . Handle == hwnd )
731+ {
732+ Log . Debug ( ClassName , $ "Dialog end: { hwnd } ") ;
733+ _dialogWindow = null ;
734+ dialogWindowExist = true ;
735+ }
736+ }
737+ if ( dialogWindowExist )
738+ {
739+ lock ( _autoSwitchedDialogsLock )
740+ {
741+ _autoSwitchedDialogs . Remove ( hwnd ) ;
742+ }
743+ InvokeResetQuickSwitchWindow ( ) ;
744+ }
745+ }
746+
643747 #endregion
644748
645749 #endregion
@@ -892,6 +996,16 @@ public static void Dispose()
892996 PInvoke . UnhookWinEvent ( _destroyChangeHook ) ;
893997 _destroyChangeHook = HWINEVENTHOOK . Null ;
894998 }
999+ if ( ! _hideChangeHook . IsNull )
1000+ {
1001+ PInvoke . UnhookWinEvent ( _hideChangeHook ) ;
1002+ _hideChangeHook = HWINEVENTHOOK . Null ;
1003+ }
1004+ if ( ! _dialogEndChangeHook . IsNull )
1005+ {
1006+ PInvoke . UnhookWinEvent ( _dialogEndChangeHook ) ;
1007+ _dialogEndChangeHook = HWINEVENTHOOK . Null ;
1008+ }
8951009
8961010 // Dispose explorers
8971011 foreach ( var explorer in _quickSwitchExplorers . Keys )
0 commit comments