Шрифт:
Интервал:
Закладка:
Эта функция может выглядеть примерно так:
function ExecuteDialog(FormClass: TFormClass; var Data): Boolean;
Я могу вам дать еще один совет: сделать все ваши формы наследниками одного класса, в котором объявлены виртуальные методы SetData и GetData.
{ ----------------------- }
unit ExecFrms;
interface
uses Forms, Controls;
type TExecForm = class(TForm)
public
procedure GetData(var Data); virtual; abstract;
procedure SetData(var Data); virtual; abstract;
end;
TExecFormClass = class of TExecForm;
function ExecuteDialog(FormClass: TExecFormClass; var Data): Boolean;
implementation
function ExecuteDialog(FormClass: TExecFormClass; var Data): Boolean;
begin
with FormClass.Create(Application) do try
SetData(Data);
Result := ShowModal = mrOK;
if Result then GetData(Data);
finally
Release;
end;
end;
end.
{ ----------------------- }
Как вы можете видеть, я поместил функцию ExecuteDialog в тот же самый модуль.
После того как Delphi создаст форму, вы должны в модуле формы сделать четыре вещи:
1. вручную измените предка формы, с TForm на TExecForm;
2. добавьте ExecFrms в список используемых модулей;
3. добавьте тип записи для хранения данных, необходимых диалогу; и
4. перекрыть методы SetData и GetData.
{ ----------------------- }
unit MyDlgs;
interface
uses WinTypes, WinProcs, Classes, Graphics, Forms,Controls, Buttons, StdCtrls, Spin, ExtCtrls, ExecFrms;
type
{ Запись для данных, необходимых модальной форме... }
TMyDlgData = record
FormCaption: string;
FormWidth: Integer;
end;
TMyDlg = class(TExecForm)
OKBtn: TBitBtn;
CancelBtn: TBitBtn;
HelpBtn: TBitBtn;
Bevel1: TBevel;
Edit1: TEdit;
SpinEdit1: TSpinEdit;
public
procedure SetData(var Data); override;
procedure GetData(var Data); override;
end;
var MyDlg: TMyDlg;
implementation
{$R *.DFM}
procedure TMyDlg.SetData(var Data);
begin
with TMyDlgData(Data) do begin
Edit1.Text := FormCaption;
SpinEdit1.Value := FormWidth;
end;
end;
procedure TMyDlg.GetData(var Data);
begin
with TMyDlgData(Data) do begin
FormCaption := Edit1.Text;
FormWidth := SpinEdit1.Value;
end;
end;
end.
{ ----------------------- }
Затем создаем и выполняем диалог, который должен выглядеть приблизительно так:
{ Добавьте ExecFrms и MyDlgs в список USES вызывающего модуля. }
procedure TForm1.GetNewCaptionAndWidthBtnClick(Sender: TObject);
var Data: TMyDlgData;
begin
Data.FormCaption := Caption;
Data.FormWidth := Width;
if ExecuteDialog(TMyDlg, Data) then begin
Caption := Data.FormCaption;
Width := Data.FormWidth;
end;
end;
Не поверите: данный код работает еще со времён Turbo Vision!
– Ed Jordan
Освобождение экземпляров формы
Delphi 1
В нашем примере для решения задачи мы передаем конструктору переменную формы. Затем, при закрытии формы, мы сбрасываем эту переменную.
Естественно, эта технология подразумевает написание некоторого кода, поэтому, если вы не расположены к этому действию, пропустите мое дальнейшее повествование.
TMyForm = class(TForm)
…
private
FormVar: ^TMyForm;
public
constructor Create(AOwner: TComponent; var AFormVar: TMyForm);
destructor Destroy; override;
end;
constructor TMyForm.Create(AOwner: TComponent; var AFormVar: TMyForm);
begin
FormVar := @AFormVar;
inherited Create;
.....
end;
destructor TMyForm.Destroy;
begin
FormVar^ := nil;
inherited Destroy;
end;
MyForm := TMyForm.Create(Self, MyForm);
MyOtherForm := TMyForm.Create(Self, MyOtherForm);
Этот код при разрушении окна автоматически сбрасывает все, что вы передаете в AFormVar, в nil.
Как вы, наверное, заметили, частный член FormVar реально является указателем на указатель. Так, читая содержимое памяти, адрес которой содержится в FormVar, мы реально получаем переменную формы. Таким образом мы можем просто установить ее в nil.
– Jeff Fisher
Условие создания главной формы?
Delphi 2
Существует ли в Delphi возможность создавать главную форму по условию? Я хочу использовать условие IF (в зависимости от передаваемого параметра) для того, чтобы определить какая форма будет главной при старте приложения. Фактически «другую» форму НЕ нужно будет загружать.
Хитрость здесь заключается в том, что мы предоставляем компилятору весь необходимый для создания форм код, но не допускаем его выполнения (IF FALSE THEN), при этом компилятор не ругается, а мы тем временем (во время выполнения приложения) выбираем и создаем главную форму. Вот пример кода, измененный .DPR-файл, который при старте случайным образом выбирает из друх форм главную:
begin
IF FALSE THEN BEGIN
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
END;
Randomize;
IF Random < 0.5 THEN Application.CreateForm(TForm1, Form1)
ELSE Application.CreateForm(TForm2, Form2);
Application.Run;
end.
Пара «подходящих» для CreateForm форм заключено в никогда не выполнимый блок, тем самым приводя компилятор в состояние свинячего восторга.
– Neil Rubenking
Динамическое создание и циклическое связывание форм
Тема: Динамическое создание и циклическое связывание форм
Как сделать простой метод, переключающий между формами?
Как мне добавить возвращаемые результаты к моей ShowModal-форме?
Как мне создавать экземпляры форм во время выполнения приложения?
Необходимый для осуществления этого метод очень прост. В моем примере я использую 3 формы с именами Mainform, Form1 и Form2. На Mainform я установил кнопку, которая выводит Form1, из нее вы можете вызвать любое количество форм (перемещаться между ними) через соответствующие кнопки, расположенные на этих формах. В моем примере "переключение" происходит между формами Form1 и Form2.
Шаг 1. Разместите следующие две строчки в секции interface той формы, которая у вас будет главной:
const
mrNext = 100;
mrPrevious = 101;
Шаг 2. Разместите на главной форме кнопку и добавьте следующий код в обработчик события ее нажатия:
var
MyForm: TForm;
R, CurForm: Integer;
begin
R := 0;
CurForm := 1;
while R <> mrCancel do begin
Case CurForm of
1: MyForm := TForm1.Create(Application);
2: MyForm := TForm2.Create(Application);
end;
try
R := MyForm.ShowModal;
finally
MyForm.Free;
end;
case R of
MrNext : Inc(CurForm);
MrPrevious : Dec(CurForm);
end;
// эти 2 строчки позволят нам не выходить за границы
if CurForm < 1 then CurForm := 2
else if CurForm > 2 then CurForm := 1;
end; // while
end;
Шаг 3. Добавьте формы 1 и 2 (и любые другие, какие вы хотите иметь) в список используемых модулей формы mainform.
Шаг 4. В форме Form1 и Form2 добавьте MainForm в список используемых модулей (чтобы они видели константы.)
Шаг 5. На форму Form1, Form2, и все последующие, добавьте 2 TBitBtn'а, с заголовками «Next» и «Previous». In the Onclick Events for these buttons add the following line of code.
Если это кнопка Next, добавьте: ModalResult := mrNext;
Если это кнопка Previous, добавьте: ModalResult := mrPrevious;
- Фундаментальные алгоритмы и структуры данных в Delphi - Джулиан Бакнелл - Программирование
- iOS. Приемы программирования - Вандад Нахавандипур - Программирование
- QT 4: программирование GUI на С++ - Жасмин Бланшет - Программирование
- C# для профессионалов. Том II - Симон Робинсон - Программирование
- Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен - Программирование
- Программирование игр и головоломок - Жак Арсак - Программирование
- Стандарты программирования на С++. 101 правило и рекомендация - Герб Саттер - Программирование
- C# 4.0: полное руководство - Герберт Шилдт - Программирование
- Программирование на Python с нуля - Максим Кононенко - Программирование
- Генерация высококачественного кода для программ, написанных на СИ - Филипп Хислей - Программирование