mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-13 19:19:10 +00:00
add "Open with" button
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<Product Id="*" Name="QuickLook" Language="1033"
|
||||
<Product Id="*" Name="QuickLook" Language="1033"
|
||||
Version="!(bind.FileVersion.fil22F7B7F07E63622AD2451459086A3CF2)" Manufacturer="Paddy Xu"
|
||||
UpgradeCode="c83b9c02-87d6-494e-9f5f-cf4c3900a54d">
|
||||
<Package InstallerVersion="500" Compressed="yes" Platform="x86" InstallScope="perUser" />
|
||||
@@ -13,7 +13,7 @@
|
||||
<Property Id='MSIINSTALLPERUSER' Value='1' />
|
||||
|
||||
<WixVariable Id="WixUILicenseRtf" Value="lgpl.rtf" />
|
||||
|
||||
|
||||
<Feature Id="ProductFeature" Title="QuickLook.Installer" Level="1">
|
||||
<ComponentGroupRef Id="QuickLookComponents" />
|
||||
<ComponentRef Id="ApplicationShortcutDesktop" />
|
||||
@@ -64,4 +64,4 @@
|
||||
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
|
||||
</Product>
|
||||
</Wix>
|
||||
</Wix>
|
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace QuickLook.Plugin.IPreviewHandlers
|
||||
{
|
||||
@@ -60,7 +58,7 @@ namespace QuickLook.Plugin.IPreviewHandlers
|
||||
_panel?.Dispose();
|
||||
_panel = null;
|
||||
}
|
||||
|
||||
|
||||
~PluginInterface()
|
||||
{
|
||||
Cleanup();
|
||||
|
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace QuickLook.Plugin.PDFViewer
|
||||
{
|
||||
|
@@ -24,7 +24,7 @@ namespace QuickLook
|
||||
if (e.Modifiers != Keys.None)
|
||||
return;
|
||||
|
||||
ViewWindowManager.GetInstance().InvokeRoutine(e.KeyCode != Keys.Space);
|
||||
ViewWindowManager.GetInstance().InvokeRoutine(e.KeyCode);
|
||||
}
|
||||
|
||||
private void InstallHook(KeyEventHandler handler)
|
||||
@@ -32,6 +32,8 @@ namespace QuickLook
|
||||
_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);
|
||||
|
134
QuickLook/Helpers/FileHelper.cs
Normal file
134
QuickLook/Helpers/FileHelper.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using QuickLook.NativeMethods;
|
||||
|
||||
namespace QuickLook.Helpers
|
||||
{
|
||||
internal class FileHelper
|
||||
{
|
||||
private static string GetExecutable(string line)
|
||||
{
|
||||
var ret = line.StartsWith("\"")
|
||||
? line.Split(new[] {"\" "}, 2, StringSplitOptions.None)
|
||||
: line.Split(new[] {' '}, 2, StringSplitOptions.None);
|
||||
|
||||
ret[0] = ret[0].StartsWith("\"") ? ret[0].Substring(1) : ret[0];
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public static bool? GetAssocApplication(string path, out string executePath, out string appFriendlyName)
|
||||
{
|
||||
executePath = string.Empty;
|
||||
appFriendlyName = string.Empty;
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return null;
|
||||
|
||||
if (Directory.Exists(path))
|
||||
return null;
|
||||
|
||||
if (!File.Exists(path))
|
||||
return null;
|
||||
|
||||
if (Path.GetExtension(path) == ".lnk")
|
||||
{
|
||||
var shell = (IWshShell) new WshShell();
|
||||
var link = shell.CreateShortcut(path);
|
||||
path = GetExecutable(link.TargetPath);
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
var isExe = ext.ToLower() == ".exe";
|
||||
|
||||
// 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);
|
||||
|
||||
if (string.IsNullOrEmpty(appFriendlyName))
|
||||
appFriendlyName = Path.GetFileName(path);
|
||||
|
||||
return isExe;
|
||||
}
|
||||
|
||||
[DllImport("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra,
|
||||
[Out] StringBuilder sOut, [In] [Out] ref uint nOut);
|
||||
|
||||
private static string GetAssocApplicationNative(string fileExtensionIncludingDot, AssocStr str)
|
||||
{
|
||||
uint cOut = 0;
|
||||
if (AssocQueryString(AssocF.Verify | AssocF.RemapRunDll | AssocF.InitIgnoreUnknown, str,
|
||||
fileExtensionIncludingDot, null, null,
|
||||
ref cOut) != 1)
|
||||
return null;
|
||||
|
||||
var pOut = new StringBuilder((int) cOut);
|
||||
if (AssocQueryString(AssocF.Verify | AssocF.RemapRunDll | AssocF.InitIgnoreUnknown, str,
|
||||
fileExtensionIncludingDot, null, pOut,
|
||||
ref cOut) != 0)
|
||||
return null;
|
||||
|
||||
return pOut.ToString();
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
[Flags]
|
||||
private enum AssocF
|
||||
{
|
||||
InitNoRemapCLSID = 0x1,
|
||||
InitByExeName = 0x2,
|
||||
OpenByExeName = 0x2,
|
||||
InitDefaultToStar = 0x4,
|
||||
InitDefaultToFolder = 0x8,
|
||||
NoUserSettings = 0x10,
|
||||
NoTruncate = 0x20,
|
||||
Verify = 0x40,
|
||||
RemapRunDll = 0x80,
|
||||
NoFixUps = 0x100,
|
||||
IgnoreBaseClass = 0x200,
|
||||
InitIgnoreUnknown = 0x400,
|
||||
InitFixedProgid = 0x800,
|
||||
IsProtocol = 0x1000,
|
||||
InitForFile = 0x2000
|
||||
}
|
||||
|
||||
//[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
private enum AssocStr
|
||||
{
|
||||
Command = 1,
|
||||
Executable,
|
||||
FriendlyDocName,
|
||||
FriendlyAppName,
|
||||
NoOpen,
|
||||
ShellNewValue,
|
||||
DdeCommand,
|
||||
DdeIfExec,
|
||||
DdeApplication,
|
||||
DdeTopic,
|
||||
InfoTip,
|
||||
QuickTip,
|
||||
TileInfo,
|
||||
ContentType,
|
||||
DefaultIcon,
|
||||
ShellExtension,
|
||||
DropTarget,
|
||||
DelegateExecute,
|
||||
SupportedUriProtocols,
|
||||
ProgId,
|
||||
AppId,
|
||||
AppPublisher,
|
||||
AppIconReference,
|
||||
Max
|
||||
}
|
||||
}
|
||||
}
|
@@ -57,6 +57,11 @@
|
||||
WindowChrome.IsHitTestVisibleInChrome="True"
|
||||
Height="15" Margin="10,0" Foreground="Gray"
|
||||
Cursor="Hand" />
|
||||
<Button x:Name="buttonOpenWith" DockPanel.Dock="Right" Content="Open with ..." Height="20"
|
||||
Margin="10,0,0,0" Padding="5,0"
|
||||
Focusable="False" Cursor="Hand"
|
||||
Background="#E5EEEEEE" BorderBrush="#E59A9A9A"
|
||||
WindowChrome.IsHitTestVisibleInChrome="True" Foreground="#FF404040" />
|
||||
<!-- set grid.background colour makes it clickable -->
|
||||
<Grid x:Name="titleArea" Background="Transparent">
|
||||
<TextBlock Text="{Binding ContextObject.Title, ElementName=mainWindow}" FontSize="14"
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
using QuickLook.Helpers;
|
||||
@@ -13,6 +14,8 @@ namespace QuickLook
|
||||
/// </summary>
|
||||
public partial class MainWindowTransparent : Window
|
||||
{
|
||||
private string _path = string.Empty;
|
||||
|
||||
internal MainWindowTransparent()
|
||||
{
|
||||
// this object should be initialized before loading UI components, because many of which are binding to it.
|
||||
@@ -31,10 +34,27 @@ namespace QuickLook
|
||||
};
|
||||
|
||||
buttonCloseWindow.MouseLeftButtonUp += (sender, e) => BeginHide(true);
|
||||
|
||||
/*PreviewKeyUp += (sender, e) =>
|
||||
{
|
||||
if (e.Key == Key.Enter)
|
||||
OpenWithAssocApp();
|
||||
};*/
|
||||
|
||||
buttonOpenWith.Click += (sender, e) => OpenWithAssocApp();
|
||||
}
|
||||
|
||||
public ContextObject ContextObject { get; private set; }
|
||||
|
||||
private void OpenWithAssocApp()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_path))
|
||||
return;
|
||||
|
||||
Process.Start(new ProcessStartInfo(_path) {WorkingDirectory = Path.GetDirectoryName(_path)});
|
||||
BeginHide(true);
|
||||
}
|
||||
|
||||
private new void Show()
|
||||
{
|
||||
// revert UI changes
|
||||
@@ -107,6 +127,8 @@ namespace QuickLook
|
||||
// get window size before showing it
|
||||
ContextObject.ViewerPlugin.Prepare(path, ContextObject);
|
||||
|
||||
SetOpenWithButtonAndPath(path);
|
||||
|
||||
Show();
|
||||
|
||||
// load plugin, do not block UI
|
||||
@@ -128,6 +150,15 @@ namespace QuickLook
|
||||
throw thrown;
|
||||
}
|
||||
|
||||
private void SetOpenWithButtonAndPath(string path)
|
||||
{
|
||||
var isExe = FileHelper.GetAssocApplication(path, out string executePath, out string appFriendlyName);
|
||||
|
||||
_path = executePath;
|
||||
buttonOpenWith.Visibility = isExe == null ? Visibility.Collapsed : Visibility.Visible;
|
||||
buttonOpenWith.Content = isExe == true ? $"Run {appFriendlyName}" : $"Open with {appFriendlyName}";
|
||||
}
|
||||
|
||||
internal bool BeginHide(bool quit = false)
|
||||
{
|
||||
if (quit && App.RunningAsViewer)
|
||||
|
@@ -42,4 +42,36 @@ 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();
|
||||
}
|
||||
}
|
@@ -105,6 +105,7 @@
|
||||
<Compile Include="Helpers\BlurLibrary\PlatformsImpl\Windows81WindowBlurController.cs" />
|
||||
<Compile Include="Helpers\BlurLibrary\PlatformsImpl\Windows8WindowBlurController.cs" />
|
||||
<Compile Include="Helpers\BlurLibrary\PlatformsImpl\WindowsVistaWindowBlurController.cs" />
|
||||
<Compile Include="Helpers\FileHelper.cs" />
|
||||
<Compile Include="MainWindowNoTransparent.cs" />
|
||||
<Compile Include="NativeMethods\ShellLink.cs" />
|
||||
<Compile Include="PidHelper.cs" />
|
||||
@@ -118,7 +119,7 @@
|
||||
<Compile Include="Plugin\InfoPanel\PluginInterface.cs" />
|
||||
<Compile Include="Plugin\InfoPanel\WindowsThumbnailProvider.cs" />
|
||||
<Compile Include="Plugin\IViewer.cs" />
|
||||
<Compile Include="Helpers\DpiHelpers.cs" />
|
||||
<Compile Include="Helpers\DpiHelper.cs" />
|
||||
<Compile Include="TrayIconManager.cs" />
|
||||
<Compile Include="Plugin\ContextObject.cs" />
|
||||
<Compile Include="Helpers\WindowHelper.cs" />
|
||||
|
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using QuickLook.Helpers;
|
||||
using QuickLook.Plugin;
|
||||
|
||||
@@ -26,8 +27,11 @@ namespace QuickLook
|
||||
_currentMainWindow = _viewWindowTransparentTransparent;
|
||||
}
|
||||
|
||||
internal void InvokeRoutine(bool replaceView = false)
|
||||
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;
|
||||
|
||||
if (replaceView && _currentMainWindow.IsLoaded && _currentMainWindow.Visibility != Visibility.Visible)
|
||||
return;
|
||||
|
||||
|
Reference in New Issue
Block a user