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 15.09.2000

Diese Seite wurde zuletzt aktualisiert am 15.09.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...

Icon, Icon, wechsle Dich...

Zurück...


Anzeige

(-hg) mailto:hg_iconfromfiledialog@aboutvb.de


In den Eigenschaften einer Datei kann der Anwender im Explorer über diesen Dialog ein Icon auswählen

Den oben stehenden Dialog kennen Sie sicher. Über ihn können Sie das Icon einer Verknüpfung in den Datei-Eigenschaften im Explorer ändern. Enthält eine Datei eigene Icons, werden diese zunächst zur Verfügung gestellt. Enthält sie keine Icons, werden nach der Anzeige einer Warnung die Icons aus der Datei Shell32.DLL gezeigt. Und schließlich können Sie in dem Dialog auch noch eine ganz andere Datei als Lieferanten eines Icons ausgucken.

Sie könnten ihn sogar für eigene Zwecke selber aufrufen, wenn Sie die dafür zuständige API-Funktion wüssten. Nun, sie könnte beispielsweise SHChangeIconDialog heißen. Könnte?

Ja, die zuständige API-Funktion ist nicht nur nicht dokumentiert. Sie hat eigentlich noch nicht einmal einen Namen, sondern nur eine so genannte Ordinal-Nummer in der Funktionstabelle. Da Visual Basic eine solche Nummer glücklicherweise zumindest als Alias einer Funktions-Deklaration akzeptiert, steht dem nichts im Wege, sie VB-konform zu taufen und zu verwenden. Ich habe sie im Stil der übrigen Shell-Dialog-Funktionen SHChangeIconDialog genannt. Sie fragen noch nach den Funktions-Parametern? Kein Problem - hier haben Sie die vollständige Deklaration:

Private Declare Function SHChangeIconDialog Lib "shell32" _
 Alias "#62" (ByVal hOwner As Long, ByVal szFilePath As String, _
 ByVal Reserved As Long, lpIndex As Long) As Long

Fragen Sie mich jetzt bitte nicht, woher ich die Deklaration habe. Sie schwirrt im Internet umher. Und genau so wie ich, hätten auch Sie schon (sogar mehrfach) darüber stolpern können...

Die Funktion sieht so eigentlich ganz gebrauchsfertig aus. Im Parameter hOwner übergeben sie das Handle des Fensters, an dem sich der Dialog ausrichten soll. Übergeben Sie hier 0, wird der Desktop zum Besitzer und der Dialog landet weit links oben im Bildschirm. Im zweiten Parameter szFilePath übergeben Sie den vollständigen Pfadnamen der Datei, deren Icons Sie einsehen möchten. Den dritten Parameter, Reserved, ignorieren Sie einfach und übergeben in jedem Fall lediglich den Wert 0. Im vierten, letzten Parameter übergeben Sie den Index des Icons, das beim Start des Dialogs vorausgewählt sein soll.

Erste Experimente mit dieser Funktion werden Ihnen zeigen, dass das so weit ganz gut klappt - solange tatsächlich die Icons der übergebenen Datei angezeigt werden.

Wie nämlich bereits Eingangs gesagt, können auch die Icons einer ganz anderen Datei zur Anzeige kommen. Die Vermutung liegt nahe, dass der geänderte Dateiname im Parameter szFilePath zurückgegeben werden könnte. Auf den ersten Blick scheint das auch zu stimmen, im Prinzip jedenfalls. Doch wenn der vollständige Pfad der zurückgegebenen Datei länger als der Pfad der ursprünglich übergebenen Datei ist, wird er auf deren Länge zurückgestutzt. Wie in solchen Fällen üblich, müssen Sie einen Puffer verwenden, der ausreichend lang ist. Solch ein Puffer ist nichts anderes, als ein ebenso genügend langer String. In der Regel wird für Dateipfade eine Länge von 260 angenommen. In diesen Puffer kopieren Sie den ursprünglichen Dateipfad, an den Sie zuvor noch ein Null-Zeichen (Ascii-Code 0, VB-Konstante vbNullChar) anhängen, damit Windows den C-Konventionen entsprechend weiß, wo der Dateipfad aufhört.

Das Kopieren erledigen Sie ganz einfach mit der MSDN Library - VB MidMid$-Zuweisung, bei der Sie die Start-Position auf 1 setzen, ohne eine Länge anzugeben. Fehlt nämlich die Längenangabe, nimmt Visual Basic automatisch die Länge des zugewiesenen Strings an und lässt den Rest des Ausgangsstrings unberührt.

Nach dem Aufruf von SHChangeIconDialog enthält der Puffer-String gegebenenfalls den neuen Dateipfad. Dieser ist ebenfalls mit einem Null-Zeichen abgeschlossen, wenn er kürzer als der Puffer ist. Sie brauchen also nur mit InStr die Position des Null-Zeichens zu ermitteln und den Puffer mit der MSDN Library - VB LeftLeft$-Funktion entsprechend zu kürzen.

Die Rückgabe des gewählten Indexes erfolgt nach dem gleichen Prinzip. Da aber Long-Werte immer gleich lang sind, erübrigt sich die Pufferschieberei. Der Parameter lpIndex gibt schlichtweg den gewählten Index zurück, ob vom Anwender geändert oder nicht.

In eine handliche Funktion gepackt (sie gibt False zurück, wenn der Anwender den Dialog abgebrochen hat, anderenfalls True), sieht das folgendermaßen aus:

Private Declare Function SHChangeIconDialog Lib "shell32" _
 Alias "#62" (ByVal hOwner As Long, ByVal szFilePath As String, _
 ByVal Reserved As Long, lpIcon As Long) As Long

Private Const MAX_PATH = 260

Public Function ChangeIconDialog(FilePath As String, Index As Long, _
 Optional ByVal OwnerWnd As Long) As Boolean

  Dim nIndex As Long
  Dim nFilePath As String
  Dim nOK As Boolean
  Dim nPos As Integer
  
  nIndex = Index
  nFilePath = Space$(MAX_PATH)
  Mid$(nFilePath, 1) = FilePath & Chr$(0)
  nOK = CBool(SHChangeIconDialog(OwnerWnd, nFilePath, 0, nIndex))
  If nOK Then
    nPos = InStr(nFilePath, vbNullChar)
    If nPos Then
      FilePath = Left$(nFilePath, nPos - 1)
    Else
      FilePath = nPos
    End If
    Index = nIndex
  End If
  ChangeIconDialog = nOK
End Function

So weit, so gut. Nun haben Sie also den Dateipfad und den Index eines sich in dieser Datei steckenden Icons. Damit können Sie in Visual Basic aber noch gar nichts anfangen Es sei denn, Ihnen reichen diese beiden Informationen völlig aus, um sie etwa per Code in eine Verknüpfung zu schreiben. Anderenfalls sind weitere Griffe in die API-Kiste notwendig, um ein in VB darstellbares Icon zu erhalten.

Der nächste Schritt ist also, das unter der angegebenen Index-Position in der Datei befindliche Icon zu extrahieren. Ich habe bewusst das Fremdwort "extrahieren" gewählt. Übersetzt ins Englische wird nämlich "extract" daraus, und fast schon auf den ersten Blick werden Sie in der Liste der API-Funktionen die Funktionen MSDN Library - API ExtractIconExtractIcon und MSDN Library - API ExtractIconExExtractIconEx sehen. Auf die nächsten zwei Blicke hin, nämlich die in die MSDN-Dokumentation zu den beiden Funktionen, scheint die erstere Funktion erheblich einfacher aufzurufen zu sein, während die zweite recht kompliziert klingt.

Widerstehen Sie der Versuchung der Bequemlichkeit und verwenden Sie die zweite Funktion. Die erste stammt nämlich noch aus der Zeit vor Windows 95, als es Icons nur in der einen Größe von 32x32 Pixels gab. Die zweite Funktion kann dagegen ganz nach Wunsch das kleine 16x16-Icon, das 32x32-Icon oder auch beide zugleich liefern. Die beiden Größen liegen, so denn beide vorhanden sind, von außen betrachtet an der gleichen Index-Position.

Private Declare Function ExtractIconEx Lib "shell32.dll" _
 Alias "ExtractIconExA" (ByVal lpszFile As String, _
 ByVal nIconIndex As Long, phiconLarge As Long, phiconSmall As Long, _
 ByVal nIcons As Long) As Long 

Wenn Sie Lust haben, können Sie mit der Funktion ExtractIconEx ein wenig herumexperimentieren und die in der Dokumentation beschriebenen Möglichkeiten, auch gleich mehrere Icons hintereinander oder gar alle Icons zu extrahieren, umzusetzen versuchen. Ein kleiner Tipp dazu: Nehmen Sie alles wörtlich und übergeben Sie statt Arrays als solchen tatsächlich nur das jeweils erste Element, etwa LargeIcons(0) und/oder SmallIcons(0). Da wir hier aber nur genau ein Icon brauchen, gegebenenfalls in beiden Größen, sparen wir uns die Arrays und verwenden einfache Long-Variablen, die die Handles der Icons aufnehmen. Aus API-Sicht ist eine einfache Variable nichts anderes als ein Array mit nur einem einzigen Element. Es geht einfach nur um die Speicheradresse der Variablen oder eben des ersten Elements als Anfangsadresse des Arrays - und deswegen will Windows ja auch separat wissen, um wie viele Elemente es sich handeln soll.

Nun haben Sie also ein oder zwei Icon-Handles und können in Visual Basic immer noch nichts damit anfangen, nicht wahr? Keine Bange - die Lösung der letzten Teilaufgabe halten wir schon seit längerem in unserem Tipp-Sortiment bereit: Vom Handle zum Picture"Vom Handle zum Picture". Und das war's denn auch. Sie brauchen lediglich sowohl für das kleine als auch das große Icon jeweils einmal die Funktion PictureFromHandle aufzurufen und dabei als Bildtyp vbPicTypeIcon anzugeben - und schon haben Sie beide Icons als VB-bequeme Picture-Objekte zur Hand.

Damit es noch bequemer wird, packen wir auch die Ausleserei in eine Funktion, und stecken auch gleich die Möglichkeit, den Auswahl-Dialog in einem Gang aufzurufen, mit hinein. Im Prinzip reicht es, die folgende Funktion IconFromFile mit der Angabe des Dateipfades und der Option ShowDialog = True aufzurufen, um im einfachsten Fall den Anwender ein großes Icon auswählen zu lassen.

Wie bei der oben stehenden Funktion (sie wird hier in der Funktion intern aufgerufen) können Sie aber auch die Vorauswahl durch die Übergabe einer Index-Position festlegen. Dazu können Sie im Parameter IconSize eine der drei Konstanten aus der Enumeration IconSizeConstants angeben, um das kleine oder das große Icon an der ausgewählten Position direkt als Picture-Obnjekt zu erhalten, oder beide Icons in einem Array mit zwei Elementen (Array-Index 1 und 2). Und wie bei ChangeIconDialog können Sie schließlich noch das Fenster-Handle übergeben.

Public Enum IconSizeConstants
  isLarge
  isSmall
  isBoth
End Enum

Public Function IconFromFile(FilePath As String, _
 Optional Index As Long, _
 Optional ByVal IconSize As IconSizeConstants, _
 Optional ByVal ShowDialog As Boolean, _
 Optional ByVal OwnerWnd As Long) As Variant

  Dim nIconLarge As Long
  Dim nIconSmall As Long
  Dim nFilePath As String
  Dim nIndex As Long
  Dim nIcons() As StdPicture
  
  nFilePath = FilePath
  nIndex = Index
  If ShowDialog Then
    If ChangeIconDialog(nFilePath, nIndex, OwnerWnd) = False Then
      Exit Function
    End If
    FilePath = nFilePath
    Index = nIndex
  End If
  Select Case IconSize
    Case isLarge
      ExtractIconEx nFilePath, nIndex, nIconLarge, 0, 1
      Set IconFromFile = PictureFromHandle(nIconLarge, vbPicTypeIcon)
      DestroyIcon nIconLarge
    Case isSmall
      ExtractIconEx nFilePath, nIndex, 0, nIconSmall, 1
      Set IconFromFile = PictureFromHandle(nIconSmall, vbPicTypeIcon)
      DestroyIcon nIconSmall
    Case isBoth
      ReDim nIcons(1 To 2)
      ExtractIconEx nFilePath, nIndex, nIconLarge, nIconSmall, 1
      Set nIcons(1) = PictureFromHandle(nIconLarge, vbPicTypeIcon)
      Set nIcons(2) = PictureFromHandle(nIconSmall, vbPicTypeIcon)
      IconFromFile = nIcons
      DestroyIcon nIconLarge
      DestroyIcon nIconSmall
  End Select
End Function

Beispiel-Projekt und Modul IconFromFileDialog (iconfromfiledialog.zip - ca. 4,3 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