1- using System . IO ;
1+ using System ;
2+ using System . IO ;
23using System . Runtime . InteropServices ;
34using System . Threading ;
45using CommunityToolkit . Mvvm . DependencyInjection ;
56using Flow . Launcher . Infrastructure . Logger ;
67using Flow . Launcher . Infrastructure . UserSettings ;
78using Interop . UIAutomationClient ;
89using NHotkey ;
9- using SHDocVw ;
1010using Windows . Win32 ;
1111using Windows . Win32 . Foundation ;
12+ using Windows . Win32 . System . Com ;
1213using Windows . Win32 . UI . Accessibility ;
1314using Windows . Win32 . UI . Shell ;
1415using WindowsInput ;
@@ -21,12 +22,12 @@ public static class QuickSwitch
2122
2223 private static readonly Settings _settings = Ioc . Default . GetRequiredService < Settings > ( ) ;
2324
24- // The class name of a dialog window is "#32770".
25+ // The class name of a dialog window
2526 private const string DialogWindowClassName = "#32770" ;
2627
2728 private static CUIAutomation8 _automation = new CUIAutomation8Class ( ) ;
2829
29- private static InternetExplorer lastExplorerView = null ;
30+ private static IWebBrowser2 lastExplorerView = null ;
3031
3132 private static readonly InputSimulator _inputSimulator = new ( ) ;
3233
@@ -68,10 +69,16 @@ public static void OnToggleHotkey(object sender, HotkeyEventArgs args)
6869
6970 private static void NavigateDialogPath ( )
7071 {
71- object document ;
72+ object document = null ;
7273 try
7374 {
74- document = lastExplorerView ? . Document ;
75+ if ( lastExplorerView != null )
76+ {
77+ // Use dynamic here because using IWebBrower2.Document can cause exception here:
78+ // System.Runtime.InteropServices.InvalidOleVariantTypeException: 'Specified OLE variant is invalid.'
79+ dynamic explorerView = lastExplorerView ;
80+ document = explorerView . Document ;
81+ }
7582 }
7683 catch ( COMException )
7784 {
@@ -183,32 +190,47 @@ uint dwmsEventTime
183190 }
184191 }
185192
186- ShellWindowsClass shellWindows ;
187193 try
188194 {
189- shellWindows = new ShellWindowsClass ( ) ;
190-
191- foreach ( var shellWindow in shellWindows )
195+ EnumerateShellWindows ( ( shellWindow ) =>
192196 {
193- if ( shellWindow is not InternetExplorer explorer )
197+ if ( shellWindow is not IWebBrowser2 explorer )
194198 {
195- continue ;
199+ return ;
196200 }
197201
198202 if ( explorer . HWND != hwnd . Value )
199203 {
200- continue ;
204+ return ;
201205 }
202206
203207 lastExplorerView = explorer ;
204- }
208+ } ) ;
205209 }
206210 catch ( System . Exception e )
207211 {
208212 Log . Exception ( ClassName , "Failed to get shell windows" , e ) ;
209213 }
210214 }
211215
216+ private static unsafe void EnumerateShellWindows ( Action < object > action )
217+ {
218+ // Create an instance of ShellWindows
219+ var clsidShellWindows = new Guid ( "9BA05972-F6A8-11CF-A442-00A0C90A8F39" ) ; // ShellWindowsClass
220+ var iidIShellWindows = typeof ( IShellWindows ) . GUID ; // IShellWindows
221+
222+ PInvoke . CoCreateInstance ( & clsidShellWindows , null , CLSCTX . CLSCTX_ALL , & iidIShellWindows , out var shellWindowsObj ) ;
223+
224+ var shellWindows = ( IShellWindows ) shellWindowsObj ;
225+
226+ // Enumerate the shell windows
227+ int count = shellWindows . Count ;
228+ for ( var i = 0 ; i < count ; i ++ )
229+ {
230+ action ( shellWindows . Item ( i ) ) ;
231+ }
232+ }
233+
212234 public static void Dispose ( )
213235 {
214236 // Dispose handle
0 commit comments