Skip to content

Commit d229bfe

Browse files
committed
Replace Interop.SHDocVw with PInvoke
1 parent 6f13f89 commit d229bfe

File tree

3 files changed

+41
-21
lines changed

3 files changed

+41
-21
lines changed

Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,5 @@
7676
<!--Bumping to it or higher needs to test and ensure this is no longer a problem-->
7777
<PackageReference Include="ToolGood.Words.Pinyin" Version="3.0.1.4" />
7878
</ItemGroup>
79-
80-
<ItemGroup>
81-
<Reference Include="Interop.SHDocVw, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null">
82-
<HintPath>QuickSwitch\Interop.SHDocVw.dll</HintPath>
83-
</Reference>
84-
</ItemGroup>
8579

8680
</Project>

Flow.Launcher.Infrastructure/NativeMethods.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,8 @@ EVENT_SYSTEM_FOREGROUND
6161
WINEVENT_OUTOFCONTEXT
6262
WM_KEYDOWN
6363
WM_SETTEXT
64-
IShellFolderViewDual2
64+
IShellFolderViewDual2
65+
CoCreateInstance
66+
CLSCTX
67+
IShellWindows
68+
IWebBrowser2

Flow.Launcher.Infrastructure/QuickSwitch/QuickSwitch.cs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
using System.IO;
1+
using System;
2+
using System.IO;
23
using System.Runtime.InteropServices;
34
using System.Threading;
45
using CommunityToolkit.Mvvm.DependencyInjection;
56
using Flow.Launcher.Infrastructure.Logger;
67
using Flow.Launcher.Infrastructure.UserSettings;
78
using Interop.UIAutomationClient;
89
using NHotkey;
9-
using SHDocVw;
1010
using Windows.Win32;
1111
using Windows.Win32.Foundation;
12+
using Windows.Win32.System.Com;
1213
using Windows.Win32.UI.Accessibility;
1314
using Windows.Win32.UI.Shell;
1415
using 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

Comments
 (0)