Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

BindEvent на Init формы

0 views
Skip to first unread message

Alexander Korolev

unread,
Oct 7, 2003, 5:30:34 AM10/7/03
to
Hi All,

Хочется следующего: вызова некоторого метода базового класса формы (назовем
его AfterFormInit) после того, как выполнится Init всей иерархии классов
конкретного класса формы, причем порядок следования Init различных классов
этой иерархии может быть разным (у одного класса Dodefault() стоит после кода
Init, у другого - перед, у третьего - в середине)

Hапример так:

define class BaseForm as Form
procedure Init
......
endproc

procedure AfterFormInit
&& Хочется, чтобы мы сюда попали после всех инитов иерархии
EndProc
enddefine

define class Form1 as BaseForm
procedure Init
....
DoDefault()
....
EndProc
enddefine

define class Form2 as Form1
procedure Init
Dodefault()
....
endproc
enddefine
....
define class FormN as FormM....
enddefine

Делал следующим образом:

в BaseForm.Load писал:

procedure Load
BindEvent(This, "Init", This, "AfterFormInit", 1)
EndProc

Сначала обрадовался, что заработало, потом оказалось
а) Код AfterFormInit иногда не выполнялся (поведение случайное)
б) Иногда (при иерархии глубже трех) получаем Exception C00..5

Понимаю, что сам для себя подложил грабли, однако как можно эту задачу решить
более правильно и красиво при условии, что это не должно затрагивать код
дочерних классов, вся реализация должна идти в базовом классе?

С уважением, А. Королев

Igor Korolyov

unread,
Oct 7, 2003, 7:19:19 AM10/7/03
to
Hi, Alexander!
You wrote to All on Tue, 07 Oct 2003 13:30:34 +0400:

AK> Хочется следующего: вызова некоторого метода базового класса формы
AK> (назовем его AfterFormInit) после того, как выполнится Init всей
AK> иерархии классов конкретного класса формы, причем порядок следования
AK> Init различных классов этой иерархии может быть разным (у одного класса
AK> Dodefault() стоит после кода Init, у другого - перед, у третьего - в
AK> середине)

А это нужно _только_ для базового класса (т.е. только в одном слое
иерархии), или для произвольного?
Если только для одного - уйди от Init к своему методу CustomInit, который и
вызывай из Init-а базового класса, а после него уж пиши
This.AfterFormInit(), если не получил оттуда .F. Сам Init спрячь от
переопределения.
Думаю это самое правильное решение будет, но оно конечно затрагивает прочие
классы...

AK> Понимаю, что сам для себя подложил грабли, однако как можно эту задачу
AK> решить более правильно и красиво при условии, что это не должно
AK> затрагивать код дочерних классов, вся реализация должна идти в базовом
AK> классе?

Думаю именно так - никак не получится :( На то оно и переопределение
методов, чтобы можно было управлять порядком вызова кода родительских
классов... Может всё-же в описании классов указать, что RETURN DODEFAULT()
должно быть самой последней командой в переопределяемом Init-е... Хотя по
мне - это сильно неудобно. Как правило нужно наоборот - сначала код
родительского класса, и только потом - свой...
Может можно уйти от Init к Activate? С флажком блокирующем повторное
исполнение...

--
WBR, Igor

Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru

Alexander Korolev

unread,
Oct 7, 2003, 7:14:05 AM10/7/03
to
Tue Oct 07 2003 15:19, Igor Korolyov wrote to Alexander Korolev:

AK>> Хочется следующего: вызова некоторого метода базового класса формы
AK>> (назовем его AfterFormInit) после того, как выполнится Init всей
AK>> иерархии классов конкретного класса формы, причем порядок следования
AK>> Init различных классов этой иерархии может быть разным (у одного класса
AK>> Dodefault() стоит после кода Init, у другого - перед, у третьего - в
AK>> середине)

IK> А это нужно _только_ для базового класса (т.е. только в одном слое
IK> иерархии), или для произвольного?

Любой произвольный класс должен вести себя таким образом: после _полной_
отработки кода в методе Init вызывать метод AfterFormInit, который
предназначен для окончательного этапа инициализации контролов посредством
вызова соответствующих методов контролов, лежащих на форме. При этом контролы
"предполагают", что на момент вызова этих методов все действия по
инициализации формы уже выполнены.

С уважением, А. Королев

Igor Korolyov

unread,
Oct 8, 2003, 3:30:29 AM10/8/03
to
Hi, Alexander!
You wrote to Igor Korolyov on Tue, 07 Oct 2003 15:14:05 +0400:

[skipped]

IK>> А это нужно _только_ для базового класса (т.е. только в одном слое
IK>> иерархии), или для произвольного?

Я имел в виду, что это не абстрактная задача, т.е. _только_ в базовом классе
формы появляется такое "раздвоение" Init-а, а скажем в унаследованном от
_form классе уже не потребуется вводить After_AfterFormInit... Тогда вполне
можно пойти на создание вместо Init своего метода, Init в _form объявить
Hidden, и из него рулить вызовами FormInit и AfterFormInit... Вот если на
каждой ступени иерархии потребуется _так_ рулить последовательностью
исполнения этого метода (ну т.е. работать несмотря на то, где в ChildClass
поставят DODEFAULT () и поставят ли вообще :)) - то конечно не напасёшся
имён методов-двойников Init-а, да и не удобно...

