Symbole zu Dateitypen ermitteln

Veröffentlicht: 15. Dez 2001 | Aktualisiert: 13. Jun 2004

Von Paul DiLascia

* * *

Auf dieser Seite

Frage Frage
Antwort Antwort

Diesen Artikel können Sie hier lesen dank freundlicher Unterstützung der Zeitschrift:

Bild02

Frage

Vor einiger Zeit haben Sie in einem Artikel erklärt, wie man das Programmsymbol aus einer ausführbaren Datei auslesen kann. Wie finde ich nun das Symbol, das für eine bestimmte Dokumentart vorgesehen wurde?

 

Antwort

Gute Frage. Die Antwort hängt davon ab, ob Sie das Symbol für eine bestimmte Datei brauchen oder für eine allgemeine Dateiart. Wenn Sie eine bestimmte Datei im Sinn haben, zum Beispiel C:\MeineAkten\DieseAkte.zzp, erhalten Sie von ExtractAssociatedIcon das dazugehörige Symbol. Das funktioniert aber nur für eine Datei, die tatsächlich auf der Festplatte oder an einer anderen geeigneten Stelle zu finden ist.

Wenn Sie das Symbol suchen, das ganz allgemein für eine bestimmte Dateiart angezeigt werden soll, müssen Sie sich an die Registrierdatenbank halten. Brauchen Sie zum Beispiel das Symbol für .bmp-Dateien, suchen Sie in der Registrierdatenbank nach dem Eintrag HKEY_CLASSES_ROOT\.bmp. Auf meiner Maschine hat er den Wert "bitmapFile". Anschließend sehen Sie unter HKEY_CLASSES_ROOT\bitmapFile nach und schauen sich den Schlüssel DefaultIcon genauer an. Auf meiner Maschine hat er folgenden Wert:

HKEY_CLASSES_ROOT\bitmapFile\DefaultIcon = 
    "C:\PROGRA~1\ACCESS~1\MSPAINT.EXE,1" 

Also handelt es sich bei dem Symbol für .bmp-Dateien um das erste Symbol in "C:\Program Files\Accessories\MSPAINT.EXE". Ganz allgemein gesprochen hat HKCR\.foo einen Wert wie foofile und HKCR\foofile\DefaultIcon gibt das Symbol an.

Aber halt, es geht noch weiter! Gelegentlich lautet der Eintrag für .foo auf "SuperApp.Document.5" oder ähnlich, was in diesem Fall die Version 5 von SuperApp bedeutet, und HKCR\SuperApp.Document.5 hat kein DefaultIcon, sondern einen Schlüssel CLSID = {long-ugly-hex-guid}. Das ist ein Hinweis darauf, dass es sich bei foofiles um COM-Objekte mit der Klassenkennung {same-long-ugly-hex-guid} handelt. Und dann müssen Sie unter HKCR\CLSID\{same-long-ugly-hex-guid}\DefaultIcon nach dem Symbol suchen. Was für ein Theater! Aber auch das war noch nicht die ganze Geschichte, weil es für foofiles eine anwenderdefinierte Symbolerweiterung geben kann (einen "custom icon handler"), die als Shell-Erweiterung implementiert wurde. Auch das müssen Sie überprüfen. Laden Sie den Icon-Handler, rufen Sie IShellIcon oder IExctractIcon auf und... langsam wird es lästig.

Zum Glück gibt es einen etwas eleganteren Weg (eigentlich habe ich Ihnen diese Sache mit der Registrierdatenbank nur vorgeführt, damit Sie ihn zu würdigen wissen): SHGetFileInfo. Diese handliche Funktion liefert alle möglichen Informationen über eine Datei. Sie hat eine ziemlich clevere Option namens SHGFI_USEFILEATTRIBUTES, mit der man den fraglichen Dateinamen angeben kann, zum Beispiel mumble.txt. SHGetFileInfo liefert die gewünschten Informationen auch dann, wenn es die fragliche Datei gar nicht gibt.

  SHFILEINFO shfi; 
  memset(&shfi,0,sizeof(shfi)); 
  SHGetFileInfo("foo.bmp",  
    FILE_ATTRIBUTE_NORMAL, 
    &shfi, sizeof(shfi), 
    SHGFI_ICON|SHGFI_USEFILEATTRIBUTES); 

Damit Sie sich anschauen können, wie das funktioniert, habe ich ein kleines Testprogramm namens FileType geschrieben (Bild B1). Es öffnet einen Dialog mit einem Eingabefeld, in dem Sie eine Namensendung wie txt oder jpg eingeben und sich das dazugehörige Dateisymbol anschauen können. Die Implementierung ist ziemlich simpel. Sobald der Anwender eine neue Namensendung eingegeben hat, schickt Windows eine EN_UPDATE-Hinweisnachricht. CMyDialog beschafft sich mit SHGetFileInfo das Symbol und zeigt es dann in einem statischen Steuerelement an. Alle weiteren Einzelheiten finden Sie im Quelltext auf der Begleit-CD dieses Hefts.

Bild01

FileType in Aktion