在我的代码中,我希望我的用户能够从其计算机上的任何位置选择一个图标。该图标可以是独立的.ico
,也可以是.exe
或.dll
中的图标-不仅是.exe/dll
的默认显示图标,而且以及其中包含的任何其他图标。
在理想的世界中,我希望能够使用此本机Windows图标选择器对话框:
但是我不知道如何使用它-可能吗?
该对话框对我来说非常理想,因为它似乎只允许用户浏览图标或标准浏览.exe
和.dll
。
如果我的用户只能使用独立的.ico
文件,那么我将采用在CommonOpenFileDialog
nuget包中为Windows Visa +和{{ 1}}(对于较旧的系统),如下所示:
Microsoft.WindowsAPICodePack-Shell
但是据我所知,这条路线不会允许我的用户从System.Windows.Forms.FolderBrowserDialog
中选择图标?
如果无法使用“图标选择器”对话框,是否有另一种方法可以从private string SelectWinXPIcon()
{
using (WinForms.OpenFileDialog ofd = new WinForms.OpenFileDialog()
{
Filter = "Icon files (*.ico)|*.ico",
})
{
WinForms.DialogResult result = ofd.ShowDialog();
switch (result)
{
case WinForms.DialogResult.OK:
case WinForms.DialogResult.Yes:
return ofd.FileName;
default:
return null;
}
}
}
private string SelectWinVistaIcon()
{
using (CommonOpenFileDialog dialog = new CommonOpenFileDialog
{
DefaultDirectory = @"C:\",
AllowNonFileSystemItems = false,
EnsurePathExists = true,
Multiselect = false,
NavigateToShortcut = true
})
{
dialog.Filters.Add(new CommonFileDialogFilter("Icon Files (*.ico)", ".ico"));
CommonFileDialogResult result = dialog.ShowDialog();
switch (result)
{
case CommonFileDialogResult.Ok:
return dialog.FileName;
default:
return null;
}
}
}
中提取图标,从而还可以选择独立的.exe/dll
文件?>
答案 0 :(得分:3)
这是通过shell32 PickIconDlg函数完成的,您可以使用pinvoke site轻松调用该函数以供参考。该函数将返回文件名和索引,然后您可以使用the shell32 ExtractIconEx function提取图标句柄。然后,您可以将图标手柄转换为GDI图标或WPF ImageSource。
例如,在XAML中声明一个图像以显示用户选择的图标:
<Image x:Name="myImage" Stretch="None" />
然后在窗口加载处理程序中使用以下代码来显示对话框,加载该对话框,将其转换为ImageSource并显示它:
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern int PickIconDlg(IntPtr hwndOwner, System.Text.StringBuilder lpstrFile, int nMaxFile, ref int lpdwIconIndex);
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern uint ExtractIconEx(string szFileName, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, uint nIcons);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern bool DestroyIcon(IntPtr handle);
private const int MAX_PATH = 0x00000104;
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
// show the Pick Icon Dialog
int index = 0;
int retval;
var handle = new WindowInteropHelper(this).Handle;
var iconfile = Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\shell32.dll";
var sb = new System.Text.StringBuilder(iconfile, MAX_PATH);
retval = PickIconDlg(handle, sb, sb.MaxCapacity, ref index);
if (retval != 0)
{
// extract the icon
var largeIcons = new IntPtr[1];
var smallIcons = new IntPtr[1];
ExtractIconEx(sb.ToString(), index, largeIcons, smallIcons, 1);
// convert icon handle to ImageSource
this.myImage.Source = Imaging.CreateBitmapSourceFromHIcon(largeIcons[0],
Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
// clean up
DestroyIcon(largeIcons[0]);
DestroyIcon(smallIcons[0]);
}
}
它将与DLL / EXE等以及独立的.ICO文件一起使用。