При работе с формами в Delphi часто возникает необходимость создавать экземпляры форм и передавать им параметры, специфичные для каждого экземпляра. В этой статье мы рассмотрим, как правильно организовать создание и хранение уникальных данных для каждого экземпляра формы.
Рассмотрим следующий пример, где создается экземпляр формы TDataForm и передается параметр Data:
type
TDataForm = class(TForm)
{ Some components}
{ Some procedures }
constructor Create(AOwner: TComponent; Data: PData; Page: String); reintroduce;
private
{ Private declarations }
public
{ Public declarations }
ViewedData: PData;
end;
var
CharacterScreen: TDataForm;
implementation
constructor TDataForm.Create(AOwner: TComponent; Data: PData; Page: String);
begin
inherited Create(nil);
ViewedData := Data;
if Page = 'Stats' then CharPageControl.TabIndex := 0;
if Page = 'Equipment' then CharPageControl.TabIndex := 1;
if Page = 'Effects' then CharPageControl.TabIndex := 2;
if Page = 'Statistics' then CharPageControl.TabIndex := 3;
ShowModal;
Free;
end;
CharacterScreen := TDataForm.Create(nil, @Data, 'Page 1');
При таком подходе, если впоследствии вызвать процедуру для этой формы, может возникнуть ошибка доступа к недопустимому адресу. При отладке переменная CharacterScreen будет иметь значение nil.
Проблема заключается в том, что мы вызываем Free в конструкторе, что делает экземпляр недоступным после закрытия формы.
Чтобы правильно создавать и управлять экземплярами форм, можно добавить статический метод в саму форму и вызывать его для создания и отображения формы. Пример кода:
type
TDataForm = class(TForm)
{ Some components}
{ Some procedures }
private
{ Private declarations }
ViewedData: PData;
constructor Create(AOwner: TComponent);
public
{ Public declarations }
class procedure Execute(Data: PData; APage: String);
end;
implementation
class function TDataForm.Execute(Data: PData; APage: String): TDataForm;
begin
Result := TDataForm.Create(nil);
Result.ViewedData := Data;
if APage = 'Характеристики' then Result.CharPageControl.TabIndex := 0 else
if APage = 'Экипировка' then Result.CharPageControl.TabIndex := 1 else
if APage = 'Эффекты' then Result.CharPageControl.TabIndex := 2 else
if APage = 'Статистика' then Result.CharPageControl.TabIndex := 3;
Result.ShowModal;
end;
constructor TDataForm.Create(AOwner: TComponent);
begin
inherited Create(nil);
end;
Теперь для отображения формы можно вызывать статический метод Execute:
var
CharacterScreen: TDataForm;
begin
CharacterScreen := TDataForm.Execute(@Data, 'Page 1');
try
// делать что-то с CharacterScreen после закрытия формы
finally
CharacterScreen.Free;
end;
end;
При таком подходе не нужно объявлять глобальную переменную для формы, что упрощает управление экземплярами форм и позволяет создавать несколько экземпляров одной формы.
Также стоит отметить, что передача данных в форму и использование ModalResult для проверки, был ли нажата кнопка "ОК" или форма была просто закрыта, является хорошей практикой.
В заключение, правильная организация экземпляров форм в Delphi заключается в использовании статических методов для создания и отображения форм, а также в передаче данных в форму и использовании ModalResult для проверки действий пользователя. Это упрощает управление экземплярами форм и делает код более чистым и легко maintainable.
В статье рассматривается, как правильно создавать и управлять экземплярами форм в Delphi, передавая им специфические параметры и обеспечивая корректное освобождение ресурсов.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.