![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как правильно динамически создавать дочерние формы [D2005, XP]
девушка © (2008-12-19 09:10:00)Добрый день!
Вопрос насколько правильно динамически создавать формы так:
Код родительской формы:
procedure TMainForm.Add_childForm();
var
FChild: TFChild;
begin
FSborki:=TFChild.Create(FMain);
FChild.Show;
end;
Код дочерней формы:
procedure TFChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
end;
Достаточно ли этого или тербуются еще действия по освобождению памяти?
Jeer (2008-12-19 15:09:00) [1]По поводу SDI:
В дочерних:
OnClose
Action := caFree;
OnDestroy
fmMy := nil
При пересоздании из главной формы (скажем по клику на Button):
if (fmMy = nil) then fmMy := TMyForm.Create;
fmMy.Show;
По поводу передачи параметров в большинстве случае мне хватает:
constructor TMyForm.Create(AOwner: TComponent; vPar: integer; vStr: string);
begin
fPar := vPar;
fStr := vStr;
inherited Create(AOwner);
end;
Впрочем, вполне может подойти и такой вариант, с учетом возможности возврата данных из форм:
constructor CreateWithParams(Value: Pointer; Owner: TComponent);
Anatoly Podgoretsky (2008-12-19 15:05:00) [2]
> Jeer © (19.12.08 11:41) [13]
Нет что бы прямо сказать, все намеками и намеками.
Сергей М. (2008-12-19 14:24:00) [3]
> Tparams
Можно и TParams, но тянуть из-за него одного в свой проект целый db.pas нет никакого резона, если конечно же в проекте этот юнит уже не участвует.
Если предполагаются заранее неизвестные кол-во и типы параметров, то удобно использовать [Ole]Variant или открытый массив.
девушка (2008-12-19 14:02:00) [4]ясно - Tparams :)
Сергей М. (2008-12-19 14:01:00) [5]
> девушка (19.12.08 13:58) [17]
Да практически какой угодно)
Тут полный простор для выбора.
девушка (2008-12-19 13:58:00) [6]> Сергей М.
Спасибо :) теперь в голове моей не опилки, да-да-да!
А какой тип посоветуете выбрать для FParams?
Сергей М. (2008-12-19 13:24:00) [7]
> девушка
Да.
FMain в дан.случае будет владельцем создаваемой доч.формы.
Владелец будет ответственен за автоматическое ее уничтожение.
При прочих равных условиях с тем же успехом в дан.случае можно указать и Application.
> методы для инициализации вызываем в OnShow
По хорошему инициализацию следует выполнять при создании (OnCreate), а не при визуализации (OnShow). Для MDIChild-формы это, конечно, не существенно, поскольку она возбуждает событие OnShow всего один раз (ибо скрыть и вновь показать ее нельзя) после создания и непосредственно перед тем как становится видимой.
> как лучше в этом случае передавать дочерней форме некие
> параметры
Точно так же как и для любого другого объекта - объявляется и реализуется собственный конструирующий метод с требуемыми параметрами:
TMyChildForm = class(..)
..
private
FParams: ..;
..
public
constructor Create(AOwner: TComponent; Params: ...);
..
end;
..
constructor TMyChildForm.Create(AOwner: TComponent; Params: ...);
begin
..
FParams: = Params; // сохраним переданные параметры
inherited Create(AOwner);// и собственно создадим форму
..
end;
..
TMyChildForm.Create(владелец, параметры);
девушка (2008-12-19 11:56:00) [8]Т.е. я так понимаю для MDI вполне нормально
procedure TMainForm.Add_childForm();
begin
TFChild.Create(FMain);
end
а методы для инициализации вызываем в OnShow. Правда тогда не понятно, как лучше в этом случае передавать дочерней форме некие параметры...
девушка (2008-12-19 11:51:00) [9]
FChild.Show;
--- опечатка
имелось ввиду :
procedure TMainForm.Add_childForm();
var
FChild: TFChild;
begin
FChild:=TFChild.Create(FMain);
FChild.Show;
end;
> Это если речь идет о MDI приложении, а не SDI.
> Я вовсе не уверен, что автор поста понимает "динамически
> создавать дочерние формы" именно в контексте MDI.
--- в данном вопросе речь идет об MDI
По поводу SDI -
procedure Add_newForm();
var
FChild: TFChild;
begin
FChild:=TFChild.Create(Application);
FChild.Show;
end;
Я так понимаю о корректном освобождении памяти заботится Application?
И в отличии от MDI форма не будет сразу видима...
Jeer (2008-12-19 11:41:00) [10]
> Anatoly Podgoretsky © (19.12.08 11:38) [12]
Естественно, на что и намекнул в [2] :)
> то все равно форма потеряна не будет,
Это смотря как создавать и убивать.
А то наплодят одинаковых форм с одинаковой фамилией, вот и потеряют ссылки на предыдущие.
Anatoly Podgoretsky (2008-12-19 11:38:00) [11]Неправильно, FChild имеет произвольное значение, поэтому все, вплоть до AV - но никогда не покажет созданую форму.
Сергей М. (2008-12-19 11:20:00) [12]А если даже и SDI, то все равно форма потеряна не будет, только доступ к ней по-другому будет возможен
Сергей М. (2008-12-19 11:18:00) [13]
> Я вовсе не уверен
Ну тогда у автора с терминологией беда)
Jeer (2008-12-19 11:12:00) [14]Это если речь идет о MDI приложении, а не SDI.
Я вовсе не уверен, что автор поста понимает "динамически создавать дочерние формы" именно в контексте MDI.
Сергей М. (2008-12-19 11:01:00) [15]
> создавать ли локальную переменную FSborki
ПРи прочих равных условиях можно не создавать - доступ к любой успешно созданной и существующей доч.форме осуществляется через св-во MDIChildren родительской MDI-формы.
Сергей М. (2008-12-19 10:58:00) [16]
> девушка
Вызов Show вообще не нужен - доч.форма в VCL MDI-приложении не может быть невидимой, и создается она ужевидимой.
девушка (2008-12-19 10:55:00) [17]Просто вопрос в том - создавать ли локальную переменную FSborki - которая, как я понимаю, будет уничтожена после отработки функции, только для того, чтобы вызвать метод Show...
девушка (2008-12-19 10:54:00) [18]
> а поскольку ( я надеюсь ) Вы не убили публичные методы Show
> и пр
Не убили :) в крайнем случае мы создадим методы с именами типа ShowData
Jeer (2008-12-19 09:44:00) [19]FSborki это и есть переменная класса TFChild, а поскольку ( я надеюсь ) Вы не убили публичные методы Show и пр, то FSborki прекрасно знает о них.
девушка (2008-12-19 09:38:00) [20]
> А Это зачем ?
Т.е. создаем без промежуточной переменной, а в метод Create добавляем вызовы Init, Show и т.д?