Skip to content

Commit 29e74ae

Browse files
committed
Use new interface styles
1 parent 2d34f1f commit 29e74ae

File tree

4 files changed

+59
-67
lines changed

4 files changed

+59
-67
lines changed

Flow.Launcher.Infrastructure/QuickSwitch/Models/WindowsExplorer.cs

Lines changed: 33 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@ namespace Flow.Launcher.Infrastructure.QuickSwitch.Models
1212
/// </summary>
1313
public class WindowsExplorer : IQuickSwitchExplorer
1414
{
15-
public IQuickSwitchExplorerWindow ExplorerWindow { get; private set; }
16-
17-
private static readonly string ClassName = nameof(WindowsExplorer);
15+
private static IWebBrowser2 _lastExplorerView = null;
1816

19-
public bool CheckExplorerWindow(IntPtr foreground)
17+
public IQuickSwitchExplorerWindow CheckExplorerWindow(IntPtr foreground)
2018
{
21-
var isExplorer = false;
19+
IQuickSwitchExplorerWindow explorerWindow = null;
20+
2221
// Is it from Explorer?
2322
var processName = Win32Helper.GetProcessNameFromHwnd(new(foreground));
2423
if (processName.ToLower() == "explorer.exe")
@@ -31,8 +30,8 @@ public bool CheckExplorerWindow(IntPtr foreground)
3130

3231
if (explorer.HWND != foreground) return true;
3332

34-
ExplorerWindow = new WindowsExplorerWindow(foreground, explorer);
35-
isExplorer = true;
33+
_lastExplorerView = explorer;
34+
explorerWindow = new WindowsExplorerWindow(foreground, explorer);
3635
return false;
3736
}
3837
catch (COMException)
@@ -43,7 +42,7 @@ public bool CheckExplorerWindow(IntPtr foreground)
4342
return true;
4443
});
4544
}
46-
return isExplorer;
45+
return explorerWindow;
4746
}
4847

4948
private static unsafe void EnumerateShellWindows(Func<object, bool> action)
@@ -74,66 +73,49 @@ private static unsafe void EnumerateShellWindows(Func<object, bool> action)
7473
}
7574
}
7675

77-
public void RemoveExplorerWindow()
78-
{
79-
ExplorerWindow = null;
80-
}
81-
8276
public void Dispose()
8377
{
84-
ExplorerWindow?.Dispose();
78+
// Release ComObjects
79+
try
80+
{
81+
if (_lastExplorerView != null)
82+
{
83+
Marshal.ReleaseComObject(_lastExplorerView);
84+
_lastExplorerView = null;
85+
}
86+
}
87+
catch (COMException)
88+
{
89+
_lastExplorerView = null;
90+
}
8591
}
8692
}
8793

8894
public class WindowsExplorerWindow : IQuickSwitchExplorerWindow
8995
{
9096
public IntPtr Handle { get; }
9197

92-
private static readonly object _lastExplorerViewLock = new();
93-
private static IWebBrowser2 _lastExplorerView = null;
98+
private static IWebBrowser2 _explorerView = null;
9499

95100
internal WindowsExplorerWindow(IntPtr handle, IWebBrowser2 explorerView)
96101
{
97102
Handle = handle;
98-
_lastExplorerView = explorerView;
99-
}
100-
101-
public void Dispose()
102-
{
103-
// Release ComObjects
104-
try
105-
{
106-
lock (_lastExplorerViewLock)
107-
{
108-
if (_lastExplorerView != null)
109-
{
110-
Marshal.ReleaseComObject(_lastExplorerView);
111-
_lastExplorerView = null;
112-
}
113-
}
114-
}
115-
catch (COMException)
116-
{
117-
_lastExplorerView = null;
118-
}
103+
_explorerView = explorerView;
119104
}
120105

121106
public string GetExplorerPath()
122107
{
123-
if (_lastExplorerView == null) return null;
108+
if (_explorerView == null) return null;
124109

125110
object document = null;
126111
try
127112
{
128-
lock (_lastExplorerViewLock)
113+
if (_explorerView != null)
129114
{
130-
if (_lastExplorerView != null)
131-
{
132-
// Use dynamic here because using IWebBrower2.Document can cause exception here:
133-
// System.Runtime.InteropServices.InvalidOleVariantTypeException: 'Specified OLE variant is invalid.'
134-
dynamic explorerView = _lastExplorerView;
135-
document = explorerView.Document;
136-
}
115+
// Use dynamic here because using IWebBrower2.Document can cause exception here:
116+
// System.Runtime.InteropServices.InvalidOleVariantTypeException: 'Specified OLE variant is invalid.'
117+
dynamic explorerView = _explorerView;
118+
document = explorerView.Document;
137119
}
138120
}
139121
catch (COMException)
@@ -174,5 +156,10 @@ public string GetExplorerPath()
174156

175157
return path;
176158
}
159+
160+
public void Dispose()
161+
{
162+
163+
}
177164
}
178165
}

Flow.Launcher.Infrastructure/QuickSwitch/QuickSwitch.cs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ public static class QuickSwitch
4040

4141
private static HWND _mainWindowHandle = HWND.Null;
4242

