Response to all selectionchanged event by using a task

This commit is contained in:
Paddy Xu
2017-05-27 23:06:55 +03:00
parent 6471125a0b
commit 93e1512b94
12 changed files with 244 additions and 95 deletions

63
QuickLook/FocusMonitor.cs Normal file
View 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; }
}
}

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using System.Runtime.InteropServices.ComTypes;
using QuickLook.NativeMethods;
using QuickLook.NativeMethods.Shell32;
namespace QuickLook.Helpers
{

View File

@@ -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
{

View File

@@ -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; }

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}

View 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);
}
}

View 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();
}
}

View File

@@ -0,0 +1,10 @@
using System.Runtime.InteropServices;
namespace QuickLook.NativeMethods.Shell32
{
[ComImport]
[Guid("00021401-0000-0000-C000-000000000046")]
internal class ShellLink
{
}
}

View File

@@ -0,0 +1,10 @@
using System.Runtime.InteropServices;
namespace QuickLook.NativeMethods.Shell32
{
[ComImport]
[Guid("72C24DD5-D70A-438B-8A42-98424B88AFB8")]
internal class WshShell
{
}
}

View File

@@ -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" />

View File

@@ -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());