Benutzer mit den meisten Antworten
Windows Icons in 256*256er größe auslesen

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/
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:
Sag mir Bescheid, wenn Du Hilfe brauchst.
- Bearbeitet Marcel RomaModerator Freitag, 27. April 2012 23:28 Code und Screenshot hinzugefügt
- Als Antwort vorgeschlagen Stefan FalzModerator Freitag, 27. April 2012 23:30
- Als Antwort markiert Tom Lambert (Koopakiller)Moderator Samstag, 28. April 2012 09:59
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 -
-
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 -
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:
Sag mir Bescheid, wenn Du Hilfe brauchst.
- Bearbeitet Marcel RomaModerator Freitag, 27. April 2012 23:28 Code und Screenshot hinzugefügt
- Als Antwort vorgeschlagen Stefan FalzModerator Freitag, 27. April 2012 23:30
- Als Antwort markiert Tom Lambert (Koopakiller)Moderator Samstag, 28. April 2012 09:59