In Delphi program I use ExtractFileDir function for getting parent folder and this code works correctly:
Fmain.frxReport1.LoadFromFile(ExtractFileDir(ExtractFileDir(ExtractFileDir(ExtractFilePath(ParamStr(0)))))+'\FastReports\report1.fr3');
How can I modify it and get parent folder's path with using "\.." as it is realised in Delphi sample program
Update:
I wrote this code:
setcurrentdir('../../');
s1:=getcurrentdir();
frxReport1.LoadFromFile(s1+'\FastReports\report1.fr3');
but I want one-line(as my code with ExtractFileDir ) and well-readable code to replace my code.
I have a function which absolutize a relative path. To absolutize a path, you need to know the base path.
I the case of Delphi you show, the paths are relative to the project directory.
Once you have an absolute path, you can apply ExtractFilePath several times to go up in the directory levels.
Let's take an example: You have a relative path "....\SomeFile.txt". This path is relative to the base path "C:\ProgramData\Acme\Project\Demo". The complete path is: "C:\ProgramData\Acme\Project\Demo....\SomeFile.txt". Then the absolute path result of AbsolutizePath will be "C:\ProgramData\Acme\SomeFile.txt".
Note that Absolutize path take care of ".." (parent directory), "." (Current directory) and drive specification (Such as C:).
function AbsolutizePath(
const RelPath : String;
const BasePath : String = '') : String;
var
I, J : Integer;
begin
if RelPath = '' then
Result := BasePath
else if RelPath[1] <> '\' then begin
if (BasePath = '') or
((Length(RelPath) > 1) and (RelPath[2] = ':')) then
Result := RelPath
else
Result := IncludeTrailingPathDelimiter(BasePath) + RelPath;
end
else
Result := RelPath;
// If there is no drive in the result, add the one from base if any
if (Length(Result) > 1) and (Result[2] <> ':') and
(Length(BasePath) > 1) and (BasePath[2] = ':') then
Insert(Copy(BasePath, 1, 2), Result, 1);
// Delete "current dir" marker
I := 1;
while TRUE do begin
I := Pos('\.\', Result, I);
if I <= 0 then
break;
Delete(Result, I, 2);
end;
// Process "up one level" marker
I := 1;
while TRUE do begin
I := Pos('\..\', Result, I);
if I <= 0 then
break;
J := I - 1;
while (J > 0) and (not CharInSet(Result[J], ['\', ':'])) do
Dec(J);
// Check if we hit drive delimiter and fix it
if (J = 2) and (Result[J] = ':') then
J := 3;
Delete(Result, J + 1, I - J + 3);
I := J;
end;
end;