Ich weiß nicht ob es von Interesse ist, aber ich stand erst heute vor folgendem kleinen Problem --
Ich wollte mit einer Datei arbeiten, die entweder einen relativen oder absoluten Pfad haben kann. Wenn es ein relativer Pfad ist, soll der Pfad des Bearbeitungstools als Basis herangezogen werden. Dabei entsteht allerdings u.U. eine Konstruktion wie
Code:
c:\Ein Ordner\data\..\Dateiname.txt
Es funktioniert zwar, sieht aber nicht besonders schön aus, denn eigentlich geht es durch die beiden Punkte einen Ordner nach oben, so dass der Pfad eigentlich nur:
Code:
c:\Ein Ordner\Dateiname.txt
lautet. Durch einen Zufall bin ich auf ein paar nützliche Funktionen gestoßen (s.
PSDK). Zwei davon (PathIsRelative, PathCanonicalize) habe ich für die folgende Funktion gebraucht:
Delphi-Quellcode:
const
shlwapi = 'shlwapi.dll';
function PathIsRelative(pszPath: PAnsiChar): bool; stdcall;
external shlwapi name 'PathIsRelativeA';
function PathCanonicalize(lpszDest, lpszSrc: PAnsiChar): bool;
stdcall; external shlwapi name 'PathCanonicalizeA';
function MakeAPrettyPath(const Path1, Path2: string): string;
var
buf : array[0..MAX_PATH]of char;
begin
// Puffer leeren
ZeroMemory(@buf,sizeof(buf));
// der 2. Pfad ist relativ, also sollen Pfad1 und Pfad2
// mit Hilfe von "PathCanonicalize" zusammengesetzt werden
if(PathIsRelative(pchar(Path2))) then
begin
if(not PathCanonicalize(buf,pchar(Path1 + Path2))) then
// im Fehlerfall werden die beiden Angaben dann eben
// doch zusammengefügt, ´s geht dann halt nicht anders. :o(
lstrcpy(buf,pchar(Path1 + Path2));
end
// der 2. Pfad ist ein absoluter Pfad, also wird auch
// nur er benutzt
else lstrcpy(buf,pchar(Path2));
SetString(Result,buf,lstrlen(buf));
end;
Zugegeben, es ist ein etwas spezieller Fall, aber so brauchte ich eben nicht selbst mit Strings hantieren. Und laut
PSDK laufen beide Funktionen ab Windows 98 und 2000. Und für 95 und NT4 muss lediglich der IE4 installiert werden.
"Path1" wäre also der Ordner meines erwähnten Tools, "Path2" wäre die gewünschte, zu bearbeitende Datei. Und die kann eben entweder einen relativen oder auch einen absoluten Pfad enthalten. Bei einem absoluten Pfad spielt der Ordner meines Tools keine Rolle und wird von der Funktion auch ignoriert. Und bei einem relativen Pfad kommt es zu dieser ... ich sage mal: optischen Konvertierung des Pfades
Delphi-Quellcode:
ShowMessage(
MakeAPrettyPath('c:\Ein Ordner\data','..\Dateiname.txt')
);
Auch die anderen "Path*"-Funktionen kann ich nur empfehlen. Als kleinen Bonus zeige ich noch schnell, wie man mit einem ausgelesenen Icon aus der Registry umgehen kann.
Ich meine damit solche Angaben, die den Dateinamen der Symboldatei und den Index enthalten:
Code:
c:\Meine Symbole\EineFetteIconLib.dll,123
Normalerweise könnte man jetzt mit "copy" und "pos" arbeiten. Aber wozu?
Delphi-Quellcode:
// mal angenommen, das wäre jetzt aus der Registry
// ausgelesen worden
IconLib := 'c:\Meine Symbole\EineFettIconLib.dll,123';
// zuerst den Index des Symbols ermitteln, ...
Index := PathParseIconLocation(pchar(IconLib));
// ... & dann diesen Anhang entfernen, damit nur der
// Dateiname übrig bleibt
PathRemoveArgs(pchar(IconLib));
Ach ja, die Deklarationen:
Delphi-Quellcode:
function PathParseIconLocation(pszIconFile: PAnsiChar): integer;
stdcall; external shlwapi name 'PathParseIconLocationA';
procedure PathRemoveArgs(pszPath: PAnsiChar); stdcall;
external shlwapi name 'PathRemoveArgsA';
So, das muss reichen.