Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.04.27;
Скачать: CL | DM;

Вниз

Создание и уничтожение дочерней формы   Найти похожие ветки 

 
cyber-pilot   (2008-03-30 19:38) [0]

из основной формы создаю дочернюю:

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;

Не помогает. Как делать правильно?


 
Leonid Troyanovsky ©   (2008-03-30 20:14) [1]


> cyber-pilot   (30.03.08 19:38)  

> Не помогает. Как делать правильно?

Либо не использовать ссылку fmRefers, что допустимо при Action := caFree,
либо использовать механизм Notification для того, чтобы ее обнилить
при разрушении формы.

Да, и конструктор Create(Self, FParam) - некошерный,
лучше, скажем, CreateWithParam, хотя можно просто
присвоить параметры и после обычного Create(Self).

--
Regards, LVT.


 
Loginov Dmitry ©   (2008-03-30 21:19) [2]

> Self := nil;

Обоснуй смысл сией манипуляции!


 
cyber-pilot   (2008-03-30 21:39) [3]


> либо использовать механизм Notification для того, чтобы
> ее обнилить
> при разрушении формы.

Я пока в этом слабо разбираюсь.


> Да, и конструктор Create(Self, FParam) - некошерный,
> лучше, скажем, CreateWithParam, хотя можно просто
> присвоить параметры и после обычного Create(Self).


Если вы имеете в виду переименовать Create в CreateWithParam, то это не самый лучший вариант, т.к. можно по ошибке вызвать простой Create. Присваивать параметры после создания формы мне тоже не нравится, т.к. можно забыть их присвоить, хотя пока я не вижу другого способа.


> Loginov Dmitry ©   (30.03.08 21:19) [2]
> > Self := nil;
>
> Обоснуй смысл сией манипуляции!


Хотел обнилить объект, чтобы потом можно было проверить существует он или нет.


 
Loginov Dmitry ©   (2008-03-30 21:53) [4]

> Хотел обнилить объект, чтобы потом можно было проверить
> существует он или нет.


А с чего решил, что обниливать следует именно переменную Self?


 
cyber-pilot   (2008-03-30 23:04) [5]


> А с чего решил, что обниливать следует именно переменную
> Self?


Это мое предположение, основанное только на интуиции.


 
{RASkov} ©   (2008-03-31 01:41) [6]

> cyber-pilot

Как вариант, уже сказанный в [1]:
1 Убрать все ссылки на форму TfmRefers и ее саму убрать из автосоздаваемых в настройках или файле проекта.
2 Создавать нечто так
with TfmRefers.Create() do begin
.....
Show;
end;
3 Закрытие так же ка и у тебя в [0] только убрать обниливание self"a.....
Если необходимо отслеживать кол-во открываемых(создаваемых) экземпляров TfmRefers, то и тут можно придумать, например как вариант, добавить в описание класса TfmRefers классовую переменную счетчик, ну и на создание Inc() а в деструкторе Dec()....


 
Семеныч   (2008-03-31 01:50) [7]

> 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 02:14) [8]

> классовую переменную счетчик,

ну немного не так.... т.е. нечто вот это я имел в виду:
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 02:29) [9]


> procedure TfmRefers.OnCreate();
> begin
>  INC(MyFormCount);
> end;
>
> procedure TfmRefers.OnDestroy(..);
> begin
>  DEC(MyFormCount);
> end;
>

Эээ. OnCreate & OnDestroy - это что? Пользовательские обработчики событий?


 
{RASkov} ©   (2008-03-31 02:37) [10]

> [9] Германн ©   (31.03.08 02:29)
> Пользовательские обработчики событий?

Ну да) Простой вариант... форма-то в дизайнере присутствует наверняка) Но можно и конструктор с деструктором перекрыть...
т.е. чуточку больше набирать кода "в ручки"... ;)


 
Германн ©   (2008-03-31 02:49) [11]


> {RASkov} ©   (31.03.08 02:37) [10]
>
> > [9] Германн ©   (31.03.08 02:29)
> > Пользовательские обработчики событий?
>
> Ну да) Простой вариант... форма-то в дизайнере присутствует
> наверняка) Но можно и конструктор с деструктором перекрыть.
> ..
> т.е. чуточку больше набирать кода "в ручки"... ;)
>

Эээ. Имея в классе переменную
> var MyFormCount: Integer=0;

и имея в классе
> class function TfmRefers.GetCount: Integer;
>

имхо, глупо отдавать увеличение/уменьшение счётчика пользователю. Он то про счётчик ничего не знает!


 
Германн ©   (2008-03-31 02:52) [12]


> Но можно и конструктор с деструктором перекрыть

Имхо, нужно перекрыть.


 
{RASkov} ©   (2008-03-31 02:53) [13]

> [11] Германн ©   (31.03.08 02:49)
> имхо, глупо отдавать увеличение/уменьшение счётчика пользователю

