Mehr als eine Datei auswählen


Da es auch Anwendungen gibt, bei denen man mehr als eine Datei laden kann, soll dies nun kurz demonstriert werden. Folgendes ist dabei zu beachten: wir müssen die Flags-Membervariable um ein Flag erweitern, was aber zur Folge hat, dass der Dialog dann im "alten" Look von Windows 3.x angezeigt wird:

ofn.Flags := { ... } or OFN_ALLOWMULTISELECT;

Dies können Sie vermeiden, indem Sie zusätzlich das Flag OFN_EXPLORER benutzen und so den von Windows 9x/NT/ME/2000/XP gewohnten Stil erhalten:

ofn.Flags := { ... } or OFN_ALLOWMULTISELECT or OFN_EXPLORER;

Weil es aber in beiden Varianten Unterschiede im Rückgabeergebnis gibt, müssen wir uns auch beides ansehen.


Der alte Dialogstil

In diesem Fall zeigt der Textpuffer auf einen String, der sowohl den Namen des Ordners als auch die Namen der ausgewählten Dateien enthält, wobei alles durch ein Leerzeichen voneinander getrennt ist. Das könnte also z.B. so aussehen:

C:\Eigene~1 Datei1.txt Datei2.txt Datei3.txt

Sie müssen den String daher entsprechend parsen, wenn Sie den Dateinamen und den Ordnernamen in Ihrer Anwendung benutzen wollen.


Der neue Dialogstil

Ein wenig anders sieht das beim Win9x-Stil der Dialogbox auf. Auch hier enthält der Textpuffer nur einen String. Doch diesmal sind die einzelnen Angaben durch das Zeichen #0 voneinander getrennt. Das hat ursächlich mit den langen Dateinamen zu tun. Im Vergleich mit dem o.g. String der alten Dialogbox würde der Ordnername diesmal als C:\Eigene Dateien zurückgeliefert werden. Der letzte Dateiname endet mit zwei #0-Zeichen.
Durch die Trennung mit den #0-Zeichen können Sie den Puffer daher nicht direkt weiterverarbeiten; Sie würden lediglich den Namen des Ordners sehen:

MessageBox(0,buffer,nil,0);

An die Dateinamen kommen Sie aber mit Hilfe einer pchar-Variablen heran, die Sie auf den Beginn des Puffers setzen:

p := buffer;

Nun gehen Sie solange durch den Textpuffer, bis das erste Zeichen dieser Variable #0 entspricht. Dazu eignet sich am besten eine while-Schleife:

while(p[0] <> #0) do
begin
  MessageBox(Handle,p,nil,0);

Auch dieser Aufruf würde zuerst den Ordnernamen anzeigen. Mit Hilfe von inc erhöhen wir jedoch die Position der pchar-Variablen im Puffer um die Länge des aktuellen Strings (+1, da er ja mit einem #0-Zeichen endet):

  inc(p,lstrlen(p)+1);
end;

Auf diese Weise erhalten wir nacheinander die einzelnen Dateinamen und können sie mit dem Namen des Ordners benutzen.