VBA: Datei-Icons einlesen und speichern

Möchtest Du den gesamten Artikel lesen? Und vielleicht sogar den Artikel im PDF-Format und die Beispieldateien herunterladen? Dann hole Dir den Artikel gleich hier - völlig kostenlos!

Symbole und Icons spielen in Microsoft-Access-Anwendungen eine oft unterschätzte Rolle. Dabei können sie die Bedienbarkeit und Verständlichkeit einer Datenbank erheblich verbessern – insbesondere dann, wenn Dateien, Ordner oder Dokumenttypen visuell unterschieden werden sollen. Während Access für viele Steuerelemente wie TreeView, ListView, Symbolleisten oder Ribbon-Schaltflächen grundsätzlich Icon-Unterstützung bietet, stellt sich in der Praxis häufig die Frage:Wie lassen sich die echten System-Icons von Dateien – so wie sie auch im Windows-Explorer angezeigt werden – in einer Access-Anwendung verwenden? Genau das zeigen wir in diesem Artikel und liefern auch noch das Know-how, um die eingelesenen Icons direkt in der Tabelle MSysResources zu speichern. Von dort können wir sie beispielsweise in ein ImageList-Steuerelement schreiben – um sie dann in TreeView- und ListView-Steuerelementen anzuzeigen.

Mit Bordmitteln von Access ist das Ermitteln der Icon-Dateien nicht möglich. Stattdessen ist ein gezielter Zugriff auf die Windows-Shell erforderlich, um Datei-Icons dynamisch zu ermitteln und für die eigene Benutzeroberfläche nutzbar zu machen.

Genau hier setzt die in diesem Artikel vorgestellte Technik an: Mithilfe der Windows-API lassen sich die systemweit registrierten Icons für beliebige Dateitypen auslesen, in ein ImageList-Steuerelement übernehmen und anschließend in verschiedenen Access-Steuerelementen einsetzen.

Der große Vorteil dieser Vorgehensweise liegt darin, dass die Icons automatisch dem jeweils installierten Programm entsprechen. PDF-Dateien, Word-Dokumente, ZIP-Archive oder ausführbare Dateien werden genauso dargestellt, wie der Benutzer sie aus dem Windows-Explorer kennt – also ohne zusätzliche Grafikdateien.

Der Artikel zeigt Schritt für Schritt, wie diese Technik umgesetzt wird, wie sich Icons performant zwischenspeichern lassen und an welchen Stellen einer Access-Datenbank sie sinnvoll eingesetzt werden können.

Die Icons können wir etwa für die Anzeige von Dateien in einem ListView-Steuerelement in einem Formular nutzen (siehe Bild 1), wie wir es im Artikel Access: Ordner und Dateien im Formular anzeigen (www.vbentwickler.de/3) vorstellen.

Dateien mit Icons in einem ListView-Steuerelement

Bild 1: Dateien mit Icons in einem ListView-Steuerelement

Vorbereitung: API-Funktionen und -Deklarationen

Für die nachfolgend vorgestellten Techniken benötigen wir als Erstes eine Reihe von API-Funktionen, Konstanten und Typen.

Diese haben wir in Listing 1 zusammengestellt.

#If VBA7 Then
     Private Declare PtrSafe Function SHGetFileInfo Lib "shell32.dll" Alias "SHGetFileInfoW" ( _
         ByVal pszPath As LongPtr, ByVal dwFileAttributes As Long, _
         psfi As SHFILEINFO, ByVal cbFileInfo As Long, _
         ByVal uFlags As Long) As LongPtr
#Else
     Private Declare Function SHGetFileInfo Lib "shell32.dll" Alias "SHGetFileInfoW" ( _
         ByVal pszPath As Long, _
         ByVal dwFileAttributes As Long, _
         psfi As SHFILEINFO, _
         ByVal cbFileInfo As Long, _
         ByVal uFlags As Long) As Long
#End If
Private Declare PtrSafe Function OleCreatePictureIndirect Lib "oleaut32.dll" ( _
     ByRef picDesc As PICTDESC, _
     ByRef RefIID As GUID, _
     ByVal fPictureOwnsHandle As Long, _
     ByRef IPic As Object) As Long
Private Type GUID
     Data1 As Long
     Data2 As Integer
     Data3 As Integer
     Data4(7) As Byte
End Type
Private Type PICTDESC
     cbSizeofStruct As Long
     picType As Long
     hImage As LongPtr
     xExt As Long
     yExt As Long
End Type
Private Type SHFILEINFO
     hIcon As LongPtr
     iIcon As Long
     dwAttributes As Long
     szDisplayName As String * 260
     szTypeName As String * 80
