mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-07 21:48:06 +00:00
Response to all selectionchanged event by using a task
This commit is contained in:
63
QuickLook/FocusMonitor.cs
Normal file
63
QuickLook/FocusMonitor.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using QuickLook.Helpers;
|
||||
|
||||
namespace QuickLook
|
||||
{
|
||||
internal class FocusMonitor
|
||||
{
|
||||
public delegate void FocusedItemChangedEventHandler(FocusedItemChangedEventArgs e);
|
||||
|
||||
private static FocusMonitor _instance;
|
||||
|
||||
public bool IsRunning { get; private set; }
|
||||
|
||||
public event FocusedItemChangedEventHandler FocusedItemChanged;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
IsRunning = true;
|
||||
|
||||
new Task(() =>
|
||||
{
|
||||
var currentPath = NativeMethods.QuickLook.GetCurrentSelectionFirst();
|
||||
|
||||
while (IsRunning)
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
|
||||
if (WindowHelper.IsFocusedControlExplorerItem())
|
||||
{
|
||||
var file = NativeMethods.QuickLook.GetCurrentSelectionFirst();
|
||||
if (file != currentPath)
|
||||
{
|
||||
FocusedItemChanged?.Invoke(new FocusedItemChangedEventArgs(file));
|
||||
currentPath = file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}).Start();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
IsRunning = false;
|
||||
}
|
||||
|
||||
internal static FocusMonitor GetInstance()
|
||||
{
|
||||
return _instance ?? (_instance = new FocusMonitor());
|
||||
}
|
||||
}
|
||||
|
||||
internal class FocusedItemChangedEventArgs : EventArgs
|
||||
{
|
||||
public FocusedItemChangedEventArgs(string files)
|
||||
{
|
||||
FocusedFile = files;
|
||||
}
|
||||
|
||||
public string FocusedFile { get; }
|
||||
}
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using QuickLook.NativeMethods;
|
||||
using QuickLook.NativeMethods.Shell32;
|
||||
|
||||
namespace QuickLook.Helpers
|
||||
{
|
||||
|
@@ -5,7 +5,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using QuickLook.NativeMethods;
|
||||
using QuickLook.NativeMethods.Shell32;
|
||||
|
||||
namespace QuickLook.Helpers
|
||||
{
|
||||
|
@@ -2,6 +2,7 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Threading;
|
||||
using QuickLook.Helpers;
|
||||
using QuickLook.Helpers.BlurLibrary;
|
||||
@@ -42,7 +43,8 @@ namespace QuickLook
|
||||
OpenWithAssocApp();
|
||||
};*/
|
||||
|
||||
buttonOpenWith.Click += (sender, e) => RunAndClose();
|
||||
buttonOpenWith.Click += (sender, e) => ViewWindowManager.GetInstance()
|
||||
.InvokeRoutine(new KeyEventArgs(Keys.Escape));
|
||||
}
|
||||
|
||||
public ContextObject ContextObject { get; private set; }
|
||||
|
@@ -1,5 +1,7 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace QuickLook.NativeMethods
|
||||
{
|
||||
@@ -16,5 +18,30 @@ namespace QuickLook.NativeMethods
|
||||
|
||||
[DllImport("QuickLook.Native.Shell32.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void GetCurrentSelectionBuffer([MarshalAs(UnmanagedType.LPWStr)] StringBuilder buffer);
|
||||
|
||||
internal static string[] GetCurrentSelection()
|
||||
{
|
||||
StringBuilder sb = null;
|
||||
// communicate with COM in a separate thread
|
||||
Task.Run(() =>
|
||||
{
|
||||
SaveCurrentSelection();
|
||||
|
||||
var n = GetCurrentSelectionCount();
|
||||
if (n != 0)
|
||||
{
|
||||
sb = new StringBuilder(n * 261); // MAX_PATH + NULL = 261
|
||||
GetCurrentSelectionBuffer(sb);
|
||||
}
|
||||
}).Wait();
|
||||
return sb == null || sb.Length == 0 ? new string[0] : sb.ToString().Split('|');
|
||||
}
|
||||
|
||||
internal static string GetCurrentSelectionFirst()
|
||||
{
|
||||
var files = GetCurrentSelection();
|
||||
|
||||
return files.Any() ? files.First() : string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,14 +2,8 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace QuickLook.NativeMethods
|
||||
namespace QuickLook.NativeMethods.Shell32
|
||||
{
|
||||
[ComImport]
|
||||
[Guid("00021401-0000-0000-C000-000000000046")]
|
||||
internal class ShellLink
|
||||
{
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[Guid("000214F9-0000-0000-C000-000000000046")]
|
||||
@@ -42,36 +36,4 @@ namespace QuickLook.NativeMethods
|
||||
void Resolve(IntPtr hwnd, int fFlags);
|
||||
void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("72C24DD5-D70A-438B-8A42-98424B88AFB8")]
|
||||
internal class WshShell
|
||||
{
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||
[Guid("F935DC21-1CF0-11D0-ADB9-00C04FD58A0B")]
|
||||
internal interface IWshShell
|
||||
{
|
||||
IWshShortcut CreateShortcut(string pathLink);
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||
[Guid("F935DC23-1CF0-11D0-ADB9-00C04FD58A0B")]
|
||||
internal interface IWshShortcut
|
||||
{
|
||||
string FullName { get; }
|
||||
string Arguments { get; set; }
|
||||
string Description { get; set; }
|
||||
string Hotkey { get; set; }
|
||||
string IconLocation { get; set; }
|
||||
string RelativePath { set; }
|
||||
string TargetPath { get; set; }
|
||||
int WindowStyle { get; set; }
|
||||
string WorkingDirectory { get; set; }
|
||||
void Load([In] string pathLink);
|
||||
void Save();
|
||||
}
|
||||
}
|
12
QuickLook/NativeMethods/Shell32/IWshShell.cs
Normal file
12
QuickLook/NativeMethods/Shell32/IWshShell.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace QuickLook.NativeMethods.Shell32
|
||||
{
|
||||
[ComImport]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||
[Guid("F935DC21-1CF0-11D0-ADB9-00C04FD58A0B")]
|
||||
internal interface IWshShell
|
||||
{
|
||||
IWshShortcut CreateShortcut(string pathLink);
|
||||
}
|
||||
}
|
22
QuickLook/NativeMethods/Shell32/IWshShortcut.cs
Normal file
22
QuickLook/NativeMethods/Shell32/IWshShortcut.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace QuickLook.NativeMethods.Shell32
|
||||
{
|
||||
[ComImport]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||
[Guid("F935DC23-1CF0-11D0-ADB9-00C04FD58A0B")]
|
||||
internal interface IWshShortcut
|
||||
{
|
||||
string FullName { get; }
|
||||
string Arguments { get; set; }
|
||||
string Description { get; set; }
|
||||
string Hotkey { get; set; }
|
||||
string IconLocation { get; set; }
|
||||
string RelativePath { set; }
|
||||
string TargetPath { get; set; }
|
||||
int WindowStyle { get; set; }
|
||||
string WorkingDirectory { get; set; }
|
||||
void Load([In] string pathLink);
|
||||
void Save();
|
||||
}
|
||||
}
|
10
QuickLook/NativeMethods/Shell32/ShellLink.cs
Normal file
10
QuickLook/NativeMethods/Shell32/ShellLink.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace QuickLook.NativeMethods.Shell32
|
||||
{
|
||||
[ComImport]
|
||||
[Guid("00021401-0000-0000-C000-000000000046")]
|
||||
internal class ShellLink
|
||||
{
|
||||
}
|
||||
}
|
10
QuickLook/NativeMethods/Shell32/WshShell.cs
Normal file
10
QuickLook/NativeMethods/Shell32/WshShell.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace QuickLook.NativeMethods.Shell32
|
||||
{
|
||||
[ComImport]
|
||||
[Guid("72C24DD5-D70A-438B-8A42-98424B88AFB8")]
|
||||
internal class WshShell
|
||||
{
|
||||
}
|
||||
}
|
@@ -83,6 +83,7 @@
|
||||
<Compile Include="Converters\BooleanToResizeModeConverter.cs" />
|
||||
<Compile Include="Converters\BooleanToVisibilityCollapsedConverter.cs" />
|
||||
<Compile Include="Converters\BooleanToResizeBorderThicknessConverter.cs" />
|
||||
<Compile Include="FocusMonitor.cs" />
|
||||
<Compile Include="Helpers\AutoStartupHelper.cs" />
|
||||
<Compile Include="Controls\BackgroundVisualHost.cs" />
|
||||
<Compile Include="Controls\BusyDecorator.cs" />
|
||||
@@ -108,7 +109,11 @@
|
||||
<Compile Include="Helpers\BlurLibrary\PlatformsImpl\WindowsVistaWindowBlurController.cs" />
|
||||
<Compile Include="Helpers\FileHelper.cs" />
|
||||
<Compile Include="MainWindowNoTransparent.cs" />
|
||||
<Compile Include="NativeMethods\ShellLink.cs" />
|
||||
<Compile Include="NativeMethods\Shell32\IShellLink.cs" />
|
||||
<Compile Include="NativeMethods\Shell32\IWshShell.cs" />
|
||||
<Compile Include="NativeMethods\Shell32\IWshShortcut.cs" />
|
||||
<Compile Include="NativeMethods\Shell32\ShellLink.cs" />
|
||||
<Compile Include="NativeMethods\Shell32\WshShell.cs" />
|
||||
<Compile Include="PidHelper.cs" />
|
||||
<Compile Include="PluginManager.cs" />
|
||||
<Compile Include="Plugin\InfoPanel\DpiHelpers.cs" />
|
||||
|
@@ -1,9 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using QuickLook.Helpers;
|
||||
@@ -14,11 +11,13 @@ namespace QuickLook
|
||||
internal class ViewWindowManager
|
||||
{
|
||||
private static ViewWindowManager _instance;
|
||||
|
||||
private readonly MainWindowNoTransparent _viewWindowNoTransparent;
|
||||
private readonly MainWindowTransparent _viewWindowTransparentTransparent;
|
||||
|
||||
private MainWindowTransparent _currentMainWindow;
|
||||
|
||||
private string _path = string.Empty;
|
||||
|
||||
internal ViewWindowManager()
|
||||
{
|
||||
_viewWindowTransparentTransparent = new MainWindowTransparent();
|
||||
@@ -43,17 +42,17 @@ namespace QuickLook
|
||||
TogglePreview(kea);
|
||||
break;
|
||||
case Keys.Escape:
|
||||
ClosePreview(kea, false);
|
||||
ClosePreview(kea);
|
||||
break;
|
||||
case Keys.Enter:
|
||||
ClosePreview(kea, true);
|
||||
RunAndClosePreview(kea);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ClosePreview(KeyEventArgs kea, bool runBeforeClose)
|
||||
private void RunAndClosePreview(KeyEventArgs kea = null)
|
||||
{
|
||||
if (!WindowHelper.IsFocusedControlExplorerItem() && !WindowHelper.IsFocusedWindowSelf())
|
||||
return;
|
||||
@@ -61,26 +60,40 @@ namespace QuickLook
|
||||
if (_currentMainWindow.Visibility != Visibility.Visible)
|
||||
return;
|
||||
|
||||
if (runBeforeClose)
|
||||
_currentMainWindow.RunAndClose();
|
||||
else
|
||||
_currentMainWindow.BeginHide();
|
||||
kea.Handled = true;
|
||||
StopFocusMonitor();
|
||||
_currentMainWindow.RunAndClose();
|
||||
if (kea != null)
|
||||
kea.Handled = true;
|
||||
}
|
||||
|
||||
private void TogglePreview(KeyEventArgs kea)
|
||||
internal void ClosePreview(KeyEventArgs kea = null)
|
||||
{
|
||||
StopFocusMonitor();
|
||||
_currentMainWindow.BeginHide();
|
||||
|
||||
if (kea != null)
|
||||
kea.Handled = true;
|
||||
}
|
||||
|
||||
private void TogglePreview(KeyEventArgs kea = null)
|
||||
{
|
||||
if (!WindowHelper.IsFocusedControlExplorerItem() && !WindowHelper.IsFocusedWindowSelf())
|
||||
return;
|
||||
|
||||
if (_currentMainWindow.Visibility == Visibility.Visible)
|
||||
_currentMainWindow.BeginHide();
|
||||
{
|
||||
ClosePreview();
|
||||
}
|
||||
else
|
||||
InvokeViewer(GetCurrentSelection());
|
||||
kea.Handled = true;
|
||||
{
|
||||
_path = NativeMethods.QuickLook.GetCurrentSelectionFirst();
|
||||
InvokeViewer();
|
||||
}
|
||||
if (kea != null)
|
||||
kea.Handled = true;
|
||||
}
|
||||
|
||||
private void SwitchPreview(KeyEventArgs kea)
|
||||
private void SwitchPreview(KeyEventArgs kea = null)
|
||||
{
|
||||
if (_currentMainWindow.Visibility != Visibility.Visible)
|
||||
return;
|
||||
@@ -88,21 +101,72 @@ namespace QuickLook
|
||||
if (!WindowHelper.IsFocusedControlExplorerItem())
|
||||
return;
|
||||
|
||||
_currentMainWindow.UnloadPlugin();
|
||||
InvokeViewer(GetCurrentSelection());
|
||||
kea.Handled = false;
|
||||
_path = NativeMethods.QuickLook.GetCurrentSelectionFirst();
|
||||
|
||||
InvokeViewer();
|
||||
if (kea != null)
|
||||
kea.Handled = false;
|
||||
}
|
||||
|
||||
internal void InvokeViewer(string path)
|
||||
private void SwitchPreviewRemoteInvoke(FocusedItemChangedEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("SwitchPreviewRemoteInvoke");
|
||||
|
||||
if (e.FocusedFile == _path)
|
||||
return;
|
||||
|
||||
if (string.IsNullOrEmpty(e.FocusedFile))
|
||||
return;
|
||||
|
||||
_currentMainWindow?.Dispatcher.Invoke(() =>
|
||||
{
|
||||
if (_currentMainWindow.Visibility != Visibility.Visible)
|
||||
return;
|
||||
|
||||
if (!WindowHelper.IsFocusedControlExplorerItem())
|
||||
return;
|
||||
|
||||
_path = NativeMethods.QuickLook.GetCurrentSelectionFirst();
|
||||
|
||||
InvokeViewer();
|
||||
});
|
||||
}
|
||||
|
||||
private void RunFocusMonitor()
|
||||
{
|
||||
if (!FocusMonitor.GetInstance().IsRunning)
|
||||
{
|
||||
FocusMonitor.GetInstance().Start();
|
||||
FocusMonitor.GetInstance().FocusedItemChanged += SwitchPreviewRemoteInvoke;
|
||||
}
|
||||
}
|
||||
|
||||
private void StopFocusMonitor()
|
||||
{
|
||||
if (FocusMonitor.GetInstance().IsRunning)
|
||||
{
|
||||
FocusMonitor.GetInstance().Stop();
|
||||
FocusMonitor.GetInstance().FocusedItemChanged -= SwitchPreviewRemoteInvoke;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool InvokeViewer(string path = null)
|
||||
{
|
||||
if (path == null)
|
||||
path = _path;
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return;
|
||||
return false;
|
||||
if (!Directory.Exists(path) && !File.Exists(path))
|
||||
return;
|
||||
return false;
|
||||
|
||||
RunFocusMonitor();
|
||||
|
||||
var matchedPlugin = PluginManager.GetInstance().FindMatch(path);
|
||||
|
||||
BeginShowNewWindow(matchedPlugin, path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void BeginShowNewWindow(IViewer matchedPlugin, string path)
|
||||
@@ -143,34 +207,6 @@ namespace QuickLook
|
||||
}
|
||||
}
|
||||
|
||||
private string GetCurrentSelection()
|
||||
{
|
||||
var path = string.Empty;
|
||||
|
||||
// communicate with COM in a separate thread
|
||||
Task.Run(() =>
|
||||
{
|
||||
var paths = GetCurrentSelectionNative();
|
||||
|
||||
if (paths.Any())
|
||||
path = paths.First();
|
||||
})
|
||||
.Wait();
|
||||
|
||||
return string.IsNullOrEmpty(path) ? string.Empty : path;
|
||||
}
|
||||
|
||||
private string[] GetCurrentSelectionNative()
|
||||
{
|
||||
NativeMethods.QuickLook.SaveCurrentSelection();
|
||||
|
||||
var n = NativeMethods.QuickLook.GetCurrentSelectionCount();
|
||||
var sb = new StringBuilder(n * 261); // MAX_PATH + NULL = 261
|
||||
NativeMethods.QuickLook.GetCurrentSelectionBuffer(sb);
|
||||
|
||||
return sb.Length == 0 ? new string[0] : sb.ToString().Split('|');
|
||||
}
|
||||
|
||||
internal static ViewWindowManager GetInstance()
|
||||
{
|
||||
return _instance ?? (_instance = new ViewWindowManager());
|
||||
|
Reference in New Issue
Block a user