Further to this answered question I have another sticky problem. My coding is Free Pascal but Delphi solutions will work probably.
In brief, I have a string value of concatenated paths that is formed by taking a source directory and recreating that tree in a destination directory. e.g.
C:\SourceDir\SubDirA becomes F:\DestinationDir\SourceDir\SubDirA.
However, the solution I have for the Linux version of my program (as posted in the link above) doesn't quite work with Windows version because I end up with :
F:\DestionationDir\C:SourceDir\SubDirA.
which is invalid.
So I came up with this "only run in Windows" code to remove the central drive letterof the reformed path, but leave the initial one at the start by saying "Look at the string starting from the 4th character in from the left. If you find 'C:', delete it" so that the path becomes F:\DestinationDir\SourceDir\SubDirA.
{$IFDEF Windows} // Only do this for the Windows version
k := posex('C:', FinalisedDestDir, 4); // Find 'C:' in the middle of the concatanated path and return its position as k
Delete(FinalisedDestDir, k, 2); // Delete the 2 chars 'C:' of 'C:\' if found, leaving the '\' to keep the path valid
{$ENDIF}
Now, that works fine IF the C: is the source of the chosen directory. But obviously if the user is copying data from another drive (such as E:, F:, G: or whatever else drive up to Z:) it will not work.
So my question is, how do I code it so that it says "if any drive letter a: to z: is found after the 4th character from the left, delete it"? Whilst any solution that works "will do", ideally I need a fast solution. The best solution would be to not have it in there in the first place, but given the solution I posted in reply to my earlier post, I can't work out how not to have it in, due to the procedure I use to form it.
Here is a code I use in my application:
function CombinePath(const BaseDir, Path: string): string;
begin
if IsPathDelimiter(Path, 1) then
Result := ExcludeTrailingBackSlash(BaseDir) + Path else
Result := IncludeTrailingBackSlash(BaseDir) + Path;
end;
function MapRootPath(const Path, NewPath: string): string;
var
Drive, RelativePath: string;
begin
Drive := ExtractFileDrive(Path); // e.g: "C:"
RelativePath := ExtractRelativePath(Drive, Path); // e.g: "Program Files\MyApp"
Result := CombinePath(NewPath, RelativePath);
end;
Usage:
ShowMessage(MapRootPath('C:\SourceDir\SubDirA', 'F:\DestionationDir'));
// result is "F:\DestionationDir\SourceDir\SubDirA"