![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Создание и уничтожение дочерней формы
cyber-pilot © (2008-03-30 19:38:00)из основной формы создаю дочернюю:
if not Assigned(fmRefers) then
fmRefers := TfmRefers.Create(Self, FParam);
fmRefers.Show;
первый раз создается нормально, а после того как я ее закрываю и пытаюсь открыть снова условие не срабатывает, выдается ошибка.
Пробовал у дочерней формы писать так:
procedure TfmRefers.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
Self := nil;
end;
Не помогает. Как делать правильно?
kiberg (2008-03-31 13:06:00) [1]Всем спасибо! Очень помогли!
Leonid Troyanovsky (2008-03-31 09:51:00) [2]
> {RASkov} © (31.03.08 01:41) [6]
> как вариант, добавить в описание класса TfmRefers классовую
> переменную счетчик, ну и на создание Inc() а в деструкторе
> Dec()....
Для того, чтобы проверить, существует ли форма определенного класса достаточно пройтись по Screen.Forms.
--
Regards, LVT.
Leonid Troyanovsky (2008-03-31 09:48:00) [3]
> cyber-pilot (30.03.08 21:39) [3]
> Я пока в этом слабо разбираюсь.
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
FForm: TForm;
protected
procedure Notification(AComponent: TComponent; Operation: TOperation);override;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
unit2;
procedure TForm1.Notification;
begin
inherited;
if (AComponent = FForm) and
(Operation = opRemove) then
FForm := nil;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if not Assigned(Form) then
FForm := TForm2.Create(Self);
FForm.Show;
end;
> Если вы имеете в виду переименовать Create в CreateWithParam,
> то это не самый лучший вариант, т.к. можно по ошибке вызвать
> простой Create.
Конструкторов у объекта может быть несколько.
А чтоб не ошибаться нужно понятно их называть.
У компонента ж (коим является и TForm) должен
быть конструктор Create(AOwner: TComponent).
Вот например:
constructor TMyComponent.Create(AOwner: TComponent); // override;
begin
inherited;
Init(..); // инициализация
end;
constructor TMyComponent.CreateWithParam(AOwner: TComponent; Param: TParam); // virtual;
begin
Create(AOwner); // вызов "простого" конструктора (инициализация)
SetParam(Param); // установка доп. парам.
end;
--
Regards, LVT.
Германн (2008-03-31 03:33:00) [4]
> Да уж.... и сорри за ошибки.... моск спит уже :( Пойду и
> я наверное тем же самым займусь)...
>
Вот это - верное решение всех вопросов!:)
{RASkov} (2008-03-31 03:27:00) [5]> Так может автору вообще не нужен наш трёп?
может.... а может еще один диплом сдадим :(
> Он спрашивал про Ерёму, а мы спорим о Фоме?
если честно, то это случайно получилось....
Впрочем ответ был в [1] еще, я его немного уточнил в [6] c "комментарием" в [8], и черт меня дернул сразу не перекрыть конструктор с деструктором... :)
Да уж.... и сорри за ошибки.... моск спит уже :( Пойду и я наверное тем же самым займусь)...
Германн (2008-03-31 03:19:00) [6]
> {RASkov} © (31.03.08 03:11) [17]
>
> > [16] Германн © (31.03.08 03:07)
> > Хотя я в своей практике ни разу не встречал компонент
> считающий
> > количество экземпляров своего класса
>
> Ну фик знает как компонет.... я тоже как бы этого не встречал.
> ...
> Но так как автору форму возможно предется показывать в единичном
> экземпляре
Так может автору вообще не нужен наш трёп?
Он спрашивал про Ерёму, а мы спорим о Фоме?
{RASkov} (2008-03-31 03:11:00) [7]> [16] Германн © (31.03.08 03:07)
> Хотя я в своей практике ни разу не встречал компонент считающий
> количество экземпляров своего класса
Ну фик знает как компонет.... я тоже как бы этого не встречал....
Но так как автору форму возможно предется показывать в единичном экземпляре, то я и подумал об этом способе, только изначально в мыслях был булевый флаг, а уж потом подумал об счетчике.... мало ли. Со счетчиком "единственность" проверить можно, а вот с булевой "триждость" уже нет :)
Германн (2008-03-31 03:07:00) [8]
> {RASkov} © (31.03.08 02:53) [13]
>
> > [11] Германн © (31.03.08 02:49)
> > имхо, глупо отдавать увеличение/уменьшение счётчика пользователю
>
> Ну почему же имхо? имхо не имхо :)
> Согласен. Лучше чуточку больше вруки набить кода, но все
> будет так как нужно, а не так как (не)вспомнит пользователь
> "нового класса"...
>
Вот только что на перекуре подумал что "имхо" в данном случае неуместно.
Уместно - "очевидно"!
:)
P.S. Хотя я в своей практике ни разу не встречал компонент считающий количество экземпляров своего класса. Имхо (извини за употребление "имхо") это НоуХау.
{RASkov} (2008-03-31 03:05:00) [9]> ну и добавить перекрыть деструктор
Блин, точно спят :(
:о)
{RASkov} (2008-03-31 03:04:00) [10]> Имхо, нужно перекрыть.
тем более конструктор оверлоаднутый... т.е. уже присутствует, нужно только туда добавить INC();.... ну и добавить перекрыть деструктор. А вот
> Если вы имеете в виду переименовать Create в CreateWithParam,
> то это не самый лучший вариант, т.к. можно по ошибке вызвать
> простой Create.
по ошибке в любом случае можно вызвать "старый" конструктор... Перекрыть же его не получится.... или у меня уже мозги спят?...
{RASkov} (2008-03-31 02:53:00) [11]> [11] Германн © (31.03.08 02:49)
> имхо, глупо отдавать увеличение/уменьшение счётчика пользователю
Ну почему же имхо? имхо не имхо :)
Согласен. Лучше чуточку больше вруки набить кода, но все будет так как нужно, а не так как (не)вспомнит пользователь "нового класса"...
Германн (2008-03-31 02:52:00) [12]
> Но можно и конструктор с деструктором перекрыть
Имхо, нужноперекрыть.
Германн (2008-03-31 02:49:00) [13]
> {RASkov} © (31.03.08 02:37) [10]
>
> > [9] Германн © (31.03.08 02:29)
> > Пользовательские обработчики событий?
>
> Ну да) Простой вариант... форма-то в дизайнере присутствует
> наверняка) Но можно и конструктор с деструктором перекрыть.
> ..
> т.е. чуточку больше набирать кода "в ручки"... ;)
>
Эээ. Имея в классе переменную
> var MyFormCount: Integer=0;
и имея в классе
> class function TfmRefers.GetCount: Integer;
>
имхо, глупо отдавать увеличение/уменьшение счётчика пользователю. Он то про счётчик ничего не знает!
{RASkov} (2008-03-31 02:37:00) [14]> [9] Германн © (31.03.08 02:29)
> Пользовательские обработчики событий?
Ну да) Простой вариант... форма-то в дизайнере присутствует наверняка) Но можно и конструктор с деструктором перекрыть...
т.е. чуточку больше набирать кода "в ручки"... ;)
Германн (2008-03-31 02:29:00) [15]
> procedure TfmRefers.OnCreate();
> begin
> INC(MyFormCount);
> end;
>
> procedure TfmRefers.OnDestroy(..);
> begin
> DEC(MyFormCount);
> end;
>
Эээ. OnCreate & OnDestroy - это что? Пользовательские обработчики событий?
{RASkov} (2008-03-31 02:14:00) [16]> классовую переменную счетчик,
ну немного не так.... т.е. нечто вот это я имел в виду:
TfmRefers = class(TForm)
..........
public
class function GetCount: Integer;
end;
.............................
var MyFormCount: Integer=0;
class function TfmRefers.GetCount: Integer;
begin
Result:=MyFormCount;
end;
procedure TfmRefers.OnCreate();
begin
INC(MyFormCount);
end;
procedure TfmRefers.OnDestroy(..);
begin
DEC(MyFormCount);
end;
procedure TfmRefers.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
end;
Ну и проверка как-нибудь типа так:if TfmRefers.GetCount=5 then "Создано 5 форм уже"
Семеныч (2008-03-31 01:50:00) [17]> cyber-pilot (30.03.08 19:38)
1. Assigned проверяет на nil. И все.
2. Имеем: if not Assigned(fmRefers) then...
а). При первом создании формы переменная fmRefers проинициализировалась. Теперь она не равна nil. Пока что все ОК.
б). Форму убили. А разве переменная fmRefers изменилась? Нет. Да и с какой стати ей было меняться? Разве ее кто-нибудь менял? Нет. И поэтому она по-прежнему не равна nil.
в). Что теперь получим в итоге проверки if not Assigned(fmRefers) then...?
Правильно - туфту получим. В этом весь и фокус.
{RASkov} (2008-03-31 01:41:00) [18]> cyber-pilot
Как вариант, уже сказанный в [1]:
1 Убрать все ссылки на форму TfmRefers и ее саму убрать из автосоздаваемых в настройках или файле проекта.
2 Создавать нечто так
with TfmRefers.Create() do begin
.....
Show;
end;
3 Закрытие так же ка и у тебя в [0] только убрать обниливание self'a.....
Если необходимо отслеживать кол-во открываемых(создаваемых) экземпляров TfmRefers, то и тут можно придумать, например как вариант, добавить в описание класса TfmRefers классовую переменную счетчик, ну и на создание Inc() а в деструкторе Dec()....
cyber-pilot (2008-03-30 23:04:00) [19]
> А с чего решил, что обниливать следует именно переменную
> Self?
Это мое предположение, основанное только на интуиции.
Loginov Dmitry (2008-03-30 21:53:00) [20]> Хотел обнилить объект, чтобы потом можно было проверить
> существует он или нет.
А с чего решил, что обниливать следует именно переменную Self?