diff --git a/QuickLook.Plugin.ArchiveViewer/Plugin.cs b/QuickLook.Plugin.ArchiveViewer/Plugin.cs new file mode 100644 index 0000000..113eb8a --- /dev/null +++ b/QuickLook.Plugin.ArchiveViewer/Plugin.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Windows; +using SharpCompress.Archives.SevenZip; +using SharpCompress.Common; +using SharpCompress.Readers; + +namespace QuickLook.Plugin.ArchiveViewer +{ + public class Plugin : IViewer + { + public int Priority => 0; + + public bool CanHandle(string path) + { + if (Directory.Exists(path)) + return false; + + using (var s = File.OpenRead(path)) + { + // The 7Zip format doesn't allow for reading as a forward-only stream so + // 7Zip is only supported through the Archive API. + if (SevenZipArchive.IsSevenZipFile(s)) + return true; + + s.Seek(0, SeekOrigin.Begin); + try + { + ReaderFactory.Open(s); + } + catch (InvalidOperationException) + { + return false; + } + } + + return true; + } + + public void Prepare(string path, ViewContentContainer container) + { + container.PreferedSize = new Size {Width = 800, Height = 600}; + } + + public void View(string path, ViewContentContainer container) + { + var files = new List(); + + if (SevenZipArchive.IsSevenZipFile(path)) + GetItemsFromSevenZip(path, files); + else + GetItemsFromIReader(path, files); + } + + public void Close() + { + throw new NotImplementedException(); + } + + private void GetItemsFromSevenZip(string path, List files) + { + using (var s = File.OpenRead(path)) + { + using (var reader = SevenZipArchive.Open(s)) + { + foreach (var entry in reader.Entries) + files.Add(entry); + } + } + } + + private void GetItemsFromIReader(string path, List files) + { + using (var s = File.OpenRead(path)) + { + using (var reader = ReaderFactory.Open(s)) + { + while (reader.MoveToNextEntry()) + files.Add(reader.Entry); + } + } + } + } +} \ No newline at end of file diff --git a/QuickLook.Plugin.ArchiveViewer/Properties/AssemblyInfo.cs b/QuickLook.Plugin.ArchiveViewer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b7bd3e9 --- /dev/null +++ b/QuickLook.Plugin.ArchiveViewer/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +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.ArchiveViewer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("QuickLook.Plugin.ArchiveViewer")] +[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("de2e3bc5-6ab2-4420-a160-48c7a7506c1c")] + +// 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")] \ No newline at end of file diff --git a/QuickLook.Plugin.ArchiveViewer/QuickLook.Plugin.ArchiveViewer.csproj b/QuickLook.Plugin.ArchiveViewer/QuickLook.Plugin.ArchiveViewer.csproj new file mode 100644 index 0000000..4f30405 --- /dev/null +++ b/QuickLook.Plugin.ArchiveViewer/QuickLook.Plugin.ArchiveViewer.csproj @@ -0,0 +1,66 @@ + + + + + Debug + AnyCPU + {DE2E3BC5-6AB2-4420-A160-48C7A7506C1C} + Library + Properties + QuickLook.Plugin.ArchiveViewer + QuickLook.Plugin.ArchiveViewer + v4.5.2 + 512 + + + true + full + false + ..\Build\Debug\Plugins\QuickLook.Plugin.ArchiveViewer\ + DEBUG;TRACE + prompt + 4 + x86 + + + pdbonly + true + ..\Build\Release\Plugins\QuickLook.Plugin.ArchiveViewer\ + TRACE + prompt + 4 + x86 + + + + + + ..\packages\SharpCompress.0.15.2\lib\net45\SharpCompress.dll + + + + + + + + + + + + + + + + + + + {8b4a9ce5-67b5-4a94-81cb-3771f688fdeb} + QuickLook + False + + + + + + + \ No newline at end of file diff --git a/QuickLook.Plugin.ArchiveViewer/packages.config b/QuickLook.Plugin.ArchiveViewer/packages.config new file mode 100644 index 0000000..64b6360 --- /dev/null +++ b/QuickLook.Plugin.ArchiveViewer/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/QuickLook.Plugin.ImageViewer/ImageFileHelper.cs b/QuickLook.Plugin.ImageViewer/ImageFileHelper.cs new file mode 100644 index 0000000..88d3f6e --- /dev/null +++ b/QuickLook.Plugin.ImageViewer/ImageFileHelper.cs @@ -0,0 +1,53 @@ +using System.IO; +using System.Windows; +using System.Windows.Media.Imaging; + +namespace QuickLook.Plugin.ImageViewer +{ + internal static class ImageFileHelper + { + internal static Size GetImageSize(string path) + { + var ori = GetOrientationFromExif(path); + + using (var stream = File.OpenRead(path)) + { + var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.None); + var frame = decoder.Frames[0]; + + if (ori == ExifOrientation.Rotate90CW || ori == ExifOrientation.Rotate270CW) + return new Size {Width = frame.PixelHeight, Height = frame.PixelWidth}; + + return new Size {Width = frame.PixelWidth, Height = frame.PixelHeight}; + } + } + + internal static ExifOrientation GetOrientationFromExif(string path) + { + using (var stream = File.OpenRead(path)) + { + var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.None); + var frame = decoder.Frames[0]; + + var orientation = ((BitmapMetadata) frame.Metadata).GetQuery(@"/app1/{ushort=0}/{ushort=274}"); + + if (orientation == null) + return ExifOrientation.Horizontal; + + return (ExifOrientation) (ushort) orientation; + } + } + + internal enum ExifOrientation + { + Horizontal = 1, + MirrorHorizontal = 2, + Rotate180 = 3, + MirrorVertical = 4, + MirrorHorizontal270CW = 5, + Rotate90CW = 6, + MirrorHorizontal90CW = 7, + Rotate270CW = 8 + } + } +} \ No newline at end of file diff --git a/QuickLook.Plugin.ImageViewer/ImagePanel.xaml.cs b/QuickLook.Plugin.ImageViewer/ImagePanel.xaml.cs index 0ce4483..41eddda 100644 --- a/QuickLook.Plugin.ImageViewer/ImagePanel.xaml.cs +++ b/QuickLook.Plugin.ImageViewer/ImagePanel.xaml.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Input; @@ -20,7 +21,22 @@ namespace QuickLook.Plugin.ImageViewer { InitializeComponent(); - viewPanelImage.Source = new BitmapImage(new Uri(path)); + var ori = ImageFileHelper.GetOrientationFromExif(path); + + var bitmap = new BitmapImage(); + using (var fs = File.OpenRead(path)) + { + bitmap.BeginInit(); + bitmap.StreamSource = fs; + bitmap.CacheOption = BitmapCacheOption.OnLoad; + bitmap.Rotation = ori == ImageFileHelper.ExifOrientation.Rotate90CW + ? Rotation.Rotate90 + : ori == ImageFileHelper.ExifOrientation.Rotate270CW + ? Rotation.Rotate270 + : Rotation.Rotate0; + bitmap.EndInit(); + } + viewPanelImage.Source = bitmap; Loaded += (sender, e) => { ZoomToFit(); }; diff --git a/QuickLook.Plugin.ImageViewer/Plugin.cs b/QuickLook.Plugin.ImageViewer/Plugin.cs index e4d7375..31a5278 100644 --- a/QuickLook.Plugin.ImageViewer/Plugin.cs +++ b/QuickLook.Plugin.ImageViewer/Plugin.cs @@ -1,16 +1,14 @@ -using System; -using System.IO; +using System.IO; using System.Windows; -using System.Windows.Media.Imaging; namespace QuickLook.Plugin.ImageViewer { public class Plugin : IViewer { + private Size _imageSize; private ImagePanel _ip; - private BitmapDecoder decoder; - public int Priority { get; } + public int Priority => 9999; public bool CanHandle(string path) { @@ -37,10 +35,9 @@ namespace QuickLook.Plugin.ImageViewer public void Prepare(string path, ViewContentContainer container) { - decoder = BitmapDecoder.Create(new Uri(path), BitmapCreateOptions.None, BitmapCacheOption.None); - var frame = decoder.Frames[0]; + _imageSize = ImageFileHelper.GetImageSize(path); - container.SetPreferedSizeFit(new Size {Width = frame.Width, Height = frame.Height}, 0.6); + container.SetPreferedSizeFit(_imageSize, 0.8); } public void View(string path, ViewContentContainer container) @@ -48,7 +45,7 @@ namespace QuickLook.Plugin.ImageViewer _ip = new ImagePanel(path); container.SetContent(_ip); - container.Title = $"{Path.GetFileName(path)}"; + container.Title = $"{Path.GetFileName(path)} ({_imageSize.Width} × {_imageSize.Height})"; } public void Close() diff --git a/QuickLook.Plugin.ImageViewer/QuickLook.Plugin.ImageViewer.csproj b/QuickLook.Plugin.ImageViewer/QuickLook.Plugin.ImageViewer.csproj index 7332d0d..b754421 100644 --- a/QuickLook.Plugin.ImageViewer/QuickLook.Plugin.ImageViewer.csproj +++ b/QuickLook.Plugin.ImageViewer/QuickLook.Plugin.ImageViewer.csproj @@ -49,6 +49,7 @@ + ImagePanel.xaml diff --git a/QuickLook.Plugin.LastResort/Extensions.cs b/QuickLook.Plugin.LastResort/Extensions.cs index 3d76182..964b50e 100644 --- a/QuickLook.Plugin.LastResort/Extensions.cs +++ b/QuickLook.Plugin.LastResort/Extensions.cs @@ -14,6 +14,10 @@ namespace QuickLook.Plugin.LastResort public static BitmapSource ToBitmapSource(this Bitmap source) { + // BitmapSource.Create throws an exception when the image is scanned backward. + // The Clone() will make it back scanning forward. + source = (Bitmap) source.Clone(); + var ip = source.GetHbitmap(); BitmapSource bs = null; try diff --git a/QuickLook.Plugin.LastResort/IconHelper.cs b/QuickLook.Plugin.LastResort/IconHelper.cs deleted file mode 100644 index b97c55e..0000000 --- a/QuickLook.Plugin.LastResort/IconHelper.cs +++ /dev/null @@ -1,256 +0,0 @@ -using System; -using System.Drawing; -using System.IO; -using System.Runtime.InteropServices; - -// ReSharper disable InconsistentNaming - -namespace QuickLook.Plugin.LastResort -{ - public static 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 readonly int X; - private readonly 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; - } -} \ No newline at end of file diff --git a/QuickLook.Plugin.LastResort/InfoPanel.xaml b/QuickLook.Plugin.LastResort/InfoPanel.xaml index 257540f..4fadf70 100644 --- a/QuickLook.Plugin.LastResort/InfoPanel.xaml +++ b/QuickLook.Plugin.LastResort/InfoPanel.xaml @@ -10,7 +10,7 @@ - + diff --git a/QuickLook.Plugin.LastResort/InfoPanel.xaml.cs b/QuickLook.Plugin.LastResort/InfoPanel.xaml.cs index 041f1a3..d0301e2 100644 --- a/QuickLook.Plugin.LastResort/InfoPanel.xaml.cs +++ b/QuickLook.Plugin.LastResort/InfoPanel.xaml.cs @@ -24,9 +24,13 @@ namespace QuickLook.Plugin.LastResort public void DisplayInfo(string path) { - var icon = IconHelper.GetBitmapFromPath(path, IconHelper.IconSizeEnum.ExtraLargeIcon).ToBitmapSource(); + var icon = + WindowsThumbnailProvider.GetThumbnail(path, 256, 256, + ThumbnailOptions.ScaleUp); - image.Source = icon; + image.Source = icon.ToBitmapSource(); + + icon.Dispose(); var name = Path.GetFileName(path); filename.Content = string.IsNullOrEmpty(name) ? path : name; diff --git a/QuickLook.Plugin.LastResort/QuickLook.Plugin.LastResort.csproj b/QuickLook.Plugin.LastResort/QuickLook.Plugin.LastResort.csproj index 43566e8..45408b7 100644 --- a/QuickLook.Plugin.LastResort/QuickLook.Plugin.LastResort.csproj +++ b/QuickLook.Plugin.LastResort/QuickLook.Plugin.LastResort.csproj @@ -54,7 +54,7 @@ - + diff --git a/QuickLook.Plugin.LastResort/WindowsThumbnailProvider.cs b/QuickLook.Plugin.LastResort/WindowsThumbnailProvider.cs new file mode 100644 index 0000000..83df4f2 --- /dev/null +++ b/QuickLook.Plugin.LastResort/WindowsThumbnailProvider.cs @@ -0,0 +1,203 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Runtime.InteropServices; + +namespace QuickLook.Plugin.LastResort +{ + [Flags] + internal enum ThumbnailOptions + { + None = 0x00, + BiggerSizeOk = 0x01, + InMemoryOnly = 0x02, + IconOnly = 0x04, + ThumbnailOnly = 0x08, + InCacheOnly = 0x10, + IconBackground = 0x80, + ScaleUp = 0x100 + } + + internal static class WindowsThumbnailProvider + { + private const string IShellItem2Guid = "7E9FB0D3-919F-4307-AB2E-9B1860310C93"; + + [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern int SHCreateItemFromParsingName( + [MarshalAs(UnmanagedType.LPWStr)] string path, + // The following parameter is not used - binding context. + IntPtr pbc, + ref Guid riid, + [MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem); + + [DllImport("gdi32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool DeleteObject(IntPtr hObject); + + public static Bitmap GetThumbnail(string fileName, int width, int height, ThumbnailOptions options) + { + var hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options); + + try + { + // return a System.Drawing.Bitmap from the hBitmap + return GetBitmapFromHBitmap(hBitmap); + } + finally + { + // delete HBitmap to avoid memory leaks + DeleteObject(hBitmap); + } + } + + internal static Bitmap GetBitmapFromHBitmap(IntPtr nativeHBitmap) + { + var bmp = Image.FromHbitmap(nativeHBitmap); + + if (Image.GetPixelFormatSize(bmp.PixelFormat) < 32) + return bmp; + + return CreateAlphaBitmap(bmp, PixelFormat.Format32bppArgb); + } + + internal static Bitmap CreateAlphaBitmap(Bitmap srcBitmap, PixelFormat targetPixelFormat) + { + var result = new Bitmap(srcBitmap.Width, srcBitmap.Height, targetPixelFormat); + + var bmpBounds = new Rectangle(0, 0, srcBitmap.Width, srcBitmap.Height); + + var srcData = srcBitmap.LockBits(bmpBounds, ImageLockMode.ReadOnly, srcBitmap.PixelFormat); + + var isAlplaBitmap = false; + + try + { + for (var y = 0; y <= srcData.Height - 1; y++) + for (var x = 0; x <= srcData.Width - 1; x++) + { + var pixelColor = Color.FromArgb( + Marshal.ReadInt32(srcData.Scan0, srcData.Stride * y + 4 * x)); + + if ((pixelColor.A > 0) & (pixelColor.A < 255)) + isAlplaBitmap = true; + + result.SetPixel(x, y, pixelColor); + } + } + finally + { + srcBitmap.UnlockBits(srcData); + } + + if (isAlplaBitmap) + return result; + return srcBitmap; + } + + private static IntPtr GetHBitmap(string fileName, int width, int height, ThumbnailOptions options) + { + IShellItem nativeShellItem; + var shellItem2Guid = new Guid(IShellItem2Guid); + var retCode = SHCreateItemFromParsingName(fileName, IntPtr.Zero, ref shellItem2Guid, out nativeShellItem); + + if (retCode != 0) + throw Marshal.GetExceptionForHR(retCode); + + var nativeSize = new NativeSize(); + nativeSize.Width = width; + nativeSize.Height = height; + + IntPtr hBitmap; + var hr = ((IShellItemImageFactory) nativeShellItem).GetImage(nativeSize, options, out hBitmap); + + Marshal.ReleaseComObject(nativeShellItem); + + if (hr == HResult.Ok) return hBitmap; + + throw Marshal.GetExceptionForHR((int) hr); + } + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")] + internal interface IShellItem + { + void BindToHandler(IntPtr pbc, + [MarshalAs(UnmanagedType.LPStruct)] Guid bhid, + [MarshalAs(UnmanagedType.LPStruct)] Guid riid, + out IntPtr ppv); + + void GetParent(out IShellItem ppsi); + void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName); + void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs); + void Compare(IShellItem psi, uint hint, out int piOrder); + } + + internal enum SIGDN : uint + { + NORMALDISPLAY = 0, + PARENTRELATIVEPARSING = 0x80018001, + PARENTRELATIVEFORADDRESSBAR = 0x8001c001, + DESKTOPABSOLUTEPARSING = 0x80028000, + PARENTRELATIVEEDITING = 0x80031001, + DESKTOPABSOLUTEEDITING = 0x8004c000, + FILESYSPATH = 0x80058000, + URL = 0x80068000 + } + + internal enum HResult + { + Ok = 0x0000, + False = 0x0001, + InvalidArguments = unchecked((int) 0x80070057), + OutOfMemory = unchecked((int) 0x8007000E), + NoInterface = unchecked((int) 0x80004002), + Fail = unchecked((int) 0x80004005), + ElementNotFound = unchecked((int) 0x80070490), + TypeElementNotFound = unchecked((int) 0x8002802B), + NoObject = unchecked((int) 0x800401E5), + Win32ErrorCanceled = 1223, + Canceled = unchecked((int) 0x800704C7), + ResourceInUse = unchecked((int) 0x800700AA), + AccessDenied = unchecked((int) 0x80030005) + } + + [ComImport] + [Guid("bcc18b79-ba16-442f-80c4-8a59c30c463b")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + internal interface IShellItemImageFactory + { + [PreserveSig] + HResult GetImage( + [In] [MarshalAs(UnmanagedType.Struct)] NativeSize size, + [In] ThumbnailOptions flags, + [Out] out IntPtr phbm); + } + + [StructLayout(LayoutKind.Sequential)] + internal struct NativeSize + { + private int width; + private int height; + + public int Width + { + set => width = value; + } + public int Height + { + set => height = value; + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct RGBQUAD + { + public byte rgbBlue; + public byte rgbGreen; + public byte rgbRed; + public byte rgbReserved; + } + } +} \ No newline at end of file diff --git a/QuickLook.Plugin.TextViewer/Plugin.cs b/QuickLook.Plugin.TextViewer/Plugin.cs index 743697d..efa1acc 100644 --- a/QuickLook.Plugin.TextViewer/Plugin.cs +++ b/QuickLook.Plugin.TextViewer/Plugin.cs @@ -15,7 +15,6 @@ namespace QuickLook.Plugin.TextViewer if (Directory.Exists(path)) return false; - // ReSharper disable once InconsistentNaming const long MAX_SIZE = 20 * 1024 * 1024; // if there is a possible highlighting scheme (by file extension), treat it as a plain text file diff --git a/QuickLook.sln b/QuickLook.sln index 3eb75e0..2bcc751 100644 --- a/QuickLook.sln +++ b/QuickLook.sln @@ -18,6 +18,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.TextViewer EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.ImageViewer", "QuickLook.Plugin.ImageViewer\QuickLook.Plugin.ImageViewer.csproj", "{FE5A5111-9607-4721-A7BE-422754002ED8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.ArchiveViewer", "QuickLook.Plugin.ArchiveViewer\QuickLook.Plugin.ArchiveViewer.csproj", "{DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -72,6 +74,14 @@ Global {FE5A5111-9607-4721-A7BE-422754002ED8}.Release|Any CPU.Build.0 = Release|Any CPU {FE5A5111-9607-4721-A7BE-422754002ED8}.Release|x86.ActiveCfg = Release|Any CPU {FE5A5111-9607-4721-A7BE-422754002ED8}.Release|x86.Build.0 = Release|Any CPU + {DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Debug|x86.ActiveCfg = Debug|Any CPU + {DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Debug|x86.Build.0 = Debug|Any CPU + {DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Release|Any CPU.Build.0 = Release|Any CPU + {DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Release|x86.ActiveCfg = Release|Any CPU + {DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/QuickLook/MainWindow.xaml b/QuickLook/MainWindow.xaml index df61026..c9ab06d 100644 --- a/QuickLook/MainWindow.xaml +++ b/QuickLook/MainWindow.xaml @@ -12,8 +12,8 @@ Topmost="True" d:DesignWidth="624" d:DesignHeight="700" MinWidth="275" MinHeight="150" WindowStartupLocation="CenterScreen" - x:ClassModifier="internal" Focusable="False" - ShowActivated="False" ShowInTaskbar="False" WindowStyle="None" + x:ClassModifier="internal" Focusable="False" + ShowActivated="False" ShowInTaskbar="False" WindowStyle="None" ResizeMode="CanResizeWithGrip" AllowsTransparency="True">