Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0131: Icons aus einer DLL extrahieren

 von 

Beschreibung 

Icons sind oft als Sammlung in einer entsprechenden dll verpackt. Windows bietet eine API die es erlaubt einerseits den Umfang der Kollektion zu bestimmen und andererseits die Bildchen gezielt auszulesen.

Update am 18. August 2003: Nach einem Hinweis von Chris wird nun auch die Funktion "DestroyIcon" genutzt.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

DestroyIcon, DrawIcon, ExtractIconA (ExtractIcon), GetSystemDirectoryA (GetSystemDirectory)

Download:

Download des Beispielprojektes [2,29 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'------------- Anfang Projektdatei Project1.vbp -------------
'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Bildfeld-Steuerelement "Picture1"
' Steuerelement: Schaltfläche "Command1"

Option Explicit

Private Declare Function GetSystemDirectory Lib "kernel32" _
        Alias "GetSystemDirectoryA" (ByVal lpBuffer As _
        String, ByVal nSize As Long) As Long
      
Private Declare Function ExtractIcon Lib "shell32.dll" Alias _
        "ExtractIconA" (ByVal hInst As Long, ByVal lpszExeFileName _
        As String, ByVal nIconIndex As Long) As Long

Private Declare Function DrawIcon Lib "user32" (ByVal hdc As Long, _
        ByVal x As Long, ByVal y As Long, ByVal hIcon As Long) _
        As Long

Private Declare Function DestroyIcon Lib "user32.dll" ( _
     ByVal hIcon As Long) As Long

Const MAX_PATH = 260&
      
Private Sub Command1_Click()
    Dim hIcon As Long
    Dim n As Long
    Dim MaxIcon As Long
    Dim Path As String
    Dim x As Long
    Dim y As Long
    
    'Systempfad ermitteln
    Path = Space$(MAX_PATH)
    Call GetSystemDirectory(Path, MAX_PATH)
    Path = Left$(Path, Len(Trim$(Path)) - 1) & "\Shell32.dll"
    
    'Maximale Iconanzahl durch nIconIndex = -1 auslesen
    MaxIcon = ExtractIcon(App.hInstance, Path, -1)
  
    Picture1.AutoRedraw = True
    
    'Icons Auslesen und ausgeben
    For y = 0 To MaxIcon Step 7
      For x = 0 To 7
        If n < MaxIcon + 1 Then
          hIcon = ExtractIcon(App.hInstance, Path, n)
          Call DrawIcon(Picture1.hdc, x * 32, Int(y / 7) * 32, hIcon)
          DestroyIcon hIcon
          n = n + 1
        End If
      Next x
    Next y
    
    'Neue Grafik ins Image
    Picture1.AutoRedraw = False
    Picture1.Refresh
End Sub
'---------- Ende Formular "Form1" alias Form1.frm  ----------
'-------------- Ende Projektdatei Project1.vbp --------------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 17 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von FanatiX am 14.02.2008 um 13:54

Probiers mal mit:
http://www.codeproject.com/KB/cs/iconhandler.aspx
und ggf.:
http://www.codechanger.com/

Das funkt auf jeden Fall ;)

Kommentar von Laurenz am 14.02.2008 um 12:40

