PowerToys/src/modules/launcher/Wox.Infrastructure/Image/ThumbnailReader.cs

159 lines
5.7 KiB
C#
Raw Normal View History

// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
Somil55/merge wpf to master (#3840) * Basic WPF searchbox working * Updated key navigation and removed coldstart for searhbox * refactored and added code back in commented * Removed XAML Island references * Basic searchbox+listview working * Getting a bit more back * got color there * Result list bit better now * Added image loader for WPF Image * Partially got the context menus rendering again * adjusting coldstart to load, control will load with main form * getting context menus back * mouse over works now * Click now works, started to remove Win.XAML references * being a bit more forcusful on focus * Shadow text is not aligned * fixing focus if listbox was used * small tweak to fix shadow text * inputs don't work but gotta figure out why. commenting out * preview text * adding back in delay * fixed height issue * Applied the correct context button styles * Created custom ItemContainerStyle to fix the blue highlights behind the command buttons * Applied the correct highlight / mouseover styling * Removed vertical scrollbar in listview * fixed for alt-space prompt * Fixed right click focus issue * Somil55/wpf modifier keys (#3378) * Removed DPI change as it was not required * Global key hooks for context menu items * Updated Key for shell, folder and indexer plugin * Updated key mapping for indexer plugin * Somil55/wpf context menu selection (#3389) * Removed DPI change as it was not required * Global key hooks for context menu items * Updated Key for shell, folder and indexer plugin * Updated key mapping for indexer plugin * Add trigger to selection on tabbing * Minor shadow adjustments so its more similiar to default shell shadow. Added intro/outro animations * Added UWP-like scrollbar style for the results list * Fixed formating and naming * Removed Powerlauncher UI project * Update PowerToys.sln * Commented out scrollbar and fade in/out animations * Added missing features from UWP branch * Fixed formatting for Product.wxs * Add dragging to WPF window Co-authored-by: Clint Rutkas <clint@rutkas.com> Co-authored-by: Niels Laute <niels.laute@live.nl>
2020-06-02 03:35:37 +08:00
using System.Runtime.InteropServices;
using System.IO;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
using System.Windows;
namespace Wox.Infrastructure.Image
{
[Flags]
public enum ThumbnailOptions
{
None = 0x00,
BiggerSizeOk = 0x01,
InMemoryOnly = 0x02,
IconOnly = 0x04,
ThumbnailOnly = 0x08,
InCacheOnly = 0x10,
}
public class WindowsThumbnailProvider
{
// Based on https://stackoverflow.com/questions/21751747/extract-thumbnail-for-any-file-in-windows
private const string IShellItem2Guid = "7E9FB0D3-919F-4307-AB2E-9B1860310C93";
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern int SHCreateItemFromParsingName(
[MarshalAs(UnmanagedType.LPWStr)] string path,
IntPtr pbc,
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem);
[DllImport("gdi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeleteObject(IntPtr hObject);
[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,
Somil55/merge wpf to master (#3840) * Basic WPF searchbox working * Updated key navigation and removed coldstart for searhbox * refactored and added code back in commented * Removed XAML Island references * Basic searchbox+listview working * Getting a bit more back * got color there * Result list bit better now * Added image loader for WPF Image * Partially got the context menus rendering again * adjusting coldstart to load, control will load with main form * getting context menus back * mouse over works now * Click now works, started to remove Win.XAML references * being a bit more forcusful on focus * Shadow text is not aligned * fixing focus if listbox was used * small tweak to fix shadow text * inputs don't work but gotta figure out why. commenting out * preview text * adding back in delay * fixed height issue * Applied the correct context button styles * Created custom ItemContainerStyle to fix the blue highlights behind the command buttons * Applied the correct highlight / mouseover styling * Removed vertical scrollbar in listview * fixed for alt-space prompt * Fixed right click focus issue * Somil55/wpf modifier keys (#3378) * Removed DPI change as it was not required * Global key hooks for context menu items * Updated Key for shell, folder and indexer plugin * Updated key mapping for indexer plugin * Somil55/wpf context menu selection (#3389) * Removed DPI change as it was not required * Global key hooks for context menu items * Updated Key for shell, folder and indexer plugin * Updated key mapping for indexer plugin * Add trigger to selection on tabbing * Minor shadow adjustments so its more similiar to default shell shadow. Added intro/outro animations * Added UWP-like scrollbar style for the results list * Fixed formating and naming * Removed Powerlauncher UI project * Update PowerToys.sln * Commented out scrollbar and fade in/out animations * Added missing features from UWP branch * Fixed formatting for Product.wxs * Add dragging to WPF window Co-authored-by: Clint Rutkas <clint@rutkas.com> Co-authored-by: Niels Laute <niels.laute@live.nl>
2020-06-02 03:35:37 +08:00
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);
}
;
Somil55/merge wpf to master (#3840) * Basic WPF searchbox working * Updated key navigation and removed coldstart for searhbox * refactored and added code back in commented * Removed XAML Island references * Basic searchbox+listview working * Getting a bit more back * got color there * Result list bit better now * Added image loader for WPF Image * Partially got the context menus rendering again * adjusting coldstart to load, control will load with main form * getting context menus back * mouse over works now * Click now works, started to remove Win.XAML references * being a bit more forcusful on focus * Shadow text is not aligned * fixing focus if listbox was used * small tweak to fix shadow text * inputs don't work but gotta figure out why. commenting out * preview text * adding back in delay * fixed height issue * Applied the correct context button styles * Created custom ItemContainerStyle to fix the blue highlights behind the command buttons * Applied the correct highlight / mouseover styling * Removed vertical scrollbar in listview * fixed for alt-space prompt * Fixed right click focus issue * Somil55/wpf modifier keys (#3378) * Removed DPI change as it was not required * Global key hooks for context menu items * Updated Key for shell, folder and indexer plugin * Updated key mapping for indexer plugin * Somil55/wpf context menu selection (#3389) * Removed DPI change as it was not required * Global key hooks for context menu items * Updated Key for shell, folder and indexer plugin * Updated key mapping for indexer plugin * Add trigger to selection on tabbing * Minor shadow adjustments so its more similiar to default shell shadow. Added intro/outro animations * Added UWP-like scrollbar style for the results list * Fixed formating and naming * Removed Powerlauncher UI project * Update PowerToys.sln * Commented out scrollbar and fade in/out animations * Added missing features from UWP branch * Fixed formatting for Product.wxs * Add dragging to WPF window Co-authored-by: Clint Rutkas <clint@rutkas.com> Co-authored-by: Niels Laute <niels.laute@live.nl>
2020-06-02 03:35:37 +08:00
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),
ExtractionFailed = unchecked((int)0x8004B200),
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)
}
[ComImportAttribute()]
[GuidAttribute("bcc18b79-ba16-442f-80c4-8a59c30c463b")]
[InterfaceTypeAttribute(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; } }
}
;
Somil55/merge wpf to master (#3840) * Basic WPF searchbox working * Updated key navigation and removed coldstart for searhbox * refactored and added code back in commented * Removed XAML Island references * Basic searchbox+listview working * Getting a bit more back * got color there * Result list bit better now * Added image loader for WPF Image * Partially got the context menus rendering again * adjusting coldstart to load, control will load with main form * getting context menus back * mouse over works now * Click now works, started to remove Win.XAML references * being a bit more forcusful on focus * Shadow text is not aligned * fixing focus if listbox was used * small tweak to fix shadow text * inputs don't work but gotta figure out why. commenting out * preview text * adding back in delay * fixed height issue * Applied the correct context button styles * Created custom ItemContainerStyle to fix the blue highlights behind the command buttons * Applied the correct highlight / mouseover styling * Removed vertical scrollbar in listview * fixed for alt-space prompt * Fixed right click focus issue * Somil55/wpf modifier keys (#3378) * Removed DPI change as it was not required * Global key hooks for context menu items * Updated Key for shell, folder and indexer plugin * Updated key mapping for indexer plugin * Somil55/wpf context menu selection (#3389) * Removed DPI change as it was not required * Global key hooks for context menu items * Updated Key for shell, folder and indexer plugin * Updated key mapping for indexer plugin * Add trigger to selection on tabbing * Minor shadow adjustments so its more similiar to default shell shadow. Added intro/outro animations * Added UWP-like scrollbar style for the results list * Fixed formating and naming * Removed Powerlauncher UI project * Update PowerToys.sln * Commented out scrollbar and fade in/out animations * Added missing features from UWP branch * Fixed formatting for Product.wxs * Add dragging to WPF window Co-authored-by: Clint Rutkas <clint@rutkas.com> Co-authored-by: Niels Laute <niels.laute@live.nl>
2020-06-02 03:35:37 +08:00
public static BitmapSource GetThumbnail(string fileName, int width, int height, ThumbnailOptions options)
{
IntPtr hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options);
try
{
return Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
finally
{
// delete HBitmap to avoid memory leaks
DeleteObject(hBitmap);
}
}
private static IntPtr GetHBitmap(string fileName, int width, int height, ThumbnailOptions options)
{
IShellItem nativeShellItem;
Guid shellItem2Guid = new Guid(IShellItem2Guid);
int retCode = SHCreateItemFromParsingName(fileName, IntPtr.Zero, ref shellItem2Guid, out nativeShellItem);
if (retCode != 0)
throw Marshal.GetExceptionForHR(retCode);
NativeSize nativeSize = new NativeSize
{
Width = width,
Height = height
};
IntPtr hBitmap;
HResult hr = ((IShellItemImageFactory)nativeShellItem).GetImage(nativeSize, options, out hBitmap);
// if extracting image thumbnail and failed, extract shell icon
if (options == ThumbnailOptions.ThumbnailOnly && hr == HResult.ExtractionFailed)
{
hr = ((IShellItemImageFactory)nativeShellItem).GetImage(nativeSize, ThumbnailOptions.IconOnly, out hBitmap);
}
Marshal.ReleaseComObject(nativeShellItem);
if (hr == HResult.Ok) return hBitmap;
throw new COMException($"Error while extracting thumbnail for {fileName}", Marshal.GetExceptionForHR((int)hr));
}
}
}