C#/ WPF:获取shell使用的图标
我正在尝试开发一个应用程序,它可以显示目录的内容,如Windows资源管理器(带有文件名和图标)。 我目前正在使用此代码:
public class IconManager { public static ImageSource GetIcon(string path, bool smallIcon, bool isDirectory) { uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES; if (smallIcon) flags |= SHGFI_SMALLICON; uint attributes = FILE_ATTRIBUTE_NORMAL; if (isDirectory) attributes |= FILE_ATTRIBUTE_DIRECTORY; SHFILEINFO shfi; if (0 != SHGetFileInfo(path, attributes, out shfi, (uint)Marshal.SizeOf(typeof(SHFILEINFO)), flags)) { return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(shfi.hIcon, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); } return null; } [StructLayout(LayoutKind.Sequential)] private struct SHFILEINFO { public IntPtr hIcon; public int iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; } [DllImport("shell32")] private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags); private const uint FILE_ATTRIBUTE_READONLY = 0x00000001; private const uint FILE_ATTRIBUTE_HIDDEN = 0x00000002; private const uint FILE_ATTRIBUTE_SYSTEM = 0x00000004; private const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010; private const uint FILE_ATTRIBUTE_ARCHIVE = 0x00000020; private const uint FILE_ATTRIBUTE_DEVICE = 0x00000040; private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080; private const uint FILE_ATTRIBUTE_TEMPORARY = 0x00000100; private const uint FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200; private const uint FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400; private const uint FILE_ATTRIBUTE_COMPRESSED = 0x00000800; private const uint FILE_ATTRIBUTE_OFFLINE = 0x00001000; private const uint FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000; private const uint FILE_ATTRIBUTE_ENCRYPTED = 0x00004000; private const uint FILE_ATTRIBUTE_VIRTUAL = 0x00010000; private const uint SHGFI_ICON = 0x000000100; private const uint SHGFI_DISPLAYNAME = 0x000000200; private const uint SHGFI_TYPENAME = 0x000000400; private const uint SHGFI_ATTRIBUTES = 0x000000800; private const uint SHGFI_ICONLOCATION = 0x000001000; private const uint SHGFI_EXETYPE = 0x000002000; private const uint SHGFI_SYSICONINDEX = 0x000004000; private const uint SHGFI_LINKOVERLAY = 0x000008000; private const uint SHGFI_SELECTED = 0x000010000; private const uint SHGFI_ATTR_SPECIFIED = 0x000020000; private const uint SHGFI_LARGEICON = 0x000000000; private const uint SHGFI_SMALLICON = 0x000000001; private const uint SHGFI_OPENICON = 0x000000002; private const uint SHGFI_SHELLICONSIZE = 0x000000004; private const uint SHGFI_PIDL = 0x000000008; private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; }
我使用此代码来获取带有图标的文件和目录:
foreach (string d in Directory.GetDirectories(Path)) { string name = ""; foreach (string p in d.Split('\')) name = p; ImageSource icon = IconManager.GetIcon(d + "\", false, true); colDesktopItems.Add(new DesktopItem() { ItemName = name, ItemPath = d }); } foreach (string f in Directory.GetFiles(Path)) { if (File.GetAttributes(f) != FileAttributes.Hidden && File.GetAttributes(f) != FileAttributes.System) { string name = ""; foreach (string p in f.Split('\')) if (p.Contains(".")) name = p; ImageSource icon = IconManager.GetIcon(f, false, false); if (name != "desktop.ini" && name != "Thumbs.db") colDesktopItems.Add(new DesktopItem() { ItemName = name.Split('.')[0], ItemPath = f, ItemIcon = icon }); } }
我还使用DispatcherTimer
进行自动刷新(间隔= 5秒):
private void dpt_Tick(object sender, EventArgs e) { if (dPath != null) { if (GetContent(dPath).ToString() != diCollection.ToString()) { diCollection.Clear(); foreach (DesktopItem i in GetContent(dPath)) diCollection.Add(i); } } }
diCollection
是包含要显示的元素的集合, dPath
是从中显示文件的目录的路径。
但是有两个问题:
该值可能不是NULL。 此行中发生exception:
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(shfi.hIcon, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
我使用相同的方法。 以下是我在我的个人图书馆中设置的方法。
public static class ImageUtilities { public static System.Drawing.Icon GetRegisteredIcon(string filePath) { var shinfo = new SHfileInfo(); Win32.SHGetFileInfo(filePath, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | Win32.SHGFI_SMALLICON); return System.Drawing.Icon.FromHandle(shinfo.hIcon); } } [StructLayout(LayoutKind.Sequential)] public struct SHfileInfo { public IntPtr hIcon; public int iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; } internal sealed class Win32 { public const uint SHGFI_ICON = 0x100; public const uint SHGFI_LARGEICON = 0x0; // large public const uint SHGFI_SMALLICON = 0x1; // small [System.Runtime.InteropServices.DllImport("shell32.dll")] public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHfileInfo psfi, uint cbSizeFileInfo, uint uFlags); }
用法:
var icon = ImageUtilites.GetRegisteredIcon(string path)
我用来为WPF创建一个ImageSource的Extension方法:
public static System.Windows.Media.ImageSource ToImageSource(this System.Drawing.Bitmap bitmap, int width, int height) { var hBitmap = bitmap.GetHbitmap(); System.Windows.Media.ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( hBitmap, IntPtr.Zero, System.Windows.Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromWidthAndHeight(width, height)); if (!DeleteObject(hBitmap)) { throw new System.ComponentModel.Win32Exception(); } return wpfBitmap; }
我忘了添加这个,我不知道你是否正在使用它..
上述就是C#学习教程:C#/ WPF:获取shell使用的图标分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
[DllImport("gdi32.dll", SetLastError = true)] private static extern bool DeleteObject(IntPtr hObject);
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/997366.html