Use own Pdf viewer implementation. wip on universal InfoPanel

This commit is contained in:
Paddy Xu
2017-04-16 01:18:54 +03:00
parent 7388c3874a
commit 431cf1f014
35 changed files with 2894 additions and 213 deletions

View File

@@ -0,0 +1,40 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace QuickLook.Plugin.LastResort
{
public static class Extensions
{
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
public static BitmapSource ToBitmapSource(this Bitmap source)
{
var ip = source.GetHbitmap();
BitmapSource bs = null;
try
{
var data = source.LockBits(new Rectangle(0, 0, source.Width, source.Height),
ImageLockMode.ReadOnly, source.PixelFormat);
bs = BitmapSource.Create(source.Width, source.Height, source.HorizontalResolution,
source.VerticalResolution, PixelFormats.Bgra32, null,
data.Scan0, data.Stride * source.Height, data.Stride);
source.UnlockBits(data);
bs.Freeze();
}
finally
{
DeleteObject(ip);
}
return bs;
}
}
}

View File

@@ -0,0 +1,255 @@
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
// ReSharper disable InconsistentNaming
namespace QuickLook.Plugin.LastResort
{
public class IconHelper
{
public enum IconSizeEnum
{
SmallIcon16 = SHGFI_SMALLICON,
MediumIcon32 = SHGFI_LARGEICON,
LargeIcon48 = SHIL_EXTRALARGE,
ExtraLargeIcon = SHIL_JUMBO
}
private const int SHGFI_SMALLICON = 0x1;
private const int SHGFI_LARGEICON = 0x0;
private const int SHIL_JUMBO = 0x4;
private const int SHIL_EXTRALARGE = 0x2;
private const int WM_CLOSE = 0x0010;
[DllImport("user32")]
private static extern
IntPtr SendMessage(
IntPtr handle,
int Msg,
IntPtr wParam,
IntPtr lParam);
[DllImport("shell32.dll")]
private static extern int SHGetImageList(
int iImageList,
ref Guid riid,
out IImageList ppv);
[DllImport("Shell32.dll")]
private static extern int SHGetFileInfo(
string pszPath,
int dwFileAttributes,
ref SHFILEINFO psfi,
int cbFileInfo,
uint uFlags);
[DllImport("user32")]
private static extern int DestroyIcon(
IntPtr hIcon);
public static Bitmap GetBitmapFromFolderPath(
string filepath, IconSizeEnum iconsize)
{
var hIcon = GetIconHandleFromFolderPath(filepath, iconsize);
return getBitmapFromIconHandle(hIcon);
}
public static Bitmap GetBitmapFromFilePath(
string filepath, IconSizeEnum iconsize)
{
var hIcon = GetIconHandleFromFilePath(filepath, iconsize);
return getBitmapFromIconHandle(hIcon);
}
public static Bitmap GetBitmapFromPath(
string filepath, IconSizeEnum iconsize)
{
var hIcon = IntPtr.Zero;
if (Directory.Exists(filepath))
{
hIcon = GetIconHandleFromFolderPath(filepath, iconsize);
}
else
{
if (File.Exists(filepath))
hIcon = GetIconHandleFromFilePath(filepath, iconsize);
}
return getBitmapFromIconHandle(hIcon);
}
private static Bitmap getBitmapFromIconHandle(IntPtr hIcon)
{
if (hIcon == IntPtr.Zero) throw new FileNotFoundException();
var myIcon = Icon.FromHandle(hIcon);
var bitmap = myIcon.ToBitmap();
myIcon.Dispose();
DestroyIcon(hIcon);
SendMessage(hIcon, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
return bitmap;
}
private static IntPtr GetIconHandleFromFilePath(string filepath, IconSizeEnum iconsize)
{
var shinfo = new SHFILEINFO();
const uint SHGFI_SYSICONINDEX = 0x4000;
const int FILE_ATTRIBUTE_NORMAL = 0x80;
var flags = SHGFI_SYSICONINDEX;
return getIconHandleFromFilePathWithFlags(filepath, iconsize, ref shinfo, FILE_ATTRIBUTE_NORMAL, flags);
}
private static IntPtr GetIconHandleFromFolderPath(string folderpath, IconSizeEnum iconsize)
{
var shinfo = new SHFILEINFO();
const uint SHGFI_ICON = 0x000000100;
const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
var flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
return getIconHandleFromFilePathWithFlags(folderpath, iconsize, ref shinfo, FILE_ATTRIBUTE_DIRECTORY,
flags);
}
private static IntPtr getIconHandleFromFilePathWithFlags(
string filepath, IconSizeEnum iconsize,
ref SHFILEINFO shinfo, int fileAttributeFlag, uint flags)
{
const int ILD_TRANSPARENT = 1;
var retval = SHGetFileInfo(filepath, fileAttributeFlag, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (retval == 0) throw new FileNotFoundException();
var iconIndex = shinfo.iIcon;
var iImageListGuid = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");
IImageList iml;
var hres = SHGetImageList((int) iconsize, ref iImageListGuid, out iml);
var hIcon = IntPtr.Zero;
hres = iml.GetIcon(iconIndex, ILD_TRANSPARENT, ref hIcon);
return hIcon;
}
}
[ComImport]
[Guid("46EB5926-582E-4017-9FDF-E8998DAA0950")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IImageList
{
[PreserveSig]
int Add(
IntPtr hbmImage,
IntPtr hbmMask,
ref int pi);
[PreserveSig]
int ReplaceIcon(
int i,
IntPtr hicon,
ref int pi);
[PreserveSig]
int SetOverlayImage(
int iImage,
int iOverlay);
[PreserveSig]
int Replace(
int i,
IntPtr hbmImage,
IntPtr hbmMask);
[PreserveSig]
int AddMasked(
IntPtr hbmImage,
int crMask,
ref int pi);
[PreserveSig]
int Draw(
ref IMAGELISTDRAWPARAMS pimldp);
[PreserveSig]
int Remove(
int i);
[PreserveSig]
int GetIcon(
int i,
int flags,
ref IntPtr picon);
}
[StructLayout(LayoutKind.Sequential)]
public struct IMAGEINFO
{
public IntPtr hbmImage;
public IntPtr hbmMask;
public int Unused1;
public int Unused2;
public RECT rcImage;
}
public struct IMAGELISTDRAWPARAMS
{
public int cbSize;
public IntPtr himl;
public int i;
public IntPtr hdcDst;
public int x;
public int y;
public int cx;
public int cy;
public int xBitmap;
public int yBitmap;
public int rgbBk;
public int rgbFg;
public int fStyle;
public int dwRop;
public int fState;
public int Frame;
public int crEffect;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
private int X;
private int Y;
public POINT(int x, int y)
{
X = x;
Y = y;
}
public POINT(Point pt) : this(pt.X, pt.Y)
{
}
public static implicit operator Point(POINT p)
{
return new Point(p.X, p.Y);
}
public static implicit operator POINT(Point p)
{
return new POINT(p.X, p.Y);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
public struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 254)] public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szTypeName;
}
}

View File

@@ -0,0 +1,12 @@
<UserControl x:Class="QuickLook.Plugin.LastResort.InfoPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:QuickLook.Plugin.LastResort"
mc:Ignorable="d" Width="450" Height="250" UseLayoutRounding="True">
<Grid>
<Image x:Name="image" Width="128" Height="128"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace QuickLook.Plugin.LastResort
{
/// <summary>
/// Interaction logic for InfoPanel.xaml
/// </summary>
public partial class InfoPanel : UserControl
{
public InfoPanel()
{
InitializeComponent();
var i = 0;
}
}
}

View File

@@ -0,0 +1,33 @@
using System.Drawing;
using System.Windows;
using Size = System.Windows.Size;
namespace QuickLook.Plugin.LastResort
{
public class Plugin : IViewer
{
private InfoPanel ip;
public int Priority => -9999;
public bool CanHandle(string sample)
{
return true;
}
public void View(string path, ViewContentContainer container)
{
var s = IconHelper.GetBitmapFromPath(path, IconHelper.IconSizeEnum.ExtraLargeIcon).ToBitmapSource();
ip = new InfoPanel();
ip.image.Source = s;
container.SetContent(ip);
container.PreferedSize = new Size {Width = ip.Width, Height = ip.Height};
}
public void Close()
{
//ip.Dispose();
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("QuickLook.Plugin.LastResort")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("QuickLook.Plugin.LastResort")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b9a5a4f6-813e-40ce-ad32-dc5c1356215d")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B9A5A4F6-813E-40CE-AD32-DC5C1356215D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>QuickLook.Plugin.LastResort</RootNamespace>
<AssemblyName>QuickLook.Plugin.LastResort</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Build\Debug\Plugins\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\Build\Release\Plugins\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Extensions.cs" />
<Compile Include="InfoPanel.xaml.cs">
<DependentUpon>InfoPanel.xaml</DependentUpon>
</Compile>
<Compile Include="Plugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="IconHelper.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\QuickLook\QuickLook.csproj">
<Project>{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}</Project>
<Name>QuickLook</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Page Include="InfoPanel.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>