mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-13 02:39:22 +08:00
Add image loader class
This commit is contained in:
parent
e8f3a30a72
commit
855d75f1bb
@ -1,230 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Wox.Helper;
|
||||
|
||||
namespace Wox.Converters
|
||||
{
|
||||
public class ImagePathConverter : IMultiValueConverter
|
||||
{
|
||||
private static readonly Dictionary<string, object> imageCache = new Dictionary<string, object>();
|
||||
|
||||
private static readonly List<string> imageExts = new List<string>
|
||||
{
|
||||
".png",
|
||||
".jpg",
|
||||
".jpeg",
|
||||
".gif",
|
||||
".bmp",
|
||||
".tiff",
|
||||
".ico"
|
||||
};
|
||||
|
||||
private static readonly List<string> selfExts = new List<string>
|
||||
{
|
||||
".exe",
|
||||
".lnk",
|
||||
".ani",
|
||||
".cur",
|
||||
".sln",
|
||||
".appref-ms"
|
||||
};
|
||||
|
||||
private static ImageSource GetIcon(string fileName)
|
||||
{
|
||||
Icon icon = GetFileIcon(fileName);
|
||||
if (icon == null) icon = Icon.ExtractAssociatedIcon(fileName);
|
||||
|
||||
if (icon != null)
|
||||
{
|
||||
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(icon.Handle,
|
||||
new Int32Rect(0, 0, icon.Width, icon.Height), BitmapSizeOptions.FromEmptyOptions());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
object img;
|
||||
if (values[0] == null) return null;
|
||||
|
||||
string path = values[0].ToString();
|
||||
if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new BitmapImage(new Uri(path));
|
||||
}
|
||||
|
||||
string relativePath = values[0].ToString();
|
||||
string pluginDirectory = values[1].ToString();
|
||||
string fullPath = Path.Combine(pluginDirectory, path);
|
||||
string ext = Path.GetExtension(path).ToLower();
|
||||
if (imageCache.ContainsKey(fullPath))
|
||||
{
|
||||
return imageCache[fullPath];
|
||||
}
|
||||
if (!selfExts.Contains(ext) && imageCache.ContainsKey(ext))
|
||||
{
|
||||
return imageCache[ext];
|
||||
}
|
||||
string fullPath = Path.Combine(pluginDirectory, relativePath);
|
||||
|
||||
string resolvedPath = string.Empty;
|
||||
if (!string.IsNullOrEmpty(path) && path.Contains(":\\") && File.Exists(path))
|
||||
if (relativePath.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
resolvedPath = path;
|
||||
return new BitmapImage(new Uri(relativePath));
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(path) && File.Exists(fullPath))
|
||||
{
|
||||
resolvedPath = fullPath;
|
||||
}
|
||||
string extn = Path.GetExtension(resolvedPath).ToLower();
|
||||
|
||||
var cacheKey = fullPath;
|
||||
if (selfExts.Contains(extn))
|
||||
{
|
||||
img = GetIcon(resolvedPath);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(resolvedPath) && imageExts.Contains(ext) && File.Exists(resolvedPath))
|
||||
{
|
||||
img = new BitmapImage(new Uri(resolvedPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
img = GetIcon(resolvedPath);
|
||||
if (!selfExts.Contains(ext)) cacheKey = ext;
|
||||
}
|
||||
|
||||
if (img != null)
|
||||
{
|
||||
imageCache.Add(cacheKey, img);
|
||||
}
|
||||
|
||||
return img;
|
||||
return ImageLoader.Load(fullPath);
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// http://blogs.msdn.com/b/oldnewthing/archive/2011/01/27/10120844.aspx
|
||||
public static Icon GetFileIcon(string name)
|
||||
{
|
||||
SHFILEINFO shfi = new SHFILEINFO();
|
||||
uint flags = SHGFI_SYSICONINDEX;
|
||||
|
||||
IntPtr himl = SHGetFileInfo(name,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
ref shfi,
|
||||
(uint) Marshal.SizeOf(shfi),
|
||||
flags);
|
||||
|
||||
if (himl != IntPtr.Zero)
|
||||
{
|
||||
IntPtr hIcon = ImageList_GetIcon(himl, shfi.iIcon, ILD_NORMAL);
|
||||
var icon = (Icon) Icon.FromHandle(hIcon).Clone();
|
||||
DestroyIcon(hIcon);
|
||||
return icon;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
[DllImport("comctl32.dll", SetLastError = true)]
|
||||
private static extern IntPtr ImageList_GetIcon(IntPtr himl, int i, uint flags);
|
||||
|
||||
private const int MAX_PATH = 256;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct SHITEMID
|
||||
{
|
||||
public ushort cb;
|
||||
[MarshalAs(UnmanagedType.LPArray)] public byte[] abID;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct ITEMIDLIST
|
||||
{
|
||||
public SHITEMID mkid;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct BROWSEINFO
|
||||
{
|
||||
public IntPtr hwndOwner;
|
||||
public IntPtr pidlRoot;
|
||||
public IntPtr pszDisplayName;
|
||||
[MarshalAs(UnmanagedType.LPTStr)] public string lpszTitle;
|
||||
public uint ulFlags;
|
||||
public IntPtr lpfn;
|
||||
public int lParam;
|
||||
public IntPtr iImage;
|
||||
}
|
||||
|
||||
// Browsing for directory.
|
||||
private const uint BIF_RETURNONLYFSDIRS = 0x0001;
|
||||
private const uint BIF_DONTGOBELOWDOMAIN = 0x0002;
|
||||
private const uint BIF_STATUSTEXT = 0x0004;
|
||||
private const uint BIF_RETURNFSANCESTORS = 0x0008;
|
||||
private const uint BIF_EDITBOX = 0x0010;
|
||||
private const uint BIF_VALIDATE = 0x0020;
|
||||
private const uint BIF_NEWDIALOGSTYLE = 0x0040;
|
||||
private const uint BIF_USENEWUI = (BIF_NEWDIALOGSTYLE | BIF_EDITBOX);
|
||||
private const uint BIF_BROWSEINCLUDEURLS = 0x0080;
|
||||
private const uint BIF_BROWSEFORCOMPUTER = 0x1000;
|
||||
private const uint BIF_BROWSEFORPRINTER = 0x2000;
|
||||
private const uint BIF_BROWSEINCLUDEFILES = 0x4000;
|
||||
private const uint BIF_SHAREABLE = 0x8000;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct SHFILEINFO
|
||||
{
|
||||
public const int NAMESIZE = 80;
|
||||
public IntPtr hIcon;
|
||||
public int iIcon;
|
||||
public uint dwAttributes;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)] public string szDisplayName;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NAMESIZE)] public string szTypeName;
|
||||
};
|
||||
|
||||
private const uint SHGFI_ICON = 0x000000100; // get icon
|
||||
private const uint SHGFI_DISPLAYNAME = 0x000000200; // get display name
|
||||
private const uint SHGFI_TYPENAME = 0x000000400; // get type name
|
||||
private const uint SHGFI_ATTRIBUTES = 0x000000800; // get attributes
|
||||
private const uint SHGFI_ICONLOCATION = 0x000001000; // get icon location
|
||||
private const uint SHGFI_EXETYPE = 0x000002000; // return exe type
|
||||
private const uint SHGFI_SYSICONINDEX = 0x000004000; // get system icon index
|
||||
private const uint SHGFI_LINKOVERLAY = 0x000008000; // put a link overlay on icon
|
||||
private const uint SHGFI_SELECTED = 0x000010000; // show icon in selected state
|
||||
private const uint SHGFI_ATTR_SPECIFIED = 0x000020000; // get only specified attributes
|
||||
private const uint SHGFI_LARGEICON = 0x000000000; // get large icon
|
||||
private const uint SHGFI_SMALLICON = 0x000000001; // get small icon
|
||||
private const uint SHGFI_OPENICON = 0x000000002; // get open icon
|
||||
private const uint SHGFI_SHELLICONSIZE = 0x000000004; // get shell size icon
|
||||
private const uint SHGFI_PIDL = 0x000000008; // pszPath is a pidl
|
||||
private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; // use passed dwFileAttribute
|
||||
private const uint SHGFI_ADDOVERLAYS = 0x000000020; // apply the appropriate overlays
|
||||
private const uint SHGFI_OVERLAYINDEX = 0x000000040; // Get the index of the overlay
|
||||
|
||||
private const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
|
||||
private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
|
||||
private const uint ILD_NORMAL = 0x00000000;
|
||||
|
||||
[DllImport("Shell32.dll")]
|
||||
private static extern IntPtr SHGetFileInfo(
|
||||
string pszPath,
|
||||
uint dwFileAttributes,
|
||||
ref SHFILEINFO psfi,
|
||||
uint cbFileInfo,
|
||||
uint uFlags
|
||||
);
|
||||
|
||||
[DllImport("User32.dll")]
|
||||
private static extern int DestroyIcon(IntPtr hIcon);
|
||||
}
|
||||
}
|
217
Wox/Helper/ImageLoader.cs
Normal file
217
Wox/Helper/ImageLoader.cs
Normal file
@ -0,0 +1,217 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Wox.Helper
|
||||
{
|
||||
public class ImageLoader
|
||||
{
|
||||
private static readonly Dictionary<string, ImageSource> imageCache = new Dictionary<string, ImageSource>();
|
||||
private static object locker = new object();
|
||||
|
||||
private static readonly List<string> imageExts = new List<string>
|
||||
{
|
||||
".png",
|
||||
".jpg",
|
||||
".jpeg",
|
||||
".gif",
|
||||
".bmp",
|
||||
".tiff",
|
||||
".ico"
|
||||
};
|
||||
|
||||
private static readonly List<string> selfExts = new List<string>
|
||||
{
|
||||
".exe",
|
||||
".lnk",
|
||||
".ani",
|
||||
".cur",
|
||||
".sln",
|
||||
".appref-ms"
|
||||
};
|
||||
|
||||
private static ImageSource GetIcon(string fileName)
|
||||
{
|
||||
Icon icon = GetFileIcon(fileName);
|
||||
if (icon == null) icon = Icon.ExtractAssociatedIcon(fileName);
|
||||
|
||||
if (icon != null)
|
||||
{
|
||||
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(icon.Handle,
|
||||
new Int32Rect(0, 0, icon.Width, icon.Height), BitmapSizeOptions.FromEmptyOptions());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ImageSource Load(string path)
|
||||
{
|
||||
ImageSource img = null;
|
||||
if (path == null) return null;
|
||||
if (imageCache.ContainsKey(path))
|
||||
{
|
||||
return imageCache[path];
|
||||
}
|
||||
|
||||
string ext = Path.GetExtension(path).ToLower();
|
||||
string resolvedPath = string.Empty;
|
||||
if (!string.IsNullOrEmpty(path) && path.Contains(":\\") && File.Exists(path))
|
||||
{
|
||||
resolvedPath = path;
|
||||
}
|
||||
|
||||
if (selfExts.Contains(ext))
|
||||
{
|
||||
img = GetIcon(resolvedPath);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(resolvedPath) && imageExts.Contains(ext) && File.Exists(resolvedPath))
|
||||
{
|
||||
img = new BitmapImage(new Uri(resolvedPath));
|
||||
}
|
||||
|
||||
if (img != null)
|
||||
{
|
||||
if (!imageCache.ContainsKey(path))
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
if (!imageCache.ContainsKey(path))
|
||||
{
|
||||
imageCache.Add(path, img);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
// http://blogs.msdn.com/b/oldnewthing/archive/2011/01/27/10120844.aspx
|
||||
private static Icon GetFileIcon(string name)
|
||||
{
|
||||
SHFILEINFO shfi = new SHFILEINFO();
|
||||
uint flags = SHGFI_SYSICONINDEX;
|
||||
|
||||
IntPtr himl = SHGetFileInfo(name,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
ref shfi,
|
||||
(uint)Marshal.SizeOf(shfi),
|
||||
flags);
|
||||
|
||||
if (himl != IntPtr.Zero)
|
||||
{
|
||||
IntPtr hIcon = ImageList_GetIcon(himl, shfi.iIcon, ILD_NORMAL);
|
||||
var icon = (Icon)Icon.FromHandle(hIcon).Clone();
|
||||
DestroyIcon(hIcon);
|
||||
return icon;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
[DllImport("comctl32.dll", SetLastError = true)]
|
||||
private static extern IntPtr ImageList_GetIcon(IntPtr himl, int i, uint flags);
|
||||
|
||||
private const int MAX_PATH = 256;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct SHITEMID
|
||||
{
|
||||
public ushort cb;
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
public byte[] abID;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct ITEMIDLIST
|
||||
{
|
||||
public SHITEMID mkid;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct BROWSEINFO
|
||||
{
|
||||
public IntPtr hwndOwner;
|
||||
public IntPtr pidlRoot;
|
||||
public IntPtr pszDisplayName;
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
public string lpszTitle;
|
||||
public uint ulFlags;
|
||||
public IntPtr lpfn;
|
||||
public int lParam;
|
||||
public IntPtr iImage;
|
||||
}
|
||||
|
||||
// Browsing for directory.
|
||||
private const uint BIF_RETURNONLYFSDIRS = 0x0001;
|
||||
private const uint BIF_DONTGOBELOWDOMAIN = 0x0002;
|
||||
private const uint BIF_STATUSTEXT = 0x0004;
|
||||
private const uint BIF_RETURNFSANCESTORS = 0x0008;
|
||||
private const uint BIF_EDITBOX = 0x0010;
|
||||
private const uint BIF_VALIDATE = 0x0020;
|
||||
private const uint BIF_NEWDIALOGSTYLE = 0x0040;
|
||||
private const uint BIF_USENEWUI = (BIF_NEWDIALOGSTYLE | BIF_EDITBOX);
|
||||
private const uint BIF_BROWSEINCLUDEURLS = 0x0080;
|
||||
private const uint BIF_BROWSEFORCOMPUTER = 0x1000;
|
||||
private const uint BIF_BROWSEFORPRINTER = 0x2000;
|
||||
private const uint BIF_BROWSEINCLUDEFILES = 0x4000;
|
||||
private const uint BIF_SHAREABLE = 0x8000;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct SHFILEINFO
|
||||
{
|
||||
public const int NAMESIZE = 80;
|
||||
public IntPtr hIcon;
|
||||
public int iIcon;
|
||||
public uint dwAttributes;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
|
||||
public string szDisplayName;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NAMESIZE)]
|
||||
public string szTypeName;
|
||||
};
|
||||
|
||||
private const uint SHGFI_ICON = 0x000000100; // get icon
|
||||
private const uint SHGFI_DISPLAYNAME = 0x000000200; // get display name
|
||||
private const uint SHGFI_TYPENAME = 0x000000400; // get type name
|
||||
private const uint SHGFI_ATTRIBUTES = 0x000000800; // get attributes
|
||||
private const uint SHGFI_ICONLOCATION = 0x000001000; // get icon location
|
||||
private const uint SHGFI_EXETYPE = 0x000002000; // return exe type
|
||||
private const uint SHGFI_SYSICONINDEX = 0x000004000; // get system icon index
|
||||
private const uint SHGFI_LINKOVERLAY = 0x000008000; // put a link overlay on icon
|
||||
private const uint SHGFI_SELECTED = 0x000010000; // show icon in selected state
|
||||
private const uint SHGFI_ATTR_SPECIFIED = 0x000020000; // get only specified attributes
|
||||
private const uint SHGFI_LARGEICON = 0x000000000; // get large icon
|
||||
private const uint SHGFI_SMALLICON = 0x000000001; // get small icon
|
||||
private const uint SHGFI_OPENICON = 0x000000002; // get open icon
|
||||
private const uint SHGFI_SHELLICONSIZE = 0x000000004; // get shell size icon
|
||||
private const uint SHGFI_PIDL = 0x000000008; // pszPath is a pidl
|
||||
private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; // use passed dwFileAttribute
|
||||
private const uint SHGFI_ADDOVERLAYS = 0x000000020; // apply the appropriate overlays
|
||||
private const uint SHGFI_OVERLAYINDEX = 0x000000040; // Get the index of the overlay
|
||||
|
||||
private const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
|
||||
private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
|
||||
private const uint ILD_NORMAL = 0x00000000;
|
||||
|
||||
[DllImport("Shell32.dll")]
|
||||
private static extern IntPtr SHGetFileInfo(
|
||||
string pszPath,
|
||||
uint dwFileAttributes,
|
||||
ref SHFILEINFO psfi,
|
||||
uint cbFileInfo,
|
||||
uint uFlags
|
||||
);
|
||||
|
||||
[DllImport("User32.dll")]
|
||||
private static extern int DestroyIcon(IntPtr hIcon);
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Wox.Helper;
|
||||
using Wox.Plugin;
|
||||
using UserControl = System.Windows.Controls.UserControl;
|
||||
|
||||
@ -23,6 +26,7 @@ namespace Wox
|
||||
|
||||
public void AddResults(List<Result> results)
|
||||
{
|
||||
|
||||
if (Dirty)
|
||||
{
|
||||
Dirty = false;
|
||||
@ -30,6 +34,10 @@ namespace Wox
|
||||
}
|
||||
foreach (var result in results)
|
||||
{
|
||||
//ThreadPool.QueueUserWorkItem(delegate
|
||||
// {
|
||||
// ImageLoader.Load(Path.Combine(result.PluginDirectory, result.IcoPath));
|
||||
// });
|
||||
int position = GetInsertLocation(result.Score);
|
||||
lbResults.Items.Insert(position, result);
|
||||
}
|
||||
|
@ -120,6 +120,7 @@
|
||||
</Compile>
|
||||
<Compile Include="Helper\FontHelper.cs" />
|
||||
<Compile Include="Helper\Forker.cs" />
|
||||
<Compile Include="Helper\ImageLoader.cs" />
|
||||
<Compile Include="Helper\SyntaxSugars.cs" />
|
||||
<Compile Include="Helper\WallpaperPathRetrieval.cs" />
|
||||
<Compile Include="Helper\WindowIntelopHelper.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user