AK> Любой произвольный класс должен вести себя таким образом: после
AK> _полной_ отработки кода в методе Init вызывать метод AfterFormInit,
AK> который предназначен для окончательного этапа инициализации контролов
AK> посредством вызова соответствующих методов контролов, лежащих на форме.
AK> При этом контролы "предполагают", что на момент вызова этих методов все
AK> действия по инициализации формы уже выполнены.

Да оно понятно в принципе... Может всё-же Form.Activate задействовать?

Sjfx

unread,
Oct 8, 2003, 3:54:44 AM10/8/03
to
Hello, Alexander!
You wrote to All on Tue, 07 Oct 2003 13:30:34 +0400:

[Skipped]
AK> procedure Load
AK> BindEvent(This, "Init", This, "AfterFormInit", 1)
AK> EndProc

AK> Сначала обрадовался, что заработало, потом оказалось
AK> а) Код AfterFormInit иногда не выполнялся (поведение случайное)
AK> б) Иногда (при иерархии глубже трех) получаем Exception C00..5

Я бы ещё пошаманил: привязал бы событие к процедуре _отдельного_
объекта, специально созданного ещё до создания формы.

А проще забить на это и ещё раз субклассировать, чтобы
Proc Init = dodefault()+код из AfterFormInit

With best regards, Sjfx.


Alexander Korolev

unread,
Oct 8, 2003, 8:55:40 AM10/8/03
to
Wed Oct 08 2003 11:54, Sjfx wrote to Alexander Korolev:

AK>> procedure Load
AK>> BindEvent(This, "Init", This, "AfterFormInit", 1)
AK>> EndProc

AK>> Сначала обрадовался, что заработало, потом оказалось
AK>> а) Код AfterFormInit иногда не выполнялся (поведение случайное)
AK>> б) Иногда (при иерархии глубже трех) получаем Exception C00..5

S> Я бы ещё пошаманил: привязал бы событие к процедуре _отдельного_
S> объекта, специально созданного ещё до создания формы.

Пробовал, то же самое причем в тех же случаях.

S> А проще забить на это и ещё раз субклассировать, чтобы
S> Proc Init = dodefault()+код из AfterFormInit

А если _это_ тоже придется субклассировать? Тогда промежуточный _этот_ класс -
родитель вызовет AfterFormInit до полной отработки метода Init класса -
потомка.

С уважением, А. Королев

Sjfx

unread,
Oct 9, 2003, 5:59:21 AM10/9/03
to
Hello, Alexander!

You wrote to Sjfx on Wed, 08 Oct 2003 16:55:40 +0400:

S>> Я бы ещё пошаманил: привязал бы событие к процедуре _отдельного_
S>> объекта, специально созданного ещё до создания формы.

AK> Пробовал, то же самое причем в тех же случаях.

Вот ить блин!.. мои соболезнования!

S>> А проще забить на это и ещё раз субклассировать, чтобы
S>> Proc Init = dodefault()+код из AfterFormInit

AK> А если _это_ тоже придется субклассировать? Тогда промежуточный _этот_
AK> класс - родитель вызовет AfterFormInit до полной отработки метода Init
AK> класса - потомка.

И проверено, что _так_ всё работает?

Кстати, в VFP-шных фреймворках обычная практика, когда внутрь цепи
субклассирования встраивается пустой класс, который является
"точкой модификации" для программистов-пользователей фреймворков.

Ну и ждём, когда поставишь SP1, сообщи о результатах.

With best regards, Sjfx.


Alexander Korolev

unread,
Oct 9, 2003, 7:06:11 AM10/9/03
to
Thu Oct 09 2003 13:59, Sjfx wrote to Alexander Korolev:

S> From: "Sjfx" <sj...@vpost.ru>

S> Hу и ждём, когда поставишь SP1, сообщи о результатах.

Ура! В SP1 вроде пофиксили! Короче когда в Load формы делаешь
BindEvent(This, "Init", This, "AfterFormInit", 1),
пока не видел случаев, чтоб возникло C5 или AfterFormInit не вызвался (что без
SP на одной из форм возникало в 1 из 2-3 случаев)

Однако другая ошибка все же не исправлена (найдено мною вчера, изложу в
следующем постинге)

С уважением, А. Королев

Alexander Korolev

unread,
Oct 9, 2003, 11:51:56 AM10/9/03
to
Thu Oct 09 2003 16:06, Alexander Korolev wrote to Sjfx:

S>> Hу и ждём, когда поставишь SP1, сообщи о результатах.

AK> Ура! В SP1 вроде пофиксили! Короче когда в Load формы делаешь
AK> BindEvent(This, "Init", This, "AfterFormInit", 1),
AK> пока не видел случаев, чтоб возникло C5 или AfterFormInit не вызвался
AK> (что без SP на одной из форм возникало в 1 из 2-3 случаев)

Упс... Теперь другая форма идет в этой ситуации на вылет с C5 (1 - 2 раза
просто AfterFormInit не вызывается, потом C0000005).

... мать, мать, мать .... - привычно отозвалось эхо :(

С уважением, А. Королев

0 new messages