End Type
Private Const PICTYPE_ICON = 3
Private Const SHGFI_ICON = &H100
Private Const SHGFI_SMALLICON = &H1
Private Const SHGFI_LARGEICON = &H0
Private Const SHGFI_USEFILEATTRIBUTES = &H10
Private Const FILE_ATTRIBUTE_NORMAL = &H80

Listing 1: API-Deklarationen

Speichern von Icon-Dateien in der Tabelle MSysResources

Die Tabelle MSysResources speichert die für eine Access-Anwendung notwendigen Ressourcen wie etwa die Bilddateien, die in Formularen, Berichten und Steuerelementen wie der Schaltfläche oder dem Bild-Steuerelement angezeigt werden.

Dies ist der Platz, an dem wir auch die Icon-Dateien speichern können. Diese können wir dann beispielsweise von dort in ein ImageList-Steuerelement übertragen, um sie von dort aus in einem TreeView– oder ListView-Steuerelement anzuzeigen.

Funktion zum Speichern von Icon-Dateien

Die Hauptfunktion heißt SaveFileIconToMSysResources und erwartet drei Parameter:

  • strFilePath: Pfad der Datei, dessen Icon wir speichern wollen
  • strResourceName: Name, unter dem die Datei in der Tabelle MSysResources gespeichert werden soll
  • bolSmallIcon: Gibt an, ob ein kleines Icon gespeichert werden soll (16 x 16 Pixel)

Die Funktion haben wir in Listing 2 abgebildet.

Public Sub SaveFileIconToMSysResources(ByVal strFilePath As String, ByVal strResourceName As String, _
         Optional ByVal bolSmallIcon As Boolean = True)
     Dim hIcon As LongPtr
     Dim pic As Object
     Dim strTempFile As String
     
     hIcon = GetFileIconHandle(strFilePath, bolSmallIcon)
     If hIcon = 0 Then Exit Sub
     Set pic = IconHandleToPicture(hIcon)
     If pic Is Nothing Then Exit Sub
     strTempFile = CurrentProject.Path & "\icon.ico"
     SavePicture pic, strTempFile
     SaveIconToMSysResources strResourceName, "ICO", strTempFile
     On Error Resume Next
     Kill strTempFile
     On Error GoTo 0
End Sub

Listing 2: Die Funktion SaveFileIconToMSysResources

Sie holt als Erstes mit der Funktion GetFileIconHandle ein Handle auf das File-Icon der Datei, die wir mit strFilePath übergeben. Außerdem übergeben wir dieser den Parameter bolSmallIcon.

Wenn das Icon-Handle nicht 0 ist, holen wir das Icon hinter dem Handle mit einer weiteren Funktion namens IconHandleToPicture, der wir das Handle übergeben. Ist das Ergebnis nicht leer, legen wir mit der Funktion SavePicture eine temporäre Datei namens icon.ico im aktuellen Datenbankordner an. Dieser übergeben wir die Objektvariable mit dem Bild (pic) sowie den Pfad der zu speichernden Datei.

Schließlich rufen wir die Funktion SaveIconToMSysResources auf, welche das Icon einliest und in der Tabelle MSysResources speichert, und löschen die temporäre Datei wieder.

Handle des Icons holen

Die Funktion GetFileIconHandle aus Listing 3 erwartet den Pfad der Datei, deren Icon wir ermitteln wollen, sowie die Angabe, ob ein kleines Icon geliefert werden soll.

Private Function GetFileIconHandle(ByVal strFilePath As String, Optional ByVal bolSmall As Boolean = True) As LongPtr
     Dim sfi As SHFILEINFO
     Dim lngFlags As Long
     lngFlags = SHGFI_ICON Or SHGFI_USEFILEATTRIBUTES
     If bolSmall Then
         lngFlags = lngFlags Or SHGFI_SMALLICON
     Else
         lngFlags = lngFlags Or SHGFI_LARGEICON
     End If
     SHGetFileInfo StrPtr(strFilePath), FILE_ATTRIBUTE_NORMAL, sfi, LenB(sfi), lngFlags
     GetFileIconHandle = sfi.hIcon
End Function

Listing 3: Funktion zum Ermitteln des Handles auf das File-Icon

Sie stellt in der Variablen lngFlags einige Parameter zusammen, die davon abhängen, ob wir ein kleines Icon haben möchten oder nicht.

SHGFI_ICON legt fest, dass wir ein Icon abfragen wollen, SHGFI_USEFILEATTRIBUTES steht für das Abfragen des Icons anhand des Dateityps beziehungsweise der Dateiendung und SHGFI_SMALLICON oder SHGFI_LARGEICON legen fest, ob wir ein kleines oder großes Icon benötigen.

Dann ruft sie die API-Funktion SHGetFileInfo auf, der wir den Parameter sfi übergeben, der letztlich das Handle über die Eigenschaft hIcon liefert.

Dieses gibt die Funktion als Ergebnis zurück.

Icon-Picture holen

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar