ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 02.05.2000

Diese Seite wurde zuletzt aktualisiert am 02.05.2000
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Das "einzig wahre" Icon

Zurück...


Anzeige

Von Martin Szugat mailto:ms_associcon@aboutvb.de

Ihre Anwendung soll wie der Explorer Dateien mit den zugehörigen Symbolen anzeigen? Kein Problem - da gibt es doch... die API-Funktion MSDN Library - API ExtractAssociatedIconExtractAssociatedIcon. Halt, nein! Die Funktion ExtractAssociatedIcon extrahiert zwar gemäß ihrem Namen zu einer gegebenen Datei das zugehörige Dateisymbol entweder direkt aus der Datei oder aus der Programmdatei, die mit dem Typ der Datei verknüpft ist. Doch darin liegt gleichermaßen das Problem mit der ExtractAssociatedIcon-Funktion. Denn falls es sich bei der betreffenden Datei beispielsweise um ein Bitmap handelt, wird statt eines Dateisymbols das Bitmap selbst angezeigt, wobei es auf die Größe eines Symbols gestaucht wird. Ein vergleichbares Problem tritt bei Programmbibliotheken zu Tage, die eigene Symbole enthalten: Anstatt des erhofften Symbols für Programmbibliotheken liefert Ihnen die ExtractAssociatedIcon-Funktion ein Symbol aus der Programmbibliothek. Der Explorer zeigt statt dessen für Bitmaps etwa das Symbol für MS Paint und für Programmbibliotheken das entsprechende Standardsymbol an.

An Stelle der ExtractAssociatedIcon-Funktion verwendet der Explorer die API-Funktion MSDN Library - API SHGetFileInfoSHGetFileInfo. Die SHGetFileInfo-Funktion liefert neben zahlreichen anderen Datei-Informationen auch das mit der Datei tatsächlich assoziierte Symbol. Außerdem erlaubt die SHGetFileInfo-Funktion bestimmte Variationen dieses Dateisymbols. Ein Ordner lässt sich beispielsweise geöffnet oder geschlossen darstellen, eine Verknüpfung wird meist durch einen kleinen Pfeil in der linken unteren Ecke des Symbols (das kann aber durchaus vom Anwender geändert werden) von einer gewöhnlichen Datei unterschieden und das Symbol einer selektierten Datei beziehungsweise Ordners wird in der Markierungsfarbe des Systems eingefärbt. Ebenso lässt sich die Größe des Dateisymbols mit Hilfe der SHGetFileInfo-Funktion einstellen: Small (16x16 Pixels), Large (32x32 Pixels) oder Shell - das ist abhängig von den Benutzereinstellungen.

Die kleine Beispiel- und Experimentieranwendung zu diesem Artikel verwendet die ExtractAssociatedIcon- und die SHGetFileInfo-Funktion, um den Unterschied zwischen den beiden Funktionen zu demonstrieren. Hierfür geben Sie im Textfeld Dateiname einen Pfad auf eine Bitmap-Datei ein (Sie können auch eine Date vom Desktop oder aus einem Explorer-Fenster in das Textfeld ziehen). Sobald das Textfeld ein gültigen Pfad auf eine existierende Datei enthält, wird in der linken Picturebox das mit dem Bitmap vermeintlich assoziierte Symbol eingeblendet. Tatsächlich wird jedoch das Bitmap selbst verkleinert dargestellt. Das im Explorer sichtbare Dateisymbol wird dagegen in der rechten Picturebox angezeigt.

Obwohl die ExtractAssociatedIcon-Funktion, wie gesagt, nur bedingt brauchbar ist, lohnt es sich, einen Blick auf die Deklaration und die Anwendung der Funktion zu werfen.

Private Declare Function ExtractAssociatedIcon Lib "shell32.dll" _
 Alias "ExtractAssociatedIconA" (ByVal hInst As Long, _
 ByVal lpIconPath As String, ByRef lpiIcon As Integer) As Long

Die Funktion erwartet drei Parameter: das Instanzen-Handle der eigenen Anwendung, den Pfadnamen der betreffenden Datei sowie den Index des Symbols, das extrahiert werden soll. Das Instanzen-Handle der eigenen Anwendung erhalten Sie von der hInstance-Eigenschaft des App-Objekts. Der Pfadname im zweiten Parameter kann entweder auf eine Datei verweisen, die ihr Dateisymbol selbst bereitstellt, wie es der Fall bei Programmdateien, Symboldateien oder Bitmapdateien ist, oder auf eine Datei, die einer Programmdatei zugeordnet ist. Bei der ersten Art von Dateien extrahiert die ExtractAssociatedIcon-Funktion das Symbol direkt aus der betreffenden Datei. Andernfalls muss sie den Umweg über die Verknüpfung des Dateityps gehen und das Symbol aus der Programmdatei extrahieren. Der letzte Parameter, der den Index des Symbols angibt, ist nur dann von Relevanz, wenn die Datei mehrere Symbole enthalten sollte. In diesem Fall sind die Symbole beginnend bei Null durchnummeriert.

Als Rückgabewert erhalten Sie von der ExtractAssociatedIcon-Funktion ein Handle für das Symbol. Mit Hilfe der Funktion PictureFromHandle-Funktion (siehe Vom Handle zum Picture"Vom Handle zum Picture") lässt sich ein Symbol- oder ein Bitmap-Handle in ein Picture-Objekt wandeln. Falls Sie diesen Extra-Schritt einsparen wollen, bieten wir Ihnen mit der Funktion GetAssociatedIcon eine fertige Lösung an. Sie übergeben ihr den Pfadnamen der betreffenden Datei und erhalten als Rückgabewert ein Picture-Objekt mit dem mit der Datei assoziierten Symbol zurück.

Public Function GetAssociatedIcon(ByRef strFilename As String) _
 As StdPicture

  Dim hicon As Long
  
  If strFilename = Empty Then
    Err.Raise 5
  End If
  hicon = ExtractAssociatedIcon(App.hInstance, strFilename, 0)
  If hicon = 0 Then
    Err.Raise 5
  End If
  Set GetAssociatedIcon = _
   PictureFromHandle(hicon, vbPicTypeIcon, True)
End Function

Allerdings ist die Dokumentation zur ExtractAssociatedIcon-Funktion einerseits fehlerhaft und andererseits unvollständig. So sollte sie Funktion über den zweiten Parameter den Pfad derjenigen Datei an den Aufrufer zurückliefern, aus der das Symbol gewonnen wurde. Der tatsächliche Index des Symbols sollte über den dritten Parameter zurückgegeben werden. Doch die beiden Parameter funktionieren ausschließlich nur in der einen Richtung, als In-Parameter. Undokumentiert ist hingegen die Möglichkeit, im zweiten Parameter statt einem konkreten Pfadnamen eine Dateimaske zu übergeben. Allerdings muss die Dateimaske auf mindestens eine konkrete Datei passen. Folglich sind Dateimasken der Form *.ext nicht zulässig. Ein Beispiel für eine gültige Dateimaske wäre hingegen C:\Windows\*.bmp. In diesem Fall liefert ExtractAssociatedIcon doch wie eigentlich erwartet als ermitteltes Symbol nicht etwa ein verkleinertes Bitmap an, sondern das tatsächliche mit Bitmap-Dateien verknüpfte Dateisymbol. Ein vergleichbarer und ebenfalls undokumentierter Trick besteht darin, bei Bitmap-Dateien einen Wert größer Null als Index zu übergeben. Das Ergebnis ist auch hier wiederum das tatsächliche Dateisymbol.

Schließlich sei an dieser Stelle noch auf einen Fehler im API-Viewer hingewiesen. Der letzte Parameter der ExtractAssociatedIcon-Funktion ist vom Typ LPWORD. LPWORD steht für "Long Pointer to Word". Unter Visual Basic entspricht ein Long Pointer einem Referenzparameter und ein Word dem Dateityp Integer. Der Parameter ist also als ByRef lpiIcon As Integer zu deklarieren. Der API-Viewer deklariert den Parameter hingegen mit ByRef lpiIcon As Long. Selbstverständlich haben wir Ihnen oben die korrekte Deklaration der ExtractAssociatedIcon-Funktion gezeigt.

