diff --git a/QuickLook/BackgroundListener.cs b/QuickLook/BackgroundListener.cs index 519297a..e258572 100644 --- a/QuickLook/BackgroundListener.cs +++ b/QuickLook/BackgroundListener.cs @@ -11,7 +11,7 @@ namespace QuickLook protected BackgroundListener() { - InstallHook(HotkeyEventHandler); + InstallKeyHook(HotkeyEventHandler); } public void Dispose() @@ -27,18 +27,19 @@ namespace QuickLook ViewWindowManager.GetInstance().InvokeRoutine(e.KeyCode); } - private void InstallHook(KeyEventHandler handler) + private void InstallKeyHook(KeyEventHandler handler) { _hook = GlobalKeyboardHook.GetInstance(); - _hook.HookedKeys.Add(Keys.Space); - //_hook.HookedKeys.Add(Keys.Enter); - - _hook.HookedKeys.Add(Keys.Up); - _hook.HookedKeys.Add(Keys.Down); - _hook.HookedKeys.Add(Keys.Left); - _hook.HookedKeys.Add(Keys.Right); + _hook.HookedDownKeys.Add(Keys.Enter); + _hook.KeyDown += handler; + _hook.HookedUpKeys.Add(Keys.Space); + _hook.HookedUpKeys.Add(Keys.Escape); + _hook.HookedUpKeys.Add(Keys.Up); + _hook.HookedUpKeys.Add(Keys.Down); + _hook.HookedUpKeys.Add(Keys.Left); + _hook.HookedUpKeys.Add(Keys.Right); _hook.KeyUp += handler; } diff --git a/QuickLook/GlobalKeyboardHook.cs b/QuickLook/GlobalKeyboardHook.cs index eac0c2f..6ec8855 100644 --- a/QuickLook/GlobalKeyboardHook.cs +++ b/QuickLook/GlobalKeyboardHook.cs @@ -14,7 +14,8 @@ namespace QuickLook private User32.KeyboardHookProc _callback; private IntPtr _hhook = IntPtr.Zero; - internal List HookedKeys = new List(); + internal List HookedDownKeys = new List(); + internal List HookedUpKeys = new List(); protected GlobalKeyboardHook() { @@ -63,13 +64,21 @@ namespace QuickLook if (code >= 0) { var key = (Keys) lParam.vkCode; - if (HookedKeys.Contains(key)) + if (HookedDownKeys.Contains(key)) { key = AddModifiers(key); var kea = new KeyEventArgs(key); if (wParam == User32.WM_KEYDOWN || wParam == User32.WM_SYSKEYDOWN) KeyDown?.Invoke(this, kea); + if (kea.Handled) + return 1; + } + else if (HookedUpKeys.Contains(key)) + { + key = AddModifiers(key); + + var kea = new KeyEventArgs(key); if (wParam == User32.WM_KEYUP || wParam == User32.WM_SYSKEYUP) KeyUp?.Invoke(this, kea); if (kea.Handled) diff --git a/QuickLook/Helpers/FileHelper.cs b/QuickLook/Helpers/FileHelper.cs index 55bbc3e..af5b8c2 100644 --- a/QuickLook/Helpers/FileHelper.cs +++ b/QuickLook/Helpers/FileHelper.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Linq; using System.Runtime.InteropServices; using System.Text; using QuickLook.NativeMethods; @@ -20,9 +21,8 @@ namespace QuickLook.Helpers return ret[0]; } - public static bool? GetAssocApplication(string path, out string executePath, out string appFriendlyName) + public static bool? GetAssocApplication(string path, out string appFriendlyName) { - executePath = string.Empty; appFriendlyName = string.Empty; if (string.IsNullOrEmpty(path)) @@ -42,14 +42,13 @@ namespace QuickLook.Helpers } var ext = Path.GetExtension(path).ToLower(); - var isExe = ext.ToLower() == ".exe"; + var isExe = new[] {".cmd", ".bat", ".pif", ".scf", ".exe", ".com", ".scr"}.Contains(ext.ToLower()); // no assoc. app. found if (string.IsNullOrEmpty(GetAssocApplicationNative(ext, AssocStr.Command))) if (string.IsNullOrEmpty(GetAssocApplicationNative(ext, AssocStr.AppId))) // UWP return null; - executePath = path; appFriendlyName = isExe ? FileVersionInfo.GetVersionInfo(path).FileDescription : GetAssocApplicationNative(ext, AssocStr.FriendlyAppName); diff --git a/QuickLook/MainWindowTransparent.xaml b/QuickLook/MainWindowTransparent.xaml index 4c1d7c5..edbdd30 100644 --- a/QuickLook/MainWindowTransparent.xaml +++ b/QuickLook/MainWindowTransparent.xaml @@ -75,7 +75,8 @@ - + diff --git a/QuickLook/MainWindowTransparent.xaml.cs b/QuickLook/MainWindowTransparent.xaml.cs index a3ba225..3909304 100644 --- a/QuickLook/MainWindowTransparent.xaml.cs +++ b/QuickLook/MainWindowTransparent.xaml.cs @@ -15,6 +15,7 @@ namespace QuickLook public partial class MainWindowTransparent : Window { private string _path = string.Empty; + private IViewer _plugin; internal MainWindowTransparent() { @@ -33,7 +34,7 @@ namespace QuickLook BlurWindow.EnableWindowBlur(this); }; - buttonCloseWindow.MouseLeftButtonUp += (sender, e) => BeginHide(true); + buttonCloseWindow.MouseLeftButtonUp += (sender, e) => BeginHide(); /*PreviewKeyUp += (sender, e) => { @@ -46,13 +47,16 @@ namespace QuickLook public ContextObject ContextObject { get; private set; } - private void OpenWithAssocApp() + internal void OpenWithAssocApp() { if (string.IsNullOrEmpty(_path)) return; - Process.Start(new ProcessStartInfo(_path) {WorkingDirectory = Path.GetDirectoryName(_path)}); - BeginHide(true); + Process.Start(new ProcessStartInfo(_path) + { + WorkingDirectory = Path.GetDirectoryName(_path) + }); + BeginHide(); } private void ResizeAndCenter(Size size) @@ -79,22 +83,26 @@ namespace QuickLook internal void UnloadPlugin() { - container.Content = null; + // clear ref to control + //container.Content = null; - // clean up plugin and refresh ContextObject for next use - ContextObject.ViewerPlugin?.Cleanup(); + ContextObject.Reset(); + + _plugin?.Cleanup(); + _plugin = null; + + GC.Collect(); } internal void BeginShow(IViewer matchedPlugin, string path) { - ContextObject.CurrentContentContainer = container; - ContextObject.ViewerPlugin = matchedPlugin; - ContextObject.ViewerWindow = this; + _path = path; + _plugin = matchedPlugin; // get window size before showing it - ContextObject.ViewerPlugin.Prepare(path, ContextObject); + _plugin.Prepare(path, ContextObject); - SetOpenWithButtonAndPath(path); + SetOpenWithButtonAndPath(); // revert UI changes ContextObject.IsBusy = true; @@ -116,7 +124,7 @@ namespace QuickLook { try { - ContextObject.ViewerPlugin.View(path, ContextObject); + _plugin.View(path, ContextObject); } catch (Exception e) { @@ -129,40 +137,23 @@ namespace QuickLook throw thrown; } - private void SetOpenWithButtonAndPath(string path) + private void SetOpenWithButtonAndPath() { - var isExe = FileHelper.GetAssocApplication(path, out string executePath, out string appFriendlyName); + var isExe = FileHelper.GetAssocApplication(_path, out string appFriendlyName); - _path = executePath; - buttonOpenWith.Visibility = isExe == null ? Visibility.Collapsed : Visibility.Visible; - buttonOpenWith.Content = isExe == true ? $"Run {appFriendlyName}" : $"Open with {appFriendlyName}"; + buttonOpenWith.Content = isExe == null + ? Directory.Exists(_path) + ? $"Browse “{Path.GetFileName(_path)}”" + : "Select ..." + : isExe == true + ? $"Run “{appFriendlyName}”" + : $"Open with “{appFriendlyName}”"; } - internal bool BeginHide(bool quitIfViewer = false, bool disposePluginOnly = false) + internal void BeginHide() { - if (quitIfViewer && App.RunningAsViewer) - { - Application.Current.Shutdown(); - return true; - } - - if (Visibility != Visibility.Visible) - return false; - UnloadPlugin(); - ContextObject.Reset(); - GC.Collect(); - - // revert UI changes - ContextObject.IsBusy = true; - - if (!disposePluginOnly) - { - Hide(); - return true; - } - - return false; + Hide(); } } } \ No newline at end of file diff --git a/QuickLook/Plugin/ContextObject.cs b/QuickLook/Plugin/ContextObject.cs index 7e39a77..c60f2c5 100644 --- a/QuickLook/Plugin/ContextObject.cs +++ b/QuickLook/Plugin/ContextObject.cs @@ -2,7 +2,6 @@ using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows; -using System.Windows.Controls; using QuickLook.Annotations; using QuickLook.Helpers; @@ -18,8 +17,7 @@ namespace QuickLook.Plugin private bool _isBusy = true; private string _title = ""; - internal ContentControl CurrentContentContainer; - internal IViewer ViewerPlugin; + private object _viewerContent; /// /// Get the viewer window. @@ -44,8 +42,12 @@ namespace QuickLook.Plugin /// public object ViewerContent { - get => CurrentContentContainer.Content; - set => CurrentContentContainer.Content = value; + get => _viewerContent; + set + { + _viewerContent = value; + OnPropertyChanged(); + } } /// @@ -94,12 +96,6 @@ namespace QuickLook.Plugin public event PropertyChangedEventHandler PropertyChanged; - public void DisposePlugin() - { - ViewerPlugin?.Cleanup(); - ViewerPlugin = null; - } - /// /// Show a notification balloon. /// diff --git a/QuickLook/ViewWindowManager.cs b/QuickLook/ViewWindowManager.cs index 54b93ac..4517d82 100644 --- a/QuickLook/ViewWindowManager.cs +++ b/QuickLook/ViewWindowManager.cs @@ -29,23 +29,58 @@ namespace QuickLook internal void InvokeRoutine(Keys key) { - // do we need switch to another file? - var replaceView = key == Keys.Up || key == Keys.Down || key == Keys.Left || key == Keys.Right; + Debug.WriteLine(key); - if (replaceView && _currentMainWindow.Visibility != Visibility.Visible) + switch (key) + { + case Keys.Up: + case Keys.Down: + case Keys.Left: + case Keys.Right: + SwitchPreviewToAnotherFile(); + break; + case Keys.Space: + TogglePreview(); + break; + case Keys.Escape: + case Keys.Enter: + ClosePreview(); + break; + default: + break; + } + } + + private void ClosePreview() + { + if (!WindowHelper.IsFocusedControlExplorerItem() && !WindowHelper.IsFocusedWindowSelf()) + return; + + if (_currentMainWindow.Visibility == Visibility.Visible) + _currentMainWindow.BeginHide(); + } + + private void TogglePreview() + { + if (!WindowHelper.IsFocusedControlExplorerItem() && !WindowHelper.IsFocusedWindowSelf()) + return; + + if (_currentMainWindow.Visibility == Visibility.Visible) + _currentMainWindow.BeginHide(); + else + InvokeViewer(GetCurrentSelection()); + } + + private void SwitchPreviewToAnotherFile() + { + if (_currentMainWindow.Visibility != Visibility.Visible) return; if (!WindowHelper.IsFocusedControlExplorerItem()) - if (replaceView || !WindowHelper.IsFocusedWindowSelf()) - return; - - // should the window be closed (replaceView == false), return without showing new one - if (_currentMainWindow.BeginHide(disposePluginOnly: replaceView)) return; - var path = GetCurrentSelection(); - - InvokeViewer(path); + _currentMainWindow.UnloadPlugin(); + InvokeViewer(GetCurrentSelection()); } internal void InvokeViewer(string path)