В этой статье мы рассмотрим, как создавать динамические формы в Delphi и Free Pascal (Lazarus) и назначать им пользовательские события, такие как OnCreate, OnClose, OnShow и другие. Это полезная техника, когда вам нужно генерировать формы во время выполнения программы, а не на этапе проектирования.
Проблема динамического создания форм с событиями
Как видно из исходного вопроса пользователя majid.ebru, основная сложность заключается в том, чтобы:
Создать форму динамически
Назначить ей обработчики событий
Сделать это в отдельном модуле для повторного использования
Решение: использование объекта для хранения обработчиков событий
Как предложили участники форума TRon и cdbc, лучший подход - создать специальный объект, который будет содержать все необходимые обработчики событий. Вот полное решение:
unit MyDynamicFormUnit;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Dialogs;
type
TDynamicFormEvents = object
procedure HandleFormCreate(Sender: TObject);
procedure HandleFormShow(Sender: TObject);
procedure HandleFormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure HandleFormClick(Sender: TObject);
end;
procedure CreateDynamicForm(const AFormName, ACaption: string);
implementation
procedure TDynamicFormEvents.HandleFormCreate(Sender: TObject);
begin
ShowMessage('Форма ' + (Sender as TForm).Name + ' создана!');
end;
procedure TDynamicFormEvents.HandleFormShow(Sender: TObject);
begin
(Sender as TForm).Caption := 'Динамическая форма: ' + (Sender as TForm).Name;
end;
procedure TDynamicFormEvents.HandleFormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
if MessageDlg('Закрыть форму?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then
CloseAction := caNone
else
CloseAction := caFree;
end;
procedure TDynamicFormEvents.HandleFormClick(Sender: TObject);
begin
ShowMessage('Вы кликнули по форме ' + (Sender as TForm).Name);
end;
procedure CreateDynamicForm(const AFormName, ACaption: string);
var
Events: TDynamicFormEvents;
begin
with TForm.Create(nil) do
try
Name := AFormName;
Caption := ACaption;
Position := poScreenCenter;
Width := 400;
Height := 300;
// Назначаем обработчики событий
OnCreate := @Events.HandleFormCreate;
OnShow := @Events.HandleFormShow;
OnClose := @Events.HandleFormClose;
OnClick := @Events.HandleFormClick;
ShowModal;
finally
Free;
end;
end;
end.
Как использовать этот модуль
В основном модуле программы вы можете вызвать создание динамической формы следующим образом:
unit MainForm;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, StdCtrls, MyDynamicFormUnit;
type
TfrmMain = class(TForm)
btnCreateForm: TButton;
procedure btnCreateFormClick(Sender: TObject);
end;
var
frmMain: TfrmMain;
implementation
{$R *.lfm}
procedure TfrmMain.btnCreateFormClick(Sender: TObject);
begin
CreateDynamicForm('DynamicForm1', 'Моя динамическая форма');
end;
end.
Альтернативное решение: использование классов вместо объектов
Вместо объекта можно использовать класс. Это дает больше гибкости, особенно если нужно сохранять состояние между вызовами событий:
unit MyDynamicFormClassUnit;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Dialogs;
type
TDynamicFormHandler = class
private
FFormCount: Integer;
public
procedure HandleFormCreate(Sender: TObject);
procedure HandleFormShow(Sender: TObject);
procedure HandleFormClose(Sender: TObject; var CloseAction: TCloseAction);
property FormCount: Integer read FFormCount;
end;
procedure CreateDynamicFormWithClass(const AFormName, ACaption: string);
implementation
procedure TDynamicFormHandler.HandleFormCreate(Sender: TObject);
begin
Inc(FFormCount);
ShowMessage(Format('Создана форма #%d: %s', [FFormCount, (Sender as TForm).Name]));
end;
procedure TDynamicFormHandler.HandleFormShow(Sender: TObject);
begin
(Sender as TForm).Caption := Format('%s (обработано форм: %d)',
[(Sender as TForm).Name, FFormCount]);
end;
procedure TDynamicFormHandler.HandleFormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
CloseAction := caFree;
ShowMessage(Format('Форма %s закрыта. Всего обработано: %d',
[(Sender as TForm).Name, FFormCount]));
end;
procedure CreateDynamicFormWithClass(const AFormName, ACaption: string);
var
Handler: TDynamicFormHandler;
begin
Handler := TDynamicFormHandler.Create;
try
with TForm.Create(nil) do
try
Name := AFormName;
Caption := ACaption;
Position := poScreenCenter;
Width := 400;
Height := 300;
OnCreate := @Handler.HandleFormCreate;
OnShow := @Handler.HandleFormShow;
OnClose := @Handler.HandleFormClose;
ShowModal;
finally
Free;
end;
finally
Handler.Free;
end;
end;
end.
Важные замечания
Сигнатуры методов: Каждое событие имеет строго определенную сигнатуру. Например:
OnCreate: procedure(Sender: TObject)
OnClose: procedure(Sender: TObject; var CloseAction: TCloseAction)
OnClick: procedure(Sender: TObject)
Освобождение ресурсов: Динамически созданные формы должны быть освобождены. В примерах используется ShowModal с последующим Free, либо обработчик OnClose с CloseAction := caFree.
Повторное использование кода: Вынесение логики в отдельный модуль (как в примерах) позволяет легко использовать этот функционал в разных проектах.
Заключение
Динамическое создание форм с назначением событий - мощная техника в Delphi и Free Pascal. Использование объектов или классов для хранения обработчиков событий делает код более организованным и пригодным для повторного использования. Представленные решения демонстрируют оба подхода и могут быть адаптированы под конкретные нужды вашего проекта.
Статья описывает создание динамических форм в Delphi/Free Pascal с назначением пользовательских событий через объекты или классы-обработчики.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.