Files
QuickLook/QuickLook.Plugin.LastResort/IconHelper.cs

256 lines
7.2 KiB
C#

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;
}
}