Вверх ↑
Ответов: 5446
Рейтинг: 323
#1: 2007-05-30 23:36:58 ЛС | профиль | цитата
Galkov, хорошо, давай разбираться.

Сейчас в пакете Delphi каждый компонент - это класс. Кодогенератор всего лишь создаёт экземпляры соответствующих классов, устанавливает свойства, а также связывает экземпляры (реализует логику работы программы). При этом компоненты существуют "независимо" от кодогенератора.

В пакете же Web компоненты являются продолжением кодогенератора: скриптами на внутреннем языке. При этом, наверное, можно создать механический аналог пакета Delphi с кодогенератором a-la Web, но такое решение будет лишено какой-либо изящности. При таком подходе мы получим по два файла кодов на каждый компонент (за исключением flow control компонентов, для которых достаточно одного): скрипт, формирующий экземпляр класса и его связи; и собственно код класса. Причём скрипты-формирователи буду похожи друг на друга как близнецы-братья.

iarspider писал(а):

* в начале SDK создаём в памяти заготовку кода компонента (назовём его "master"), который будет обрабатывать все события
* по мере формирования кодов содержимого - добавлять master-у обработчики и их псевдокоды (ссылки вперёд!)
* по завершении SDK мы должны разрешить все ссылки вперёд, довести псевдо-коды до окончательной формы и только тогда записать в выходной поток код master-а


Сразу замечу, что вариант с нагромождением двух файлов на компонент мне не нравится, поэтому я его не рассматриваю.

В Delphi (KOL) обработка событий компонентами основана на перехвате собственной WinMain и вызове функций по "зарегистрированным" указателям (которая в нашем случае происходит в член-процедуре Init).

Теперь пакет Web. При однофайловой схеме генерации кода, мы оказываемся вынуждены, в части обработки событий, следовать логике wxWidgets. Есть два пути: через EventTable, или через Connect() (динамическое назначение обработчиков).

1. Через EventTable мы назначаем событию член-функцию класса, в котором этот Table определён. А сделать это мы должны в неком "master"-элементе контейнера (что-то типа EditMulti), который будет выполнять роль "диспетчера" - вызывать по событию XXX свой методж OnXXX, который уже сделает нужные действия. Было бы неестественным (и блокировало бы начисто возможность создания динамических компонентов) иметь одного master-а на всю схему - у каждого контейнера должен быть свой master. Этот "элемент" должен быть и первым, и одновременно последним элементом контейнера. Первым - чтобы сказать кодогенератору, что до конца контейнера все события будет обрабатывать именно он, последним - чтобы "вернуть" старый обработчик.

2. Через Connect(). Этот метод, на первый взгляд, кажется перспективным, но при этом мы либо начисто лишаемся возможности что-либо выдавать из компонента в потоке, либо опять вынуждены прибегать к услугам "посредника" (master). Более того, в этом случае нам придётся для каждой кнопки создавать свой класс-наследник wxButton, и создавать экземпляр уже этого класса.

Надеюсь, теперь понятнее.
карма: 1

0