Ну почему же имхо? имхо не имхо :)
Согласен. Лучше чуточку больше вруки набить кода, но все будет так как нужно, а не так как (не)вспомнит пользователь "нового класса"...


 
{RASkov} ©   (2008-03-31 03:04) [14]

> Имхо, нужно перекрыть.

тем более конструктор оверлоаднутый... т.е. уже присутствует, нужно только туда добавить INC();.... ну и добавить перекрыть деструктор. А вот

> Если вы имеете в виду переименовать Create в CreateWithParam,
> то это не самый лучший вариант, т.к. можно по ошибке вызвать
> простой Create.

по ошибке в любом случае можно вызвать "старый" конструктор... Перекрыть же его не получится.... или у меня уже мозги спят?...


 
{RASkov} ©   (2008-03-31 03:05) [15]

> ну и добавить перекрыть деструктор

Блин, точно спят :(
:о)


 
Германн ©   (2008-03-31 03:07) [16]


> {RASkov} ©   (31.03.08 02:53) [13]
>
> > [11] Германн ©   (31.03.08 02:49)
> > имхо, глупо отдавать увеличение/уменьшение счётчика пользователю
>
> Ну почему же имхо? имхо не имхо :)
> Согласен. Лучше чуточку больше вруки набить кода, но все
> будет так как нужно, а не так как (не)вспомнит пользователь
> "нового класса"...
>

Вот только что на перекуре подумал что "имхо" в данном случае неуместно.
Уместно - "очевидно"!
:)

P.S. Хотя я в своей практике ни разу не встречал компонент считающий количество экземпляров своего класса. Имхо (извини за употребление "имхо") это НоуХау.


 
{RASkov} ©   (2008-03-31 03:11) [17]

> [16] Германн ©   (31.03.08 03:07)
> Хотя я в своей практике ни разу не встречал компонент считающий
> количество экземпляров своего класса

Ну фик знает как компонет.... я тоже как бы этого не встречал....
Но так как автору форму возможно предется показывать в единичном экземпляре, то я и подумал об этом способе, только изначально в мыслях был булевый флаг, а уж потом подумал об счетчике.... мало ли. Со счетчиком "единственность" проверить можно, а вот с булевой "триждость" уже нет :)


 
Германн ©   (2008-03-31 03:19) [18]


> {RASkov} ©   (31.03.08 03:11) [17]
>
> > [16] Германн ©   (31.03.08 03:07)
> > Хотя я в своей практике ни разу не встречал компонент
> считающий
> > количество экземпляров своего класса
>
> Ну фик знает как компонет.... я тоже как бы этого не встречал.
> ...
> Но так как автору форму возможно предется показывать в единичном
> экземпляре

Так может автору вообще не нужен наш трёп?
Он спрашивал про Ерёму, а мы спорим о Фоме?


 
{RASkov} ©   (2008-03-31 03:27) [19]

> Так может автору вообще не нужен наш трёп?

может.... а может еще один диплом сдадим :(

> Он спрашивал про Ерёму, а мы спорим о Фоме?

если честно, то это случайно получилось....
Впрочем ответ был в [1] еще, я его немного уточнил в [6] c "комментарием" в [8], и черт меня дернул сразу не перекрыть конструктор с деструктором... :)

Да уж.... и сорри за ошибки.... моск спит уже :( Пойду и я наверное тем же самым займусь)...


 
Германн ©   (2008-03-31 03:33) [20]


> Да уж.... и сорри за ошибки.... моск спит уже :( Пойду и
> я наверное тем же самым займусь)...
>

Вот это - верное решение всех вопросов!:)


 
Leonid Troyanovsky ©   (2008-03-31 09:48) [21]


> 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.


 
Leonid Troyanovsky ©   (2008-03-31 09:51) [22]


> {RASkov} ©   (31.03.08 01:41) [6]

> как вариант, добавить в описание класса TfmRefers классовую
> переменную счетчик, ну и на создание Inc() а в деструкторе
> Dec()....

Для того, чтобы проверить, существует ли форма определенного класса достаточно пройтись по Screen.Forms.

--
Regards, LVT.


 
kiberg   (2008-03-31 13:06) [23]

Всем спасибо! Очень помогли!



Страницы: 1 вся ветка

Текущий архив: 2008.04.27;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.017 c
15-1205675818
Loginov Dmitry
2008-03-16 16:56
2008.04.27
Очередное обновление Matrix32


15-1205208015
Slider007
2008-03-11 07:00
2008.04.27
С днем рождения ! 11 марта 2008 вторник


8-1179149538
Veter
2007-05-14 17:32
2008.04.27
GIF


3-1196320157
rar
2007-11-29 10:09
2008.04.27
связь Oracle и MS SQL


15-1205740771
Wold
2008-03-17 10:59
2008.04.27
SSL и TLS