43-
private static readonly List<IQuickSwitchExplorer> _quickSwitchExplorers = new()
43+
private static readonly Dictionary<IQuickSwitchExplorer, IQuickSwitchExplorerWindow> _quickSwitchExplorers = new()
4444
{
45-
new WindowsExplorer()
45+
{ new WindowsExplorer(), null }
4646
};
4747

4848
private static IQuickSwitchExplorer _lastExplorer = null;
@@ -172,10 +172,11 @@ public static void SetupQuickSwitch(bool enabled)
172172
}
173173
else
174174
{
175-
// Remove last explorer
176-
foreach (var explorer in _quickSwitchExplorers)
175+
// Remove explorer windows
176+
foreach (var explorer in _quickSwitchExplorers.Keys)
177177
{
178-
explorer.RemoveExplorerWindow();
178+
_quickSwitchExplorers[explorer]?.Dispose();
179+
_quickSwitchExplorers[explorer] = null;
179180
}
180181

181182
// Remove dialog window handle
@@ -235,10 +236,13 @@ private static bool RefreshLastExplorer()
235236
// Enum windows from the top to the bottom
236237
PInvoke.EnumWindows((hWnd, _) =>
237238
{
238-
foreach (var explorer in _quickSwitchExplorers)
239+
foreach (var explorer in _quickSwitchExplorers.Keys)
239240
{
240-
if (explorer.CheckExplorerWindow(hWnd))
241+
var explorerWindow = explorer.CheckExplorerWindow(hWnd);
242+
if (explorerWindow != null)
241243
{
244+
_quickSwitchExplorers[explorer]?.Dispose();
245+
_quickSwitchExplorers[explorer] = explorerWindow;
242246
_lastExplorer = explorer;
243247
found = true;
244248
return false;
@@ -259,7 +263,7 @@ private static bool RefreshLastExplorer()
259263

260264
public static string GetActiveExplorerPath()
261265
{
262-
return RefreshLastExplorer() ? _lastExplorer.ExplorerWindow?.GetExplorerPath() : string.Empty;
266+
return RefreshLastExplorer() ? _quickSwitchExplorers[_lastExplorer].GetExplorerPath() : string.Empty;
263267
}
264268

265269
#endregion
@@ -474,11 +478,14 @@ uint dwmsEventTime
474478
{
475479
lock (_lastExplorerLock)
476480
{
477-
foreach (var explorer in _quickSwitchExplorers)
481+
foreach (var explorer in _quickSwitchExplorers.Keys)
478482
{
479-
if (explorer.CheckExplorerWindow(hwnd))
483+
var explorerWindow = explorer.CheckExplorerWindow(hwnd);
484+
if (explorerWindow != null)
480485
{
481486
Log.Debug(ClassName, $"Explorer window: {hwnd}");
487+
_quickSwitchExplorers[explorer]?.Dispose();
488+
_quickSwitchExplorers[explorer] = explorerWindow;
482489
_lastExplorer = explorer;
483490
break;
484491
}
@@ -610,7 +617,7 @@ private static async Task<bool> NavigateDialogPathAsync(HWND hwnd, bool auto = f
610617
string path;
611618
lock (_lastExplorerLock)
612619
{
613-
path = _lastExplorer?.ExplorerWindow?.GetExplorerPath();
620+
path = _quickSwitchExplorers[_lastExplorer]?.GetExplorerPath();
614621
}
615622
if (string.IsNullOrEmpty(path)) return false;
616623

@@ -801,8 +808,9 @@ public static void Dispose()
801808
}
802809

803810
// Dispose explorers
804-
foreach (var explorer in _quickSwitchExplorers)
811+
foreach (var explorer in _quickSwitchExplorers.Keys)
805812
{
813+
_quickSwitchExplorers[explorer]?.Dispose();
806814
explorer.Dispose();
807815
}
808816
_quickSwitchExplorers.Clear();

Flow.Launcher.Plugin/Interfaces/IQuickSwitchDialog.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
22

3+
#nullable enable
4+
35
namespace Flow.Launcher.Plugins
46
{
57
/// <summary>

Flow.Launcher.Plugin/Interfaces/IQuickSwitchExplorer.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,24 @@
11
using System;
22

3+
#nullable enable
4+
35
namespace Flow.Launcher.Plugins
46
{
57
/// <summary>
68
/// Interface for handling file explorer instances in QuickSwitch.
79
/// </summary>
810
public interface IQuickSwitchExplorer : IDisposable
911
{
10-
IQuickSwitchExplorerWindow ExplorerWindow { get; }
11-
1212
/// <summary>
1313
/// Check if the foreground window is a Windows Explorer instance.
1414
/// </summary>
1515
/// <param name="foreground">
1616
/// The handle of the foreground window to check.
1717
/// </param>
1818
/// <returns>
19-
/// True if the foreground window is a Windows Explorer instance, otherwise false.
19+
/// The explorer window if the foreground window is a Windows Explorer instance. Null if it is not.
2020
/// </returns>
21-
bool CheckExplorerWindow(IntPtr foreground);
22-
23-
/// <summary>
24-
///
25-
/// </summary>
26-
void RemoveExplorerWindow();
21+
IQuickSwitchExplorerWindow? CheckExplorerWindow(IntPtr foreground);
2722
}
2823

2924
public interface IQuickSwitchExplorerWindow : IDisposable

0 commit comments

Comments
 (0)