none
Windows Icons in 256*256er größe auslesen RRS feed

  • Frage

  • Ich muss einige SystemIcons (IDI_ERROR, IDI_WARNING, ...) im 256 Pixelformat in ein ImageSource einlesen. Ich probiere jetzt schon ca. 2 Stunden mit LoadIcon herum, doch es wird nicht sorecht etwas:

                                ImageSource _Icon = Imaging.CreateBitmapSourceFromHIcon(
                                    drw.Icon.FromHandle(User32.LoadIcon(IntPtr.Zero, (IntPtr)WinMsg.IDI_ERROR)).Handle,
                                    new Int32Rect(0, 0, 32, 32), //Wenn ich 256 angebe kommt eine Exception
                                    BitmapSizeOptions.FromEmptyOptions()); 
                [DllImport("user32.dll", CharSet = CharSet.Unicode)]
                public static extern IntPtr LoadIcon(IntPtr hInstance, IntPtr lpIconName);

    Wenn die Version unter Vista (Ich weiß wie man das heraus bekommt) liegt brauche ich die Icons natürlich nur in der größtmöglichen auflösung, also 32 (oder 48?) Pixel.

    Wie stelle ich das am besten an?


    Koopakiller - http://koopakiller.ko.ohost.de/

    Freitag, 27. April 2012 17:24
    Moderator

Antworten

  • Du findest natürlich auch viele andere Libraries mit vielen anderen Icons in vielen anderen Resolutionen. Wenn Du sie extrahieren willst, dann mußt Du nicht über die Shell (wie oben geschehen) gehen, sondern über die PrivateExtractIcons-Funktion.

    Die Funktion ermöglicht es, die gewünschte Größe des zu extrahierenden Icons direkt anzugeben, was deinem Zweck entgegenkommt. Als Output-Parameter erhälts Du dann bei Erfolg ein Icon-Handle sowie eine Resourcen-ID. 

    Hier eine erste Skizze dazu:

        public class IconExtractor
        {
            [DllImport("User32.dll")]
            public extern static int PrivateExtractIcons(string libraryName, int iconIndex, int iconWidth, int iconHeight, out IntPtr iconHandles, out IntPtr iconID, int numberIcons, IntPtr flags);
            private string libraryName;
            private IntPtr iconHandle;
            private IntPtr iconID;
            public IconExtractor(string libraryName)
            {
                this.libraryName = libraryName;
            }
            public Icon GetIcon(int iconIndex, int size)
            {
                PrivateExtractIcons(this.libraryName, iconIndex, size, size, out iconHandle, out iconID, 1, IntPtr.Zero);
                if(iconHandle != IntPtr.Zero) return Icon.FromHandle(iconHandle);
                return null;
            }
        }

    Das Error-Symbol findest Du - wenn ich nicht irre - unter Index 93. Und so sieht eine einfache Testanwendung aus:

    Icon Extractor Tool

    Sag mir Bescheid, wenn Du Hilfe brauchst.


    Freitag, 27. April 2012 22:33
    Moderator

Alle Antworten

  • Hallo,

    Ex nihilo nihil fit. Wenn die Icons in der gewünschten Resolution nicht verfügbar sind, kannst Du die vorhandenen Bitmaps höchstens skalieren, was aber zu unscharfen Kanten und verpixelten Oberflächen führt. Auf Windows 7 kannst Du über das Windows API Code Pack auf die sog. StockIcons direkt zugreifen. Aber auch hier ist das Error-Icon keine 255 Pixel breit:

    using System;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Interop;
    using System.Drawing;
    using Microsoft.WindowsAPICodePack.Shell;
    namespace WpfApplication3
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
            private void Grid_Loaded(object sender, RoutedEventArgs e)
            {
                // Über GDI+: Gibt ein 32x32 Bitmap zurück
                ImageSource imageSource = Imaging.CreateBitmapSourceFromHIcon(SystemIcons.Error.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                // Über GDI+: Gibt ein auf 255x255 skaliertes Bitmap zurück, unscharf natürlich
                // ImageSource imageSource = Imaging.CreateBitmapSourceFromHIcon(SystemIcons.Error.Handle, Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight(255, 255));
                image1.Source = imageSource;
                // Windows 7 (über Microsoft.WindowsAPICodePack): Gibt für Large ein 42x42 Bitmap zurück
                StockIcons stockIcons = new StockIcons(StockIconSize.Large, false, false);
                StockIcon errorIcon = stockIcons.Error;
                image2.Source = errorIcon.BitmapSource;
            }
        }
    }

    Gruß
    Marcel

    Freitag, 27. April 2012 20:52
    Moderator
  • Mmh, da frag ich mich aber warum ich dann in der imageres.dll eine Version des Icons mit 256*256 Pixeln vorfinde:
    In VS geöffnet hat das Icon die Nummer 94, in Axialis Icon Workshop die 94.

    Koopakiller - http://koopakiller.ko.ohost.de/

    Freitag, 27. April 2012 21:06
    Moderator
  • Mmh, da frag ich mich aber warum ich dann in der imageres.dll eine Version des Icons mit 256*256 Pixeln vorfinde:

    IDI_ERROR dürfte aber das Error Icon aus der User32.dll sein. Und das gibt es, im Gegensatz zu IDI_SHIELD nur mit maximal 48x48 Pixel.

    Wenn Du das große Icon willst, musst Du das Icon explizit aus der imageres.dll auslesen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Freitag, 27. April 2012 22:20
    Moderator
  • Gut, wenn die dort drinn liegen ist mir das natürlich klar...

    Kennt vielleicht jemand eine Methode aus der imageres.dll zum auslesen, oder muss ich dafür ebenfalls LoadIcon benutzen?


    Koopakiller - http://koopakiller.ko.ohost.de/

    Freitag, 27. April 2012 22:24
    Moderator
  • Du findest natürlich auch viele andere Libraries mit vielen anderen Icons in vielen anderen Resolutionen. Wenn Du sie extrahieren willst, dann mußt Du nicht über die Shell (wie oben geschehen) gehen, sondern über die PrivateExtractIcons-Funktion.

    Die Funktion ermöglicht es, die gewünschte Größe des zu extrahierenden Icons direkt anzugeben, was deinem Zweck entgegenkommt. Als Output-Parameter erhälts Du dann bei Erfolg ein Icon-Handle sowie eine Resourcen-ID. 

    Hier eine erste Skizze dazu:

        public class IconExtractor
        {
            [DllImport("User32.dll")]
            public extern static int PrivateExtractIcons(string libraryName, int iconIndex, int iconWidth, int iconHeight, out IntPtr iconHandles, out IntPtr iconID, int numberIcons, IntPtr flags);
            private string libraryName;
            private IntPtr iconHandle;
            private IntPtr iconID;
            public IconExtractor(string libraryName)
            {
                this.libraryName = libraryName;
            }
            public Icon GetIcon(int iconIndex, int size)
            {
                PrivateExtractIcons(this.libraryName, iconIndex, size, size, out iconHandle, out iconID, 1, IntPtr.Zero);
                if(iconHandle != IntPtr.Zero) return Icon.FromHandle(iconHandle);
                return null;
            }
        }

    Das Error-Symbol findest Du - wenn ich nicht irre - unter Index 93. Und so sieht eine einfache Testanwendung aus:

    Icon Extractor Tool

    Sag mir Bescheid, wenn Du Hilfe brauchst.


    Freitag, 27. April 2012 22:33
    Moderator
  • Vielen Dank!

    So funktionierts :) :) :)


    Koopakiller - http://koopakiller.ko.ohost.de/

    Samstag, 28. April 2012 09:59
    Moderator