Re: Problem mit dem Auslesen von Resourcendaten aus Resourcenblöcken einer Binärdatei,...
- From: Kerem Gümrükcü <kareem114@xxxxxxxxxxx>
- Date: Wed, 4 Mar 2009 08:46:50 +0100
Hallo,
ich habe mittlerweile eine Lösung für das Problem gefunden,
das sicher dem einen oder anderen auch eine große Hilfe sein
wird. Der Weg über das klassiche Laden mit folgenden Funktionen
zum Laden eines Icons oder Bitmaps ist viel zu kompliziert:
LoadLibraryEx
FindResource
LoadResource
LockResource
SizeOfResource
CopyMemory
FreeLibrary
Zwar bekommt man die rohen Daten der Resourcen, aber diese
sind de-facto, nicht vollständig und der Rest muss aus dem PE
sehr kompliziert und mit viel Speicher/Zeigergeschiebe kopiert werden.
Wenn man diesen Weg geht, dann muss man die PE Datei komplett
zerlegen um an die Header und Sektionsdaten zu kommen, was
ziemlich aufwendig und kompliziert sein kann. Es geht viel einfacher,..;-)
Zum laden eines Icons oder eines Bitmaps benötigt man nur eine
einzige Funktion: LoadImage(...)
[LoadImage Function]
http://msdn.microsoft.com/en-us/library/ms648045.aspx
Damit kann man sich gleich ein Icon, eine Bitmap, oder einen
Cursor aus einer Binärdatei holen. Intern sind diese Daten in
bestimmten Sektionen abgespeichert, z.b. ICON für Icons,
BITMAP für Bitmaps, etc,...wer mehr wissen will, der kann mal
eine native EXE/DLL schreiben, diese mit Icons, Cursor, Bitmaps
vollpacken und sich dann mit einem Resource-Viewer ansehen.
Natürlich kann die Datei auch benutzerdefinierte Resourcen haben,
aber das ist dann ein Fall für den klassichen, komplizierten Weg
oben, den ich nicht einschlagen will, zumindest für den Fall hier.
Um ein Icon zu laden, z.b. ein Icon aus der Shell32.dll, sagen wir
mal das Icon mit der Ordinalnummer "2049" benötigen wir den
"Icon Group". All diese Informationen bekommen wir mit den zwei Funktionen
EnumResourceNames (...) und EnumResourceTypes(...).
[EnumResourceNames Function]
http://msdn.microsoft.com/en-us/library/ms648037(VS.85).aspx
[http://msdn.microsoft.com/en-us/library/ms648039(VS.85).aspx]
Pinvokes dazu gibt es hier: www.pinvoke.net
Das erst mal am Rande erwähnt.
Die Hauptfunktion ist die LoadImage(...)
[LoadImage Function]
http://msdn.microsoft.com/en-us/library/ms648045.aspx
Jetzt kommt der Trick:
Schaut man sich die Funktion an und würde man diese
gemäß den Pinvoke/Marshalling Konventionen übersetzen,
dann würde die so aussehen:
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr LoadImage(IntPtr hinst, string lpszName, uint uType,
int cxDesired, int cyDesired, uint fuLoad);
Das ist auch richtig, aber wenn wir die ID, also die ID für das Groupicon haben,
dann nicht mehr, denn wenn man sich die Doku ansieht zu der Funktion ist
da ein Satz, der ziemlich unscheinbar aussieht, aber sehr wichtig ist:
"If the image resource is to be loaded by ordinal from the module, use the
MAKEINTRESOURCE macro to convert the image ordinal into a form that can
be passed to the LoadImage function."
Schauen wir uns das Makro an, so erkennen wir, das die LoadImage(...)
in wirklichkeit einen WORD erwartet, der in .NET konventionen einen
"UInt16" darstellt, bzw. einen "ushort":
Hier das Makro:
LPTSTR MAKEINTRESOURCE(
WORD wInteger
);
Übertragen wir das auf die LoadImage in der .NET Version, so
bekommen wir diese Funktion:
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr LoadImage(IntPtr hinst, ushort lpszName, uint uType,
int cxDesired, int cyDesired, uint fuLoad);
So können wir nun ein Icon, einen Cursor, oder eine Bitmap mit der
Ordinalzahl ohne Probleme laden. Der Rückgabewert ist ein HANDLE
also ein IntPtr das, jeh nach geladenem Typ, entweder ein Icon handle,
Cursor Handle, oder ein Bitmap Handle ist. Nun kann man mit den
..NET Klassen ganz einfach ein Icon/Bitmap/Cursor daraus erzeugen:
Icon icon = Icon.FromHandle(IconHandle);
Cursor cursor = new Cursor(CursorHandle);
Bitmap bitmap = Bitmap.FromHbitmap(BitmapHandle);
Das wars,...und ich habe mich wieder in den Tiefen der Bits
und Bytes verloren,.... :-D
Naja, ich hoffe, das hilft dem einen oder anderen,...
Hier sind noch die Pinvoke Übersetzungen, die ich
gemacht habe:
public enum LoadImageImageType : ushort
{
IMAGE_BITMAP = 0,
IMAGE_ICON = 1,
IMAGE_CURSOR = 2,
IMAGE_ENHMETAFILE = 3
}
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadImage(IntPtr hinst, ushort resourceId, LoadImageImageType ImageType,
int cxDesired, int cyDesired, uint fuLoad);
Mehr Informationen zu den Parametern der LoadImage(...) in der MSDN. Da geht
noch einiges, was man da noch von der Funktion "anfordern" kann,...
Grüße
Kerem
--
--
----------------------- Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Latest Project: http://www.pro-it-education.de/software/deviceremover
Latest Open-Source Projects: http://entwicklung.junetz.de
----------------------- "This reply is provided as is, without warranty express or implied."
.
- Follow-Ups:
- Re: Problem mit dem Auslesen von Resourcendaten aus Resourcenblöcken einer Binärdatei,...
- From: Thomas Scheidegger
- Re: Problem mit dem Auslesen von Resourcendaten aus Resourcenblöcken einer Binärdatei,...
- References:
- Prev by Date: WPF: Datenübergabe an Formular
- Next by Date: Re: Problem mit dem Auslesen von Resourcendaten aus Resourcenblöcken einer Binärdatei,...
- Previous by thread: Problem mit dem Auslesen von Resourcendaten aus Resourcenblöcken einer Binärdatei,...
- Next by thread: Re: Problem mit dem Auslesen von Resourcendaten aus Resourcenblöcken einer Binärdatei,...
- Index(es):
Relevant Pages
|