Also der Code schaut bei mir jetzt so aus, aber funktioneren tut es leider immer noch nicht. :-(

Option Strict Off
Option Explicit On
Imports VB = Microsoft.VisualBasic
Friend Class Form1

Private Declare Function GetSystemDirectory Lib "kernel32" Alias "GetSystemDirectoryA"(ByVal lpBuffer As String, ByVal nSize As Integer) As Integer

Private Declare Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA"(ByVal hInst As Integer, ByVal lpszExeFileName As String, ByVal nIconIndex As Integer) As Integer

Private Declare Function DrawIcon Lib "user32" (ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer, ByVal hIcon As Integer) As Integer

Private Declare Function DestroyIcon Lib "user32.dll" (ByVal hIcon As Integer) As Integer

Const MAX_PATH As Short = 260

Private Sub Command1_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Command1.Click
Dim hIcon As Integer
Dim n As Integer
Dim MaxIcon As Integer
Dim Path As String
Dim x As Integer
Dim y As Integer

'Systempfad ermitteln
Path = Environ("SystemRoot") & "\system32\Shell32.dll"

'Maximale Iconanzahl durch nIconIndex = -1 auslesen
MaxIcon = ExtractIcon(VB6.GetHInstance.ToInt32, Path, -1)

'Icons Auslesen und ausgeben
For y = 0 To MaxIcon Step 7
For x = 0 To 7
If n < MaxIcon + 1 Then
hIcon = ExtractIcon(VB6.GetHInstance.ToInt32, Path, n)
'UPGRADE_ISSUE: PictureBox Eigenschaft Picture1.hdc wurde nicht aktualisiert. Klicken Sie hier für weitere Informationen: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="CC4C7EC0-C903-48FC-ACCC-81861D12DA4A"'
Call DrawIcon(Picture1.Handle, x * 32, Int(y / 7) * 32, hIcon)
DestroyIcon(hIcon)
n = n + 1
End If
Next x
Next y

'Neue Grafik ins Image
Picture1.Refresh()
MsgBox("rdy!")
End Sub

End Class

Kommentar von FanatiX am 14.02.2008 um 11:46

Autoredraw wird nicht mehr benötigt.
Picture1.hdc wird zu Picture1.Handle

Kommentar von Laurenz am 14.02.2008 um 10:41

Hi,
Bei VB.net bringt der bei folgenden sachen Fehler da es die scheinbar nimma gibt.was kann ich machen das es funktioniert?

'UPGRADE_ISSUE: PictureBox Eigenschaft Picture1.AutoRedraw wurde nicht aktualisiert. Klicken Sie hier für weitere Informationen: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="CC4C7EC0-C903-48FC-ACCC-81861D12DA4A"'
Picture1.AutoRedraw = True

'UPGRADE_ISSUE: PictureBox Eigenschaft Picture1.hdc wurde nicht aktualisiert. Klicken Sie hier für weitere Informationen: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="CC4C7EC0-C903-48FC-ACCC-81861D12DA4A"'
Call DrawIcon(Picture1.hdc, x * 32, Int(y / 7) * 32, hIcon)

'UPGRADE_ISSUE: PictureBox Eigenschaft Picture1.AutoRedraw wurde nicht aktualisiert. Klicken Sie hier für weitere Informationen: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="CC4C7EC0-C903-48FC-ACCC-81861D12DA4A"'
Picture1.AutoRedraw = False
mfg

Kommentar von NickiR am 15.11.2005 um 16:26

Hat sich erledigt, meine Pfade waren ungültig.

Meine Pfade enthielten beispielsweise Anführungszeichen, damit ich keine Probleme mit Leerzeichen im Pfad bekomme.
Damit kommt die ExtractIcon-Funktion nicht klar, sie interpretiert es als ungültigen Pfad.

MfG, NickiR

Kommentar von NickiR am 14.11.2005 um 08:48

Hi

Ich verwende den Code, um Icons aus EXE-Dateien auszulesen. Bei einigen Dateien funktioniert das aber nicht, z.B. bei der VB6.exe

Was kann ich in solchen Fällen tun?

MfG, NickiR

Kommentar von Jan am 20.05.2004 um 20:14

Kann man Icons auch in VB.NET auslesen?

Kommentar von ~Sammy~ am 19.04.2004 um 14:18

Hi

Das wurd ich auch gern wissen! Ich suche schon eine Ganze zeitlang nach einer Möglichkeit Icons in der Größe 48 x 48 auszulesen!

Kommentar von Jörn am 03.03.2004 um 16:43

an FanatiX: zuerst in die PictureBox zeichnen lassen, dann kannst Du z.B. mit "ImageList1.ListImages.Add i, , Picture1.Image" die ImageList füllen. Leider läßt die Qualität der Icons etwas nach...

Kommentar von FanatiX am 01.01.2004 um 11:57

hm praktischer wärs wenn man die icons erst in eine imagelist füllt, dann in eine imagecombo....dann könnte man auch ne beschreibung anbringen, sehr praktsich wenn man seine eigenen icons "zur schau stellen" möchte....aber die imagelist kann ja ned zeichnen :) gibts da ne lösung für? hab jetzt schon bestimmt den 20. versuch hinter mir und keine ideen mehr wies gehen könnte :(

Kommentar von Elmar am 02.05.2002 um 12:21

Oft gefragt: Wie kann ich nun selbst eine DLL erstellen, um aus dieser Icons zu extrahieren ?
Erstellen Sie einfach ein neues Projekt / ActiveX-DLL und erstellen Sie mit dem Res-Editor eine neue Resource. Fügen Sie nun beliebig viele Icons hinzu. Kompilieren Sie zu einer 'DLL'. Anhand der IDs können die Icons nun identifiziert bzw geladen /extrahiert werden.
MfG, Elmar

Kommentar von PhilippVB am 25.04.2002 um 20:59

An Bard: Mit ExtractIconEx kannst du die kleinen und die großen Symbole auslesen. 48 x 48 geht aber, glaube ich, nicht. Aber du kannst auch LoadImage verwenden.

Kommentar von Peter am 24.04.2002 um 19:53

Wie kann ich 'hIcon' in das 'IPictureDisp' Format umwandeln???

Kommentar von Chris am 23.04.2002 um 08:23

Dear ActiveVB!
This is a good source code, BUT!!!:
YOU MUST DESTROY THE ICON WHAT YOU EXTRACTED! PLEASE USE:
DestroyIcon function after every extraction ...
bye Chris.

Kommentar von Ferdinand am 14.08.2001 um 15:25

Ich habe ein Verschlüsselungs-Programm das unter Win 98 läuft aber nicht unter Win ME

Kommentar von Alex am 19.04.2001 um 09:16

P.S.: Alles was unter Windows 98 läuft, läuft unter WinME auch. Ich persönlich kenne kein einziges Programm oder API, dass unter Win98 läuft, unter WinME aber nicht. Gruss, Alex

Kommentar von Bard am 15.12.2000 um 15:05

Gibt es eine Möglichkeit zu bestimmen, dass nur große Icons (48x48) zurückgegeben werden?