Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0668: 24Bit- und 32Bit-Icons aus Ressource laden und anzeigen

 von 

Beschreibung 

24 Bit- und 32 Bit-Icons können nicht mit dem Ressourceneditor als normale Iconressource geladen werden. Diese Beispiel zeigt, wie es dennoch funktioniert. Man muss das Icon als "CUSTOM"-Ressource einbinden und mit diesem Code können dann auch 24 Bit- und 32 Bit-Icons wieder geladen und angezeigt werden.

Schwierigkeitsgrad:

Schwierigkeitsgrad 1

Verwendete API-Aufrufe:

RtlMoveMemory (CopyMemory), CreateIconFromResourceEx, OleCreatePictureIndirect

Download:

Download des Beispielprojektes [69,96 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  ---------

Option Explicit

' benötig eine Ressourcen-Datei (RES) mit einem Icon als
' "Custom"-Ressource ("32BitIcons") und der Ressource-ID: 101
' 24bit- und 32bit-Icons müssen als Custom-Ressource
' in der Ressourcendatei (*.RES) eingebunden werden,
' da das einbinden als normale IconRessource nicht
' funktioniert. VB selbst kann keine 32Bit Icons per
' LoadPicture-Befehl laden. Auch das setzen der
' Picture/Icon-Eigenschaft, über das Eigenschaftsfenster
' eines Controls mit einem 32bit-Icon, funktioniert nicht.

' ----==== sonstige Const ====----
Private Const IconVersion As Long = &H30000
Private Const LR_DEFAULTCOLOR As Long = &H0&

' ----==== sonstige Types ====----
Private Type IconHeader
    ihReserved As Integer
    ihType As Integer
    ihCount As Integer
End Type

Private Type IconEntry
    ieWidth As Byte
    ieHeight As Byte
    ieColorCount As Byte
    ieReserved As Byte
    iePlanes As Integer
    ieBitCount As Integer
    ieBytesInRes As Long
    ieImageOffset As Long
End Type

Private Type PICTDESC
    cbSizeOfStruct As Long
    picType As Long
    hgdiObj As Long
    hPalOrXYExt As Long
End Type

Private Type IID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(0 To 7)  As Byte
End Type

' ----==== USER32 API Declarationen ====----
Private Declare Function CreateIconFromResourceEx Lib "user32" _
    (presbits As Any, ByVal dwResSize As Long, _
    ByVal fIcon As Long, ByVal dwVer As Long, _
    ByVal cxDesired As Long, ByVal cyDesired As Long, _
    ByVal Flags As Long) As Long

' ----==== KERNEL32 API Declarationen ====----
Private Declare Sub CopyMemory Lib "kernel32" Alias _
    "RtlMoveMemory" (pDst As Any, pSrc As Any, _
    ByVal ByteLen As Long)

' ----==== OLE API Declarations ====----
Private Declare Sub OleCreatePictureIndirect Lib "oleaut32.dll" _
    (lpPictDesc As PICTDESC, riid As IID, ByVal fOwn As Boolean, _
    lplpvObj As Object)

'------------------------------------------------------
' Funktion     : HandleToPicture
' Beschreibung : Umwandeln eines Bitmaphandle
'                in ein StdPicture Objekt
' Übergabewert : hBMPHandle = Bitmaphandle
'                ObjectType = Bitmaptyp
' Rückgabewert : StdPicture Objekt
'------------------------------------------------------
Private Function HandleToPicture(ByVal hBMPHandle As Long, _
    ByVal ObjectType As PictureTypeConstants, _
    Optional ByVal hpal As Long = 0) As StdPicture
    
    On Error Goto PROC_ERR
    
    Dim tPictDesc As PICTDESC
    Dim IID_IPicture As IID
    Dim oPicture As IPicture
    
    ' Initialisiert die PICTDESC Structur
    With tPictDesc
        .cbSizeOfStruct = Len(tPictDesc)
        .picType = ObjectType
        .hgdiObj = hBMPHandle
        .hPalOrXYExt = hpal
    End With
    
    ' Initialisiert das IPicture Interface ID
    With IID_IPicture
        .Data1 = &H7BF80981
        .Data2 = &HBF32
        .Data3 = &H101A
        .Data4(0) = &H8B
        .Data4(1) = &HBB
        .Data4(3) = &HAA
        .Data4(5) = &H30
        .Data4(6) = &HC
        .Data4(7) = &HAB
    End With
    
    ' Erzeugen des Objekts
    OleCreatePictureIndirect tPictDesc, _
    IID_IPicture, True, oPicture
    
    ' Rückgabe des Pictureobjekts
    Set HandleToPicture = oPicture
    
PROC_EXIT:
    Exit Function
    
PROC_ERR:
    MsgBox "Error: " & Err.Number & ". " & Err.Description, , _
    "HandleToPicture"
    Resume PROC_EXIT
    
End Function

'------------------------------------------------------
' Funktion     : LoadIconFromRes
' Beschreibung : Laden von 24bit- und 32bit Icons
'                aus einer "Custom"-Resource
' Übergabewert : ResIndex = Kennung (ID) der Daten
'                           in der Ressourcedatei
'                ResFormat = Zeichenfolgenname der
'                            benutzerdefinierten Ressource
'                IconIndex = Index des zuladenden Icons
' Rückgabewert : StdPicture Objekt
'------------------------------------------------------
Private Function LoadIconFromRes(ByVal ResIndex As Long, _
    ByVal ResFormat As String, _
    ByVal IconIndex As Long) As StdPicture
    
    On Error Goto PROC_ERR
    
    Dim hIcon As Long
    Dim ResData() As Byte
    Dim tIconHeader As IconHeader
    Dim tIconEntry() As IconEntry
    
    ' Resource in ByteArray speichern
    ResData = LoadResData(ResIndex, ResFormat)
    
    ' IconHeader aus ByteArray kopieren
    Call CopyMemory(tIconHeader, ResData(0), LenB(tIconHeader))
    
    ' ist das eine Icondatei
    ' ihType muss 1 sein
    If tIconHeader.ihType = 1 Then
        
        'ihCount enthält die Anzahl der Icons
        
        ' gibt es diesen IconIndex
        If IconIndex >= 0 Then
            If IconIndex <= tIconHeader.ihCount - 1 Then
                
                ' IconEntry dimensionieren
                ReDim tIconEntry(tIconHeader.ihCount - 1)
                
                ' IconEntry´s aus ByteArray kopieren
                Call CopyMemory(tIconEntry(0), _
                ResData(LenB(tIconHeader)), _
                LenB(tIconEntry(0)) * tIconHeader.ihCount)
                
                ' tIconEntry enthält nun alle wichtigen
                ' Daten wie Größe der Icons, Bittiefe der
                ' Icons, Start und Größe in Byte der
                ' einzelnen Icons
                
                ' Icon aus Resource erzeugen bzw.
                ' Handle vom Icon ermitteln
                hIcon = CreateIconFromResourceEx( _
                ResData(tIconEntry(IconIndex).ieImageOffset), _
                tIconEntry(IconIndex).ieBytesInRes, 1, IconVersion, _
                tIconEntry(IconIndex).ieWidth, _
                tIconEntry(IconIndex).ieHeight, LR_DEFAULTCOLOR)
                
                ' StdPicture Objekt erstellen (Icon)
                Set LoadIconFromRes = HandleToPicture(hIcon, _
                vbPicTypeIcon)
                
            End If
        End If
    End If
    
PROC_EXIT:
    Exit Function
    
PROC_ERR:
    MsgBox "Error: " & Err.Number & ". " & Err.Description, , _
    "LoadIconFromRes"
    Resume PROC_EXIT
    
End Function

Private Sub Form_Load()
    ' Lädt das 3. Icon aus der "32BitIcons"-Resource
    ' mit der ID "101"
    Me.Icon = LoadIconFromRes(101, "32BitIcons", 2)
    
    ' Lädt das 8. Icon aus der "32BitIcons"-Resource
    ' mit der ID "101"
    Me.Picture = LoadIconFromRes(101, "32BitIcons", 7)
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 5 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 pain2000 am 22.10.2010 um 14:25

Hi Frank,
hatte das Thema schon fast wieder vergessen, aber besser spät als nie... ;-))
Danke für den Hinweis. Hab mir nochmal beide Tipps genau angeschaut... und klar, du hast Recht!!
Hab jetzt quasi beide Tipps (Codes) zu einen zusammen gebastelt und entschlackt. Haut prima hin. Die in Tipp 0730 enthaltene Routine zur Mischung der Hintergrundfarbe, fehlt hier ja quasi.

