Dodanie ścieżki relatywnej do pliku z pomocą Select Directory

0

Siemanko
Mam wczytywanie do Listboxa do którego dodaje ścieżkę relatywna do pliku oraz otwarcie okna dialogowego z określonej lokalizacji. Wszystko chodzi jak należy ale mam pytanie. To samo chciałbym uzyskać o ile to możliwe w SelectDirectory. Jeśli tak to jak to powinno wyglądać?

procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
begin
OpenDialog1.FileName := '';
OpenDialog1.InitialDir := extractfilepath(paramstr(0)) + 'Files\';
if OpenDialog1.Execute then
 begin
   for I := 0 to OpenDialog1.Files.Count - 1 do
   begin
       ListBox1.Items.Add(ExtractRelativePath(extractfilepath(paramstr(0)),OpenDialog1.Files[i]));  
     ListBox2.Items.Add(ExtractFileNameWithoutExtension(ExtractFileName(OpenDialog1.Files[i])));
   end;
 end;
end;

Coś takiego chciałbym uzyskać tutaj.
ListFiles (procedura przeszukująca folder)

procedure TForm1.Button1Click(Sender: TObject);
var
  LDirectory: String;
begin
  if SelectDirectory('Select directory', 'C:', LDirectory) then
    ListFiles(IncludeTrailingPathDelimiter(LDirectory), ListBox1.Items);
end;
0

Przecież to logiczne, że aby wybrać katalog to należy zamiast OpenDialog wywołać SelectDirectory. Z czym masz problem? Zamień poniższe linijki kodu:

OpenDialog1.FileName := '';
OpenDialog1.InitialDir := extractfilepath(paramstr(0)) + 'Files\';
if OpenDialog1.Execute then

na te:

var
  LDirectory: String;
begin
  if SelectDirectory('Select directory', 'C:', LDirectory) then

Jeśli warunek zostanie spełniony (czyli użytkownik faktycznie wybierze jakiś katalog) to w zmiennej LDirectory będziesz miał pełną ścieżkę wybranego katalogu.

0

A no mam problem
Nie mogę od tak tego zamienić bo chcę dodać ścieżkę relatywną.
czyli przerobić to te dwa dodania do jednego i drugiego Listboxa

ListBox1.Items.Add(ExtractRelativePath(extractfilepath(paramstr(0)),OpenDialog1.Files[i]));  
     ListBox2.Items.Add(ExtractFileNameWithoutExtension(ExtractFileName(OpenDialog1.Files[i])));

z tym

 ListFiles(IncludeTrailingPathDelimiter(LDirectory), ListBox1.Items);

procedure TForm1.Button1Click(Sender: TObject);
var
  LDirectory: String;
begin
  if SelectDirectory('Select directory', 'C:', LDirectory) then
  ListFiles(IncludeTrailingPathDelimiter(LDirectory), ListBox1.Items);
end;

ListFiles musi zostać bo jest wywołaniem procedury po niżej

procedure ListFiles(const APath: String; AFilesList: TStrings);
var
  LFileRec: TSearchRec;
begin
  AFilesList.Clear();
  if FindFirst(APath + '*.mp3', faAnyFile, LFileRec) = 0 then
    try
      repeat
        AFilesList.Add(APath + LFileRec.Name);
      until FindNext(LFileRec) <> 0;
    finally
      FindClose(LFileRec);
    end;
end;

1

No nie problem, jeśli się myśli co się robi. Przecież nie każę Ci tylko przekopiować kodu i nic więcej, a zastosować zabieg ze starego kodu w nowym... Skoro chcesz umieścić ścieżkę relatywną, a SelectDirectory zwraca absolutną to oczywiste jest, aby użyć funkcji ExtractRelativePath na zmiennej LDirectory:

procedure TForm1.Button1Click(Sender: TObject);
var
  LDirectory: String;
begin
  { wartość początkowa - ścieżka pliku wykonywalnego }
  LDirectory := ExtractFilePath(ParamStr(0));
  
  { jeżeli użytkownik wybrał jakikolwiek katalog }
  if SelectDirectory('Wybierz katalog:', LDirectory, LDirectory) then
  begin
    { zamiana ścieżki absolutnej na relatywną }
    LDirectory := ExtractRelativePath(LDirectory);
    
    { dalszy kod }
  end;