Die Anwendung der SHGetFileInfo-Funktion als Alternative ist zwar ein wenig komplizierter als die der ExtractAssociatedIcon-Funktion, doch die SHGetFileInfo-Funktion ermittelt im Unterschied zur ExtractAssociatedIcon-Funktion das Symbol, das auch vom Explorer angezeigt wird. Und sie liefert darüber hinaus weitere Informationen zu der betreffenden Datei. Neben der Deklaration der Funktion benötigen Sie weiterhin die Deklarationen für den benutzerdefinierten Typ SHFILEINFO und für die SHGFI-Konstanten.

Private Const SHGFI_ATTRIBUTES  As Long = &H800
Private Const SHGFI_DISPLAYNAME As Long = &H200
Private Const SHGFI_EXETYPE As Long = &H2000
Private Const SHGFI_ICON As Long = &H100
Private Const SHGFI_ICONLOCATION As Long = &H1000
Private Const SHGFI_LARGEICON As Long = &H0
Private Const SHGFI_LINKOVERLAY As Long = 32768 '= &H8000
Private Const SHGFI_OPENICON As Long = &H2
Private Const SHGFI_PIDL As Long = &H8
Private Const SHGFI_SELECTED As Long = &H10000
Private Const SHGFI_SHELLICONSIZE As Long = &H4
Private Const SHGFI_SMALLICON As Long = &H1
Private Const SHGFI_SYSICONINDEX As Long = &H4000
Private Const SHGFI_TYPENAME As Long = &H400
Private Const SHGFI_USEFILEATTRIBUTES As Long = &H10
Private Const MAX_PATH = 260

Private Type SHFILEINFO
  hicon As Long
  iIcon As Long
  dwAttributes As Long
  szDisplayName As String * MAX_PATH
  szTypeName As String * 80
End Type

Private Declare Function SHGetFileInfo Lib "shell32.dll" _
 Alias "SHGetFileInfoA" (ByVal pszPath As String, _
 ByVal dwFileAttributes As Long, psfi As SHFILEINFO, _
 ByVal cbFileInfo As Long, ByVal uFlags As Long) As Long

In der Struktur SHFILEINFO legt die SHGetFileInfo-Funktion die Datei-Informationen ab. Welche Informationen über die Datei ermittelt werden sollen, legen die genannten SHGFI-Konstanten fest. Des weiteren erwartet die SHGetFileInfo-Funktion den Pfadnamen der Datei sowie optional Attribute, die die Datei eindeutig identifizieren. Die SHFILEINFO-Struktur setzt sich zusammen aus dem Handle des Dateisymbols, dem Index des Symbols in der System Image List, den Dateiattributen, dem angezeigten Namen für die Datei und dem Typnamen der Datei. Indem wir der SHGetFileInfo-Funktion die Konstante SHGFI_ICON übergeben, teilen wir der Funktion mit, dass wir ausschließlich an dem Eintrag hIcon der SHFILEINFO-Struktur interessiert sind, da hier das Handle das Dateisymbols abgelegt wird. Die Konstante SHGFI_ICON lässt sich mittels Or-Operator mit den folgenden Konstanten kombinieren: SHGFI_LARGEICON, SHGFI_LINKOVERLAY, SHGFI_OPENICON, SHGFI_SELECTED, SHGFI_SHELLICONSIZE und SHGFI_SMALLICON.

Das Modul modAssocIcon.bas stellt Ihnen für diese Konstanten die Enumeration shgfiFlags zur Verfügung, die entsprechende Konstanten enthält und Ihnen die Wahl der gewünschten Konstante bei der Eingabe erleichtert.

Public Enum shgfiFlags
  shgfiLarge = SHGFI_LARGEICON
  shgfiLink = SHGFI_LINKOVERLAY
  shgfiOpen = SHGFI_OPENICON
  shgfiSelected = SHGFI_SELECTED
  shgfiShell = SHGFI_SHELLICONSIZE
  shgfiSmall = SHGFI_SMALLICON
End Enum

