Ich lege gleich noch einen nach -
Es gab ja schon einige Beiträge zum Thema "Wie registriere ich meinen eigenen Dateityp?" Die meisten Funktionen waren mir persönlich allerdings nicht detailliert genug. Aus dem Grund habe ich eine eigene Klasse namens
TFileTypeRegistration entworfen, die sich natürlich hauptsächlich an meinen Wünschen orientiert, aber evtl. auch für andere von Interesse ist.
Im Anhang gibt es die Units und ein Beispiel. Nun ist der Quellcode zwar kommentiert und enthält auch ein paar Beispiele. Aber trotzdem möchte ich kurz die Vorteile aufzählen, die es IMHO gibt -
Die meisten Funktionen registrieren einen Dateityp mit einer einzigen Aktion (wie
open o.ä.). Sollen mehrere Aktionen für den Typ registriert werden, muss die Funktion u.U. mehrfach aufgerufen werden. Dabei sind immer wieder die gleichen Parameter zu übergeben, was IMHO die Gefahr von Tipp- o.ä. Fehlern erhöht. Unter Umständen schreibt man also in den falschen Schlüssel.
Das kann bei der o.g. Klasse nicht passieren, weil hier die wichtigsten Eigenschaften einmal beim Registrieren des Typs gesetzt und dann intern benutzt werden. Daher sieht ein Aufruf so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| ftr := TFileTypeRegistration.Create; try if(ftr.RegisterType('.foo','FooFile','FOO-File')) then begin ftr.AddHandler('open','notepad.exe "%1"','Öffnen'); ftr.AddHandler('print','notepad.exe /p "%1"'); end; finally ftr.Free; end; |
Dann kann man auch den Standardhandler setzen; das ist der Eintrag, der im Kontextmenü fett gedruckt wird, und der bei einem Doppelklick auf die entsprechende Datei ausgeführt wird. Die Funktion "SetDefaultHandler" benutzt dabei den zuletzt benutzten Handler. Im o.g. Beispiel wäre das
print.
Da die Funktion überladen ist, kann man den gewünschten Handler aber auch selbst wählen:
Delphi-Quelltext
1:
| ftr.SetDefaultHandler('open'); |
Und man kann dafür sorgen, dass sich der eigene Typ auch bequem über das Menü "Neu" anlegen lässt. Das kennt man bspw. von Textdateien (Rechtsklick in einen freien Bereich -> Neu -> Textdatei). Allerdings darf die Beschreibung des Dateityps kein Leerzeichen aufweisen, und sie darf nicht leer sein. Es muss also beim Registrieren zwingend eine Beschreibung angegeben werden, weil diese die Referenz für den Dateinamen bildet.
Der entsprechende Befehl der Klasse lautet
Delphi-Quelltext
1:
| ftr.AddNewFileSupport; |
Mit "RemoveNewFileSupport" lässt sich diese Fähigkeit zu einem späteren Zeitpunkt wieder aufheben, ohne dass dafür der Dateityp entfernt und neu registriert werden muss.
Das war übrigens ein weiterer Kritikpunkt, den ich bei diversen anderen Lösungen hatte. Man konnte immer nur den kompletten Typ entfernen, nie nur einzelne Handler. Mit der o.g. Klasse geht es aber:
Delphi-Quelltext
1: 2:
| if(ftr.GetInternalKey('.foo') <> '') then ftr.DeleteHandler('print'); |
Die Funktion "GetInternalKey" liefert hier den internen Schlüssel zurück, auf den ".foo" zeigt. Das Rückgabeergebnis interessiert in dem Fall aber nicht, weil auch die Eigenschaft "FInternalName" gesetzt wird, die ihrerseits von "DeleteHandler" verwendet wird. Auf die Weise besteht also IMHO nicht die Gefahr, dass man in einem falschen Schlüssel löscht.
Um den kompletten Typ zu entfernen, benutzt man
Delphi-Quelltext
1:
| ftr.UnregisterType('.foo'); |
Noch etwas, das bei anderen, mir bekannten Lösungen nicht möglich war, ist das "Verlinken" mit bereits existierenden Typen. Angenommen der ".foo"-Typ ist auch bloß eine Textdatei, dann könnte ich doch dafür sorgen, dass der Typ intern mit den Textdateien verknüpft wird.
Dazu muss ich lediglich den internen Namen von ".txt" kennen, und kann dann die Verknüpfung durchführen:
Delphi-Quelltext
1: 2: 3:
| s := ftr.GetInternalName('.txt'); if(s <> '') then ftr.RegisterType('.foo',s); |
Bei Entfernen darf nun natürlich
auf keinen Fall "UnregisterType" benutzt werden, weil dadurch auch der interne Schlüssel der Textdateien gelöscht werden würde. Stattdessen gibt es "UnregisterExtension", die lediglich den Schlüssel ".foo" entfernt:
Delphi-Quelltext
1:
| ftr.UnregisterExtension('.foo'); |
Und noch ein Vorteil: Ich kann vorhandene Dateitypen ergänzen, ohne dass ich den internen Schlüssel kennen muss. Die Dateiendung reicht. Wenn ich einen eigenen Handler für Textdateien anlegen will, damit mein Programm als zusätzliche Option erscheint, genügt:
Delphi-Quelltext
1: 2:
| if(ftr.RegisterType('.txt','WhoTheF***Cares')) then ftr.AddHandler('MyOwnApp','c:\folder\foo.exe "%1"'); |
Das Besondere dabei ist, dass ich hier zwar den internen Namen "WhoTheF***Cares" benutzt habe, dass aber die Funktion "RegisterType" zuerst prüft ob der Typ bereits bekannt ist. In dem Fall wird dann der
tatsächliche interne Schlüssel gesucht und benutzt. Nur wenn es den Typ nicht geben würde, dann würde natürlich meine Vorauswahl verwendet werden.
Auf die gleiche Weise wie o.g. kann ich natürlich auch diesen zusätzlichen Handler wieder entfernen, ohne dass das irgendwelche Auswirkungen auf die Textdateien an sich hätte.