При проектировании ПО в среде Lazarus одним из центральных моментов является реализация приложений, в которых из главной формы выполняется вызов подчиненных форм (модально, т.е подчиненная форма не позволяет продолжать работу до своего закрытия) или нет.
В предлагаемом ниже отрывке приводится статья о работе со связанными формами, ни в коем случае не претендую на авторство, дам ссылку н исходник в следующих записях
Эта статья врядли будет интересна тем, кто раньше программировал в Delphi. Она в большей степени рассчитана на программистов VB, MS Access и других средств быстрой разработки. В каждой системе существуют свои правила и подходы, касающиеся программного открытия экранных форм, а также передачи и возврата параметров
Открытие форм в модальном режиме
Наиболее очевидным применением программного открытия дополнительной формы является выбор или поиск какого-либо значения в справочнике с последующим возвратом, например, кода найденного элемента в основную форму. Такую форму надо открывать модально, так как нет смысла продолжать выполнение основной программы, пока не сделан выбор и форма не закрыта. Попробуем это реализовать.
В качестве примера создадим новый проект и на главную форму поместим пару полей ввода и кнопок:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
В качестве тестовой задачи будем открывать дополнительную форму с полем ввода, в котором первоначально должен содержаться текст из соответствующего поля ввода главной формы. Далее предусмотрим изменение этого текста и возврат обновленного значения в главную форму. Для этого сначала создадим дополнительную форму примерно такого вида:
unit Unit2;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons;
type
{ TForm2 }
TForm2 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ private declarations }
function GetTestValue: string;
procedure SetTestValue(const AValue: string);
public
{ public declarations }
property TestValue: string read GetTestValue write SetTestValue;
end;
function RunTestForm(const InitialValue: string): string;
var
Form2: TForm2;
В качестве программного интерфейса для передачи параметра будем использовать свойство TestValue, которое определим в секции public класса формы. Также определим и реализуем более чем очевидные методы для установки и считывание значения свойства, а также обработчик события нажатия на кнопку, в котором свойству формы ModalResult присваивается значение mrOK, что и приводит к закрытию (но не уничтожению!) формы. Однако, самый большой интерес представляет функция RunTestForm. Как можно заметить, она определена вне класса формы, хотя и в том же модуле. Это может показаться странным программистам VB, где модуль класса полностью отождествляется с самим классом. Как и в Delphi, в Lazarus это не так. Хотя в одном модуле можно определить только одну форму (иначе визуальный дизайнер форм не сможет работать), другие элементы приложения не обязательно реализовывать отдельно. В нашем случае функция RunTestForm содержит код, необходимый для создания формы, передачи ей начального значения поля ввода и возврата отредактированного значения. Очевидно, что RunTestForm по смыслу связана с классом формы, поэтому будет разумно (хотя и вовсе не обязательно) расположить её в модуле формы.
implementation
function RunTestForm(const InitialValue: string): string;
begin
with TForm2.Create(Application) do // Создание экземпляра формы.
try
TestValue := InitialValue; // Установка начального значения.
ShowModal; // Вывод формы на экран в модальном режиме.
if ModalResult = mrOK then // Если форма закрыта нажатием кнопки, подтверждающей изменения,
result := TestValue // возвращаем изменённое значение.
else // Если форма закрыта любым другим способом, т.е. изменения отменены,
result := InitialValue; // возвращаем первоначальное значение.
finally
Free; // Уничтожение экземпляра формы и высвобождение ресурсов.
end;
end;
{ TForm2 }
procedure TForm2.Button1Click(Sender: TObject);
begin
ModalResult := mrOK;
end;
function TForm2.GetTestValue: string;
begin
result := Edit1.Text;
end;
procedure TForm2.SetTestValue(const AValue: string);
begin
Edit1.Text := AValue;
end;
initialization
{$I unit2.lrs}
end.
Теперь посмотрим, как использовать всё это в основной форме. Добавим в обработчики событий нажатия на кнопки вызовы функции RunTestForm, в результате чего раздел реализации модуля главной формы приобретёт такой вид:
implementation
uses
Unit2;
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text := RunTestForm(Edit1.Text);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Edit2.Text := RunTestForm(Edit2.Text);
end;
initialization
{$I unit1.lrs}
end.
Вот и всё. Только не забудьте в свойствах проекта удалить дополнитетьную форму из списка автоматически создающихся форм. Теперь можно потестировать, то, что у нас получилось. Запустите программу и понажимайте кнопки на главной форме. Обратите внимание, что пока дополнительная форма присутствует на экране, Вы не можете перевести фокус на какую-либо другую форму, как и положено для модального режима.
Комментариев нет:
Отправить комментарий