do not show preview window on every SPACE key; code refactoring

This commit is contained in:
Paddy Xu
2017-04-26 23:15:06 +03:00
parent fa764b2e69
commit fc5b2742d1
13 changed files with 217 additions and 96 deletions

View File

@@ -5,6 +5,11 @@
#define EXPORT extern "C" __declspec(dllexport)
EXPORT int GetFocusedWindowType()
{
return Shell32::GetFocusedWindowType();
}
EXPORT void SaveCurrentSelection()
{
Shell32::SaveCurrentSelection();

View File

@@ -5,24 +5,23 @@
class Shell32
{
public:
enum FocusedWindowType
{
INVALID = 0,
DESKTOP = 1,
EXPLORER = 2,
};
static FocusedWindowType GetFocusedWindowType();
static void SaveCurrentSelection();
static UINT GetCurrentSelectionCount();
static void GetCurrentSelectionBuffer(PWCHAR buffer);
private:
enum FocusedWindowType
{
INVALID,
DESKTOP,
EXPLORER,
};
static std::vector<std::wstring> vector_items;
static void SaveSelectedFromDesktop();
static void SaveSelectedFromExplorer();
static FocusedWindowType GetFocusedWindowType();
static CComQIPtr<IWebBrowser2> AttachDesktopShellWindow();
static void vectorFromDataObject(CComPtr<IDataObject> dao);
};

View File

@@ -7,7 +7,7 @@ using System.Runtime.InteropServices;
namespace QuickLook.Plugin.LastResort
{
public class IconHelper
public static class IconHelper
{
public enum IconSizeEnum
{

View File

@@ -1,8 +1,4 @@
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms;
using QuickLook.Utilities;
namespace QuickLook
@@ -13,8 +9,6 @@ namespace QuickLook
private GlobalKeyboardHook _hook;
private MainWindow _showingWindow;
protected BackgroundListener()
{
InstallHook(HotkeyEventHandler);
@@ -22,49 +16,7 @@ namespace QuickLook
private void HotkeyEventHandler(object sender, KeyEventArgs e)
{
if (_showingWindow != null)
{
_showingWindow.Close();
_showingWindow = null;
GC.Collect();
return;
}
var path = string.Empty;
// communicate with COM in a separate thread
Task.Run(() =>
{
var paths = GetCurrentSelection();
if (paths.Any())
path = paths.First();
})
.Wait();
if (string.IsNullOrEmpty(path))
return;
var matched = PluginManager.FindMatch(path);
if (matched == null)
return;
_showingWindow = new MainWindow();
_showingWindow.Closed += (sender2, e2) => { _showingWindow = null; };
_showingWindow.viewContentContainer.ViewerPlugin = matched;
// get window size before showing it
matched.Prepare(path, _showingWindow.viewContentContainer);
_showingWindow.Show();
matched.View(path, _showingWindow.viewContentContainer);
_showingWindow.ShowFinishLoadingAnimation();
ViewWindowManager.GetInstance().InvokeRoutine();
}
private void InstallHook(KeyEventHandler handler)
@@ -76,19 +28,6 @@ namespace QuickLook
_hook.KeyUp += handler;
}
private string[] GetCurrentSelection()
{
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 BackgroundListener GetInstance()
{
return _instance ?? (_instance = new BackgroundListener());

View File

@@ -8,6 +8,7 @@ using System.Windows.Media.Animation;
using System.Windows.Threading;
using QuickLook.Annotations;
using QuickLook.ExtensionMethods;
using QuickLook.Plugin;
using QuickLook.Utilities;
namespace QuickLook
@@ -53,10 +54,24 @@ namespace QuickLook
base.Show();
NoactivateWindowHelper.SetNoactivate(new WindowInteropHelper(this));
WindowHelper.SetNoactivate(new WindowInteropHelper(this));
}
internal void ShowFinishLoadingAnimation()
internal void BeginShow(IViewer matchedPlugin, string path)
{
viewContentContainer.ViewerPlugin = matchedPlugin;
// get window size before showing it
matchedPlugin.Prepare(path, viewContentContainer);
Show();
matchedPlugin.View(path, viewContentContainer);
ShowFinishLoadingAnimation();
}
private void ShowFinishLoadingAnimation()
{
var speed = 100;

View File

@@ -3,9 +3,12 @@ using System.Runtime.InteropServices;
namespace QuickLook.NativeMethods
{
internal class Kernel32
internal static class Kernel32
{
[DllImport("kernel32.dll")]
internal static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll")]
internal static extern IntPtr GetCurrentThreadId();
}
}

View File

@@ -3,8 +3,11 @@ using System.Text;
namespace QuickLook.NativeMethods
{
internal class QuickLook
internal static class QuickLook
{
[DllImport("QuickLook.Native.Shell32.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int GetFocusedWindowType();
[DllImport("QuickLook.Native.Shell32.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern void SaveCurrentSelection();

View File

@@ -1,10 +1,11 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Text;
namespace QuickLook.NativeMethods
{
internal class User32
internal static class User32
{
[DllImport("user32.dll")]
internal static extern IntPtr SetWindowsHookEx(int idHook, KeyboardHookProc callback, IntPtr hInstance,
@@ -17,10 +18,28 @@ namespace QuickLook.NativeMethods
internal static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref KeyboardHookStruct lParam);
[DllImport("user32.dll")]
public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
internal static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
internal static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
internal static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
[DllImport("user32.dll")]
internal static extern IntPtr AttachThreadInput(IntPtr idAttach, IntPtr idAttachTo, bool fAttach);
[DllImport("user32.dll")]
internal static extern IntPtr GetFocus();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll")]
internal static extern IntPtr GetParent(IntPtr hWnd);
internal delegate int KeyboardHookProc(int code, int wParam, ref KeyboardHookStruct lParam);

View File

@@ -79,7 +79,8 @@
<Compile Include="Plugin\ViewContentContainer.xaml.cs">
<DependentUpon>ViewContentContainer.xaml</DependentUpon>
</Compile>
<Compile Include="Utilities\NoactivateWindowHelper.cs" />
<Compile Include="Utilities\WindowHelper.cs" />
<Compile Include="ViewWindowManager.cs" />
<Page Include="Styles\ScrollBarStyleDictionary.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@@ -5,7 +5,7 @@ using System.Windows.Interop;
namespace QuickLook.Utilities
{
internal class AeroGlass
internal static class AeroGlass
{
internal static void EnableBlur(Window window)
{

View File

@@ -1,15 +0,0 @@
using System.Windows.Interop;
using QuickLook.NativeMethods;
namespace QuickLook.Utilities
{
internal class NoactivateWindowHelper
{
internal static void SetNoactivate(WindowInteropHelper window)
{
User32.SetWindowLong(window.Handle, User32.GWL_EXSTYLE,
User32.GetWindowLong(window.Handle, User32.GWL_EXSTYLE) |
User32.WS_EX_NOACTIVATE);
}
}
}

View File

@@ -0,0 +1,62 @@
using System;
using System.Text;
using System.Windows.Interop;
using QuickLook.NativeMethods;
namespace QuickLook.Utilities
{
internal static class WindowHelper
{
internal static void SetNoactivate(WindowInteropHelper window)
{
User32.SetWindowLong(window.Handle, User32.GWL_EXSTYLE,
User32.GetWindowLong(window.Handle, User32.GWL_EXSTYLE) |
User32.WS_EX_NOACTIVATE);
}
internal static string GetWindowClassName(IntPtr window)
{
var pClassName = new StringBuilder(256);
User32.GetClassName(window, pClassName, pClassName.Capacity);
return pClassName.ToString();
}
internal static IntPtr GetParentWindow(IntPtr child)
{
return User32.GetParent(child);
}
internal static IntPtr GetFocusedWindow()
{
var activeWindowHandle = User32.GetForegroundWindow();
var activeWindowThread = User32.GetWindowThreadProcessId(activeWindowHandle, IntPtr.Zero);
var currentThread = Kernel32.GetCurrentThreadId();
User32.AttachThreadInput(activeWindowThread, currentThread, true);
var focusedControlHandle = User32.GetFocus();
User32.AttachThreadInput(activeWindowThread, currentThread, false);
return focusedControlHandle;
}
internal static bool IsFocusedControlExplorerItem()
{
if (NativeMethods.QuickLook.GetFocusedWindowType() == 0)
return false;
var focusedWindowClass = GetWindowClassName(GetFocusedWindow());
var focusedWindowParentClass =
GetWindowClassName(GetParentWindow(GetFocusedWindow()));
if (focusedWindowParentClass != "SHELLDLL_DefView")
return false;
if (focusedWindowClass != "SysListView32" && focusedWindowClass != "DirectUIHWND")
return false;
return true;
}
}
}

View File

@@ -0,0 +1,90 @@
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using QuickLook.Plugin;
using QuickLook.Utilities;
namespace QuickLook
{
internal class ViewWindowManager
{
private static ViewWindowManager _instance;
private MainWindow _viewWindow;
internal void InvokeRoutine()
{
if (CloseCurrentWindow())
return;
if (!WindowHelper.IsFocusedControlExplorerItem())
return;
var path = GetCurrentSelection();
if (string.IsNullOrEmpty(path))
return;
var matchedPlugin = PluginManager.FindMatch(path);
if (matchedPlugin == null)
return;
BeginShowNewWindow(matchedPlugin, path);
}
private void BeginShowNewWindow(IViewer matchedPlugin, string path)
{
_viewWindow = new MainWindow();
_viewWindow.Closed += (sender2, e2) => { _viewWindow = null; };
_viewWindow.BeginShow(matchedPlugin, path);
}
private bool CloseCurrentWindow()
{
if (_viewWindow != null)
{
_viewWindow.Close();
_viewWindow = null;
GC.Collect();
return true;
}
return false;
}
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());
}
}
}