mfg pain2000.

Kommentar von Frank am 30.09.2010 um 07:09

Hi pain2000

Wenn Du Dir beide Codes genau anschaust, wirst Du feststellen das der Ursprung der Icondaten ein ByteArray ist. Bei diesem Tipp hier ist es "ResData" und im anderem Tipp "bytIcoData". Woher die ByteArrys nun gefüllt werden ist dabei egal. Der restliche Code um dann ein bestimmtes Icon aus diesem ByteArray anzuzeigen ist fast gleich.

PS: Sorry wenn ich erst jetzt auf Deine Frage geantwortet habe. Solltest Du weitere Fragen haben, dann bitte ich Dich einen Thread im Forum aufzumachen.

Mfg Frank

Kommentar von pain2000 am 11.02.2010 um 15:53

OK, funzt soweit,
aber bei 32Bit Icons zeigt er mir den Schatten nur schwarz an und die Ränder des Icons sind fransig.
Bei "Tipp 0730: 32-Bit-Icons laden und anzeigen" funzt es dagegen prächtig, nur muss das Icon dann als extra Datei vorhanden sein...
Kann man die beiden Tips nicht irgendwie kombinieren? Bin mit VB leider nicht so 100%ig fit.

Kommentar von Frank Schüler am 15.03.2007 um 19:49

Hi Tobias

Einfach in VB6 den Ressourceneditor starten und über den Button "Add Custom Resouce..." das 24- oder 32bit Icon laden. Den Namen für die Customressource änderst Du indem Du dann auf die ID 101 mit der rechten Maustaste klickst unter Properties/Type.

MFG Frank

Kommentar von Tobias Salzmann am 14.03.2007 um 14:44

Wie wurde die Res datei erstellt einfach nur ein Icon reingepackt?