end;
0

Przepraszam i dziękuję.

LDirectory := ExtractRelativePath(LDirectory);

There is no overloaded version of 'ExtractRelativePath' that can be called with these arguments
co w takim wypadku jeszcze zrobić

0

co w takim wypadku jeszcze zrobić

Zaglądnąć do dokumentacji i próbować coś zrobić samemu, a nie tylko czekać aż wrzucę gotowca. Z pośpiechu zgubiłem jeden parametr (pierwszy), w którym powinna się znaleźć ścieżka bazowa. Tak więc w pierwszym parametrze wstaw ścieżkę pliku wykonywalnego, a w drugim podaj zmienną LDirectory.

0

To moja wina przepraszam.
Działa wszystko fajnie...

procedure TForm2.Button1Click(Sender: TObject);
var
  LDirectory: String;
begin
  { wartość początkowa - ścieżka pliku wykonywalnego }
  LDirectory := ExtractFilePath(ParamStr(0));
  { jeżeli użytkownik wybrał jakikolwiek katalog }
  if SelectDirectory('Wybierz katalog:', LDirectory, LDirectory) then
  begin
    { zamiana ścieżki absolutnej na relatywną }
    LDirectory := ExtractRelativePath(ExtractFilePath(ParamStr(0)),LDirectory );
      { dalszy kod }
   ListFiles(IncludeTrailingPathDelimiter(LDirectory), ListBox1.Items)  ;
   ListFiles (ExtractFileNameWithoutExtension(LDirectory),ListBox2.Items));
  end;
end;

... mam problem z ostatnią linijką nie potrafię jej poprawnie złożyć tak by do drugiego Listboxa dodawała same nazwy plików bez rozszerzenia za co odpowiada funkcja ExtractFileNameWithoutExtension. W tym momencie nie ma błędu kompilatora ale też nic nie dodaje

0

... mam problem z ostatnią linijką nie potrafię jej poprawnie złożyć tak by do drugiego Listboxa dodawała same nazwy plików bez rozszerzenia za co odpowiada funkcja ExtractFileNameWithoutExtension. W tym momencie nie ma błędu kompilatora ale też nic nie dodaje

Przecież używasz dokładnie tej samej funkcji dla obu komponentów, no to niby dlaczego jedno wywołanie miało by dodać pełne ścieżki plików, a drugie tylko nazwy? Poza tym robisz drugi głupi błąd, używając funkcji ExtractFileNameWithoutExtension na ścieżce katalogu ze zmiennej LDirectory. Co to niby ma dać? Kompletnie nie myślisz przy pisaniu tego programu, kopiujesz kody zupełnie bez zastanowienia.

Aby jedna procedura mogła uzupełniać dwie listy i do pierwszej dodawać względne ścieżki plików, a do drugiej tylko nazwy plików, to wystarczy nieco zmodyfikować jej nagłówek i ciało. Wystarczy dodać jeszcze jeden parametr dla drugiej listy, a w pętli dodać ścieżkę do pierwszej listy i od razu samą nazwę pliku do drugiej. Dzięki temu nie trzeba będzie dwa razy przeszukiwać dysku, bo wystarczy raz.

procedure ListFiles(const APath: String; APathsList, ANamesList: TStrings);
var
  LFileRec: TSearchRec;
begin
  AFilesList.Clear();

  if FindFirst(APath + '*.mp3', faAnyFile, LFileRec) = 0 then
  try
    repeat
      APathsList.Add(APath + LFileRec.Name);
      ANamesList.Add(ExtractFileNameWithoutExtension(LFileRec.Name));
    until FindNext(LFileRec) <> 0;
  finally
    FindClose(LFileRec);
  end;
end;

I wywołanie tej procedury:

procedure TForm2.Button1Click(Sender: TObject);
var
  LAppPath, LSelectedPath: String;
begin
  LAppPath := ExtractFilePath(ParamStr(0));

  if SelectDirectory('Wybierz katalog:', LAppPath, LSelectedPath) then
  begin
    LSelectedPath := ExtractRelativePath(LAppPath, LSelectedPath);
    LSelectedPath := IncludeTrailingPathDelimiter(LSelectedPath);

    ListFiles(LSelectedPath, ListBox1.Items, ListBox2.Items);
  end;
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1