Poniżej przedstawiam mój sposób wykorzystania okien dialogowych; Mam nadzieję, że nic nie pomyliłem (pisałem z pamięci) - w razie nieprawidłowości poprawię; To okno dialogowe służy przykładowo do pobrania listy plików - pozycji z kontrolki klasy TListBox
; Po wybraniu odpowiednich pozycji i wciśnięciu przycisku btnAdd
są kopiowane do pola FFormFilesList
w klasie formularza, następnie przed zwolnieniem formularza z pamięci lista plików zawarta w klasie formularza jest kopiowana do listy zawartej w klasie dialogu;
Nie trzeba tworzyć dodatkowej listy w klasie formularza, bo w zdarzeniu OnClose
można kopiować bezpośrednio z kontrolki - jak kto woli; Chciałem tym jedynie pokazać w jaki sposób lista tych plików wędruje z formularza (TFilesForm.FFormFilesList
) do klasy dialogu (TFilesDialog.FDialogFilesList
), a z kolei z niej do funkcji wykorzystującej dialog (funkcja UseFilesDialog
, argument FilesList
); Obie klasy muszą być w jednym module;
Deklaracja klasy formularza
type
TFilesForm = class(TForm)
lbFiles: TListBox;
btnAdd: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnAddClick(Sender: TObject);
private
FFormFilesList: TStrings;
end;
Definicje zdarzeń
procedure TFilesForm.FormCreate(Sender: TObject);
begin
FFormFilesList := TStringList.Create();
end;
procedure TFilesForm.FormDestroy(Sender: TObject);
begin
FFormFilesList.Free();
end;
procedure TFilesForm.btnAddClick(Sender: TObject);
begin
for I := 0 to Pred(lbFiles.Items.Count) do
if lbFiles.Selected[I] then
FFormFilesList.Add(lbFiles.Items[I]);
if FFormFilesList.Items.Count = 0 then
ShowMessage('Nie wybrano plików!')
else
ModalResult := mrOk;
end;
Deklaracja klasy dialogu zarządzającego formularzem
type
TFilesDialog = class(TObject)
private
FFilesForm: TFilesForm;
FDialogFilesList: TStrings;
procedure DialogClose(Sender: TObject; var Action: TCloseAction);
public
constructor Create();
destructor Destroy(); override;
function Execute(Owner: TComponent): Boolean;
public
property FilesList: TStrings read FDialogFilesList;
end;
Definicje metod
constructor TFilesDialog.Create();
begin
inherited Create();
FFilesForm := nil;
FDialogFilesList := TStringList.Create();
end;
destructor TFilesDialog.Destroy();
begin
FDialogFilesList.Free();
inherited Destroy();
end;
procedure TFilesDialog.DialogClose(Sender: TObject; var Action: TCloseAction);
var
I: Integer;
begin
if FFilesForm.FFormFilesList.Count > 0 then
FDialogFilesList.Assign(FFilesForm.FFormFilesList);
//Action := caFree;
end;
function TFilesDialog.Execute(Owner: TComponent): Boolean;
begin
if not Assigned(FFilesForm) then
FFilesForm := TFilesForm.Create(Owner);
FFilesForm.OnClose := DialogClose;
Result := FFilesForm.ShowModal = mrOk;
end;
Przykładowa funkcja wykorzystująca klasę dialogu
function UseFilesDialog(Owner: TComponent; var{out} FilesList: TStrings): Boolean;
var
FilesDlg: TFilesDialog;
begin
FilesDlg := TFilesDialog.Create();
try
Result := FilesDlg.Execute(Owner);
if FilesDlg.FilesList.Count > 0 then
FilesList.Assign(FilesDlg.FilesList);
finally
FilesDlg.Free();
end;
end;
Przykład użycia powyższej funkcji
procedure TForm1.Button1Click(Sender: TObject);
var
slFiles: TStrings;
begin
slFiles := TStringList.Create();
try
if UseFilesDialog(Self, slFiles) then
{ wykorzystanie listy plików z slFiles }
finally
slFiles.Free();
end;
end;
Metoda według mnie bezpieczna, daje możliwość ręcznego zarządzania tworzonym i zwalnianym dynamicznie formularzem, a także zwracania dowolnych danych, nie wliczając w to ModalResult
; Mnie ta metoda nigdy nie zawiodła - nie miałem problemów z wyciekami pamięci czy niewiadomego pochodzenia AV; Jednak w/w kodu nie kompilowałem i nie testowałem, więc mogłem coś pomylić - jakby coś było nie tak - poprawię.