Am Beispiel der Konstanten SHGFI_LINKOVERLAY offenbart sich übrigens eine weitere Unzulänglichkeit des API-Viewers. Die Konstanten SHGFI sind ursprünglich als DWORD-Werte deklariert, jedoch kennt Visual Basic keinen Typ für ganzzahlige, positive Werte. Folglich muss der Long-Typ als Ersatz erhalten. Der Wert der SHGFI_LINKOVERLAY-Konstante in hexadezimaler Schreibweise lautet 0x8000. Der Wert 0x8000 entspricht als DWORD interpretiert der Zahl 32768. In VB würde man hierfür &H8000 schreiben, was allerdings der Zahl -32768 entspricht, da bei &H8000 das oberste Bit gesetzt ist. Das oberste Bit wird bei Long-Werten als Vorzeichenbit "missbraucht". Folglich wird der hexadezimale Wert &H8000 als negative Ganzzahl interpretiert. Doch da ein Großteil der WIN32API.TXT automatisch anhand von C++-Headerdateien generiert wurde, liefert der API-Viewer für die Konstante SHGFI_LINKOVERLAY die irrtümliche Deklaration:

Public Const SHGFI_LINKOVERLAY = &H8000

Richtigerweise muss sie jedoch lauten:

Private Const SHGFI_LINKOVERLAY As Long = 32768

Um den Aufruf der SHGetFileInfo-Funktion zu vereinfachen, haben wir diesen in die Funktion GetDisplayedIcon gepackt. In deren erstem Parameter übergeben Sie den Pfadnamen einer Datei bzw. eines Ordners. Es sind sowohl absolute als auch relative Pfade erlaubt sowie konkrete Dateimasken (zum Beispiel: C:\Windows\*.bmp). Im zweiten, optionalen Parameter lässt sich eine Bitmaske bestehend aus den eben genannten shgfiFlags-Konstanten übergeben. Die Kombination shgfiOpen Or shgfiSelected sorgt beispielsweise dafür, dass ein Ordner als geöffnet und selektiert dargestellt wird. Als Rückgabewert erhalten Sie ein Picture-Objekt mit dem gewünschten Dateisymbol.

Die Struktur der GetDisplayedIcon-Funktion ist ähnlich der der ExtractAssociatedIcon-Funktion. Als erstes wird die Bitmaske mit den shgfiFlags-Konstanten um die Konstante SHGFI_ICON erweitert. Dann erfolgt bereits der Aufruf der SHGetFileInfo-Funktion. Im ersten Parameter wird der SHGetFileInfo-Funktion der Pfadname der Datei übergeben. Im zweiten Parameter könnten die weitere Attribute abgelegt werden, die die Datei gegebenenfalls näher spezifizieren. Die GetDisplayedIcon-Funktion übergibt hier einfach Null, da wir diese bei dieser Verwendungsart der Funktion nicht benötigen und auch gar nicht ur Verfügung haben. Der dritte Parameter wird mit der SHFILEINFO-Struktur belegt und der vierte Parameter mit der Größe dieser Struktur. Im fünften und letzten Parameter finden sich schließlich die shgfiFlags-Konstanten.

Public Function GetDisplayedIcon( _
 ByRef strFilename As String, _
 Optional ByVal lngFlags As shgfiFlags = shgfiLarge) _
 As StdPicture

  Dim fi As SHFILEINFO
  Dim lngReturn As Long
  
  lngFlags = lngFlags Or SHGFI_ICON
  lngReturn = SHGetFileInfo(strFilename, 0, fi, Len(fi), lngFlags)
  If lngReturn = 0 Then
    Err.Raise 5
  End If
  Set GetDisplayedIcon = _
   PictureFromHandle(fi.hicon, vbPicTypeIcon, True)
End Function

Falls die SHGetFileInfo-Funktion einen Rückgabewert gleich Null liefert, war der Aufruf der SHGetFileInfo-Funktion nicht erfolgreich und die GetDisplayedIcon-Funktion löst daher einen Laufzeitfehler aus. Andernfalls wird das Handle des Symbols an die Vom Handle zum PicturePictureFromHandle-Funktion überreicht, die im Austausch ein Picture-Objekt liefert. Dieses Picture-Objekt gibt die GetDisplayedIcon-Funktion an ihren eigenen Aufrufer zurück.


Beispiel-Projekt AssocIconTest mit Modul modAssocIcon (associcon.zip - ca. 5 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche



Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer