| Статьи | - Код компонента |
Код компонента
Введение
Данная статья предназначена для разработчиков элементов стандартного пакета.
Наполнение исходника компонента кодом
На втором этапе вы наполняете сгенерированный исходник компонента кодом. Прежде всего, стоит осветить несколько общих моментов при программирование компонента:
- Все Методы и Свойства компонента должны быть представлены в исходнике в следующем виде: где _Data - данные, переданные точки входа от внешних компонент, и Index - индекс точки входа(используется только для компонент с переменным числом точек таких, как FormatStr, Hub и другие), _work_ и _var_ префиксы, вставляемые HiAsm для исключения совпадения имен с операторами и функциями языка, doMethod и Property - произвольные имена методов и свойств, определяемые разработчиком.
procedure _work_doMethod(var _Data:TData; Index:word); - для методов компонента и
procedure _var_Property(var _Data:TData; Index:word); - для свойств компонента - Все События и Данные компонента должны быть представлены в исходнике в следующем виде: где THI_Event - структура из двух полей, описанная в модуле Share и содержащая тело метода и его индекс(если данная точка была связана с другой точкой), _event_ и _data_ префиксы, onEvent и Data произвольные имена.
_event_onEvent:THI_Event; - для событий компонента и
_data_Data:THI_Event; - для данных компонента - Свойства компонента, настраиваемые на этапе разработки схемы, должны быть представлены в виде:где _prop_ - префикс, вставляемый HiAsm, Property - произвольно имя и Type - тип свойства(почти всегда генерируется автоматически)
_prop_Property:Type;
- После генерации шаблона вам придется вручную прописать Pascal типы для Enum свойств, поскольку программа никак не может знать, какими они будут. Простой пример, у компонента Таймер(Timer) есть св-во Enabled описанное следующим образом: это свойство типа Enum(14) поэтому HiAsm не сможет определить для него тип данных, который вы должны будете задать сами. В данном случае это логический тип boolean.
Enable=True - таймер работает после запуска программы, False - таймер отключен|14|0|True,False
- Для инициализации компонента(если это необходимо) и для его деинициалиазации используются методы Create и Destroy соответственно:
constructor Create;
destructor Destroy; override;
Чтение данных, переданных точке входа
Точке входа данные передаются в переменной _Data типа TData. Структура TData так же объявлена в модуле Share и содержит 4 поля - первое определяет тип данных в виде номера от 1 до количества используемых типов. Все используемые типы объявлены в виде констант в модуле Share с именами data_XXX. Три оставшиеся поля это целочисленный, строковый и дробный параметры, используемые для передачи собственно данных. В таблице ниже показано, какому типу, какая константа соответствует, и в каком поле передаются данные для каждого из типов:
Комментарии:
Имя типа | Константа | Поле в _Data | Тип Delphi | Чтение |
Integer | data_int | idata | Integer | ReadInteger |
String | data_str | sdata | String | ReadString |
Data | data_data | (все) | TData | ReadData |
List | (нет) | (нет) | (нет) | (нет) |
StrList | (нет) | (нет) | (нет) | (нет) |
Icon | (нет) | (нет) | (нет) | (нет) |
Real | data_real | rdata | Real | ReadReal |
Color | data_int | idata | TColor | ReadInteger |
Script | (нет) | (нет) | (нет) | (нет) |
Stream | data_stream | idata | PStream | ReadStream |
Bitmap | data_bitmap | idata | PBitmap | ReadBitmap |
Wave | (нет) | (нет) | (нет) | (нет) |
Array | (нет) | (нет) | (нет) | (нет) |
Enum | (нет) | (нет) | (нет) | (нет) |
Types | data_types | idata | PType | ReadTypes |
Комментарии:
- (нет) - данный тип не участвует в обмене данных между компонентами
- PStream и PBitmap типы данных из библиотеки KOL, передаются в поле idata как указатели.
- Процедуры ReadXXX содержат 3 параметра: первым идет переменная _Data, переданная точке входа из вне, вторым указывается соответствующая точка данных типа Данные _data_XXXX(если она есть), и последним идет свойство компонента по умолчанию _prop_(тоже, если оно есть)
- В том случае, когда метод не принимает данные через точки _data_XXX и не использует св-ва по умолчанию, необходимо использовать ф-ции ToXXX для преобразования данных к нужному типу.
Компоненты в процессе работы
Как выглядит исходник, сгенерированный HiAsm вы можете посмотреть, нажав перед компиляцией программы сочетание клавиш Ctrl+D. В результате этого в папку Elements\code\ будут помещены все исходные коды программы. Инициализация компонент программы начинается с главного компонента проекта, например, для Windows приложения это MainForm. Затем создаются классы для всех остальных элементов и после этого они по очереди инициализируются. Совершенно очевидно, что ни в конструкторе класса(методе Create), ни в процедурах установки свойств компонента по умолчанию(если св-ва _prop_XXX вы реализуете через оператор Delphi property) вы не можете обращаться к внешним компонентам. Конечно, есть небольшая вероятность, что во время тестирования ваш компонент окажется последним в списке инициализации и вся схема уже будет загружена в память, т.е. вызов внешних методов будет работать корректно. Но не стоит забывать, что это только вероятность.
Но что делать, если вашему компоненту все же нужен доступ к форме? Такими элементами в HiAsm, например, являются !DropFile!, !KeyHook! и !ClipboardHook!, которые перекрывают оконную ф-цию главной формы, чтобы получать некоторые сообщения от ОС Windows. Для этих целей в модуле Share добавлен объект класса TInitMan, имеющий один полезный для нас интерфейсный метод: procedure InitAdd(Proc:TInitProc) где TInitProc - любая процедура класса или объекта без параметров. Достаточно в Create класса вашего компонента добавить свою процедуру этим методом, и тогда она будет вызвана после создания всех элементов схемы в любом HiAsm проекте
Но что делать, если вашему компоненту все же нужен доступ к форме? Такими элементами в HiAsm, например, являются !DropFile!, !KeyHook! и !ClipboardHook!, которые перекрывают оконную ф-цию главной формы, чтобы получать некоторые сообщения от ОС Windows. Для этих целей в модуле Share добавлен объект класса TInitMan, имеющий один полезный для нас интерфейсный метод: procedure InitAdd(Proc:TInitProc) где TInitProc - любая процедура класса или объекта без параметров. Достаточно в Create класса вашего компонента добавить свою процедуру этим методом, и тогда она будет вызвана после создания всех элементов схемы в любом HiAsm проекте
BB-code статьи для вставки
Всего комментариев: 0
(комментарии к статье еще не добавлены)