52

I'm making a custom error dialog in my WPF app and I want to use a standard windows error icon. Can I get the OS-specific icon from WPF? If not, does anyone know where to get .pngs with transparency of them? Or know where in Windows to go extract them from?

So far my searches have turned up nothing.

RandomEngy
  • 14,931
  • 5
  • 70
  • 113
  • Do you want the same image regardless of platform, or do you want the icon corresponding to the current version of Windows (including future versions)? – Ben Voigt Apr 03 '10 at 21:58
  • Ideally, an icon that looks like the standard icon for that version of Windows. But I can settle for just getting the standard for Vista/7. – RandomEngy Apr 03 '10 at 22:09

10 Answers10

40

There is a SystemIcons class, but it need adjustment for WPF needs (i.e. converting Icon to ImageSource).

Vijay Chavda
  • 826
  • 2
  • 15
  • 34
bohdan_trotsenko
  • 5,167
  • 3
  • 43
  • 70
  • 1
    You completely obviated the need for p/invoke. Good call. – Ben Voigt Apr 03 '10 at 22:00
  • 4
    by the way, http://stackoverflow.com/questions/1127647/convert-system-drawing-icon-to-system-media-imagesource, this may help – bohdan_trotsenko Apr 03 '10 at 22:20
  • 3
    That other thread has about four steps too many. Use http://msdn.microsoft.com/en-us/library/system.windows.interop.imaging.createbitmapsourcefromhicon(v=VS.90).aspx – Ben Voigt Apr 04 '10 at 02:05
  • 18
    Imaging.CreateBitmapSourceFromHIcon(SystemIcons.Error.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); - Seems to work great, thanks! – RandomEngy Apr 04 '10 at 04:22
  • Agreed. Also, that other thread does show the CreateBitmapSourceFromHIcon solution as well -- you just have to scroll down to see it (it isn't the accepted answer). – Richard Walters Oct 19 '11 at 18:44
29

The vast majority of developers out there don't know that Visual Studio comes with an Image Library. So here goes two links that highlight it:

About using Microsoft Visual Studio 2008 Image Library.

BurnsBA
  • 4,347
  • 27
  • 39
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
25

This is how I used a System icon in XAML:

xmlns:draw="clr-namespace:System.Drawing;assembly=System.Drawing"
...
<Image Source="{Binding Source={x:Static draw:SystemIcons.Warning},
        Converter={StaticResource IconToImageSourceConverter},
        Mode=OneWay}" />

I used this converter to turn an Icon to ImageSource:

public class IconToImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var icon = value as Icon;
        if (icon == null)
        {
            Trace.TraceWarning("Attempted to convert {0} instead of Icon object in IconToImageSourceConverter", value);
            return null;
        }

        ImageSource imageSource = Imaging.CreateBitmapSourceFromHIcon(
            icon.Handle,
            Int32Rect.Empty,
            BitmapSizeOptions.FromEmptyOptions());
        return imageSource;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
run2thesun
  • 358
  • 5
  • 12
  • Do you also have a custom extension method called ToImageSource() ? I couldn't find anything built in that would do that. – RandomEngy Apr 20 '15 at 20:50
  • Yes I forgot about that. I added the code from the extension method into the converter itself. – run2thesun Apr 20 '15 at 21:22
  • 1
    For error "IconToImageSourceConverter could not be resolved". The `converter` needs to be defined in the `FrameworkElement.Resource` element (i.e. Application, Window, UserControl). See SO answer: [https://stackoverflow.com/a/34351777/4962272](https://stackoverflow.com/a/34351777/4962272) – Matt M Oct 22 '20 at 16:16
6

In Visual Studio, use File + Open + File and select c:\windows\system32\user32.dll. Open the Icon node and double-click 103. On my machine that's the Error icon. Back, right-click it and select Export to save it to a file.

That's the iffy way. These icons are also available in Visual Studio. From your Visual Studio install directory, navigate to Common7\VS2008ImageLibrary\xxxx\VS2008ImageLibrary.zip + VS2008ImageLibrary\Annotations&Buttons\ico_format\WinVista\error.ico. The redist.txt file in the Visual Studio install directly explicitly gives you the right to use this icon in your own application.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Actually the unmanaged resource IDs are #defined in winuser.h and compiled into literally millions of programs by now. So they aren't changing. The index within the DLL, and even which DLL contains the system icons might change, but the resource ID never will. – Ben Voigt Apr 03 '10 at 21:54
  • @Ben: no, MB_ICONERROR has the value 0x10. Not close to the resource ID. Again: if you have special knowledge of how this works then, puhleze, post your own answer. – Hans Passant Apr 03 '10 at 22:36
  • You seem determined to make everything personal rather than let each technical topic stand alone. In this particular case, you might educate yourself by reading the answer I was typing as you posted yours and several hours before your comment. The resource ID OIC_HAND or equivalently OIC_ERROR, which is used with the MAKEINTRESOURCE macro, hasn't changed since LoadImage was introduced and never can, since it's compiled into millions of programs. – Ben Voigt Apr 04 '10 at 02:02
  • sorry, I was mistaken about the intervening time. It was just about one hour, not several hours before. – Ben Voigt Apr 04 '10 at 02:09
5

You can use .NET's SystemIcons class for roughly the first three steps if the default size is ok, see modosansreves answer

So it could be as simple as:

 Imaging.CreateBitmapSourceFromHIcon(SystemIcons.Error.Handle)
Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
4

Use this:

using System;
using System.Drawing;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Markup;
using System.Windows.Media.Imaging;

using Extensions
{
    [ContentProperty("Icon")]
    public class ImageSourceFromIconExtension : MarkupExtension
    {
        public Icon Icon { get; set; }

        public ImageSourceFromIconExtension()
        {
        }

        public ImageSourceFromIconExtension(Icon icon)
        {
            Icon = icon;
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return Imaging.CreateBitmapSourceFromHIcon(Icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
        }
    }
}

Don't forget to add System.Drawing reference to your project from global location.

Then use this in your xaml:

<WindowOrSomething x:Class="BlaBlaWindow"
    xmlns:draw="clr-namespace:System.Drawing;assembly=System.Drawing"
    xmlns:ext="clr-namespace:Extensions">
    <Image Source="{ext:ImageSourceFromIcon {x:Static draw:SystemIcons.Error}}"/>
</WindowOrSomething>
DileriumL
  • 41
  • 1
3

Can't you simply use Windows API?

Delphi Example:

procedure TForm1.FormClick(Sender: TObject);
var
  errIcon: HICON;
begin
  errIcon := LoadIcon(0, IDI_ERROR);
  DrawIcon(Canvas.Handle, 10, 10, errIcon)
end;
Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384
0

You can draw it like this:

Graphics g = this.CreateGraphics();
g.DrawIcon(SystemIcons.Question, 40, 40);
Hun1Ahpu
  • 3,315
  • 3
  • 28
  • 34
0

use SystemIcons and convert them to an ImageSource like so:

try   
{
    var temp = SystemIcons.WinLogo.ToBitmap();  //Your icon here
    BitmapImage bitmapImage = new BitmapImage();
    using (MemoryStream memory = new MemoryStream())
    {
       temp.Save(memory, ImageFormat.Png);
       memory.Position = 0;
       bitmapImage.BeginInit();
       bitmapImage.StreamSource = memory;
       bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
       bitmapImage.EndInit();
    }
    this.Icon = bitmapImage;
}
catch (Exception ex)
{
    this.Icon = null;
}
JKennedy
  • 18,150
  • 17
  • 114
  • 198
0

Convert SystemIcons.Error etc to .png (maintains transparency) then add output to resources and use as usual in WPF Image control.

    System.Drawing.SystemIcons.Error.ToBitmap().Save("Error.png", System.Drawing.Imaging.ImageFormat.Png);