Регистрация объектов
Для регистрации любого объекта используется обращение к глобальной процедуре Register-Type, определенной в интерфейсной части модуля Objects. Единственным параметром обращения к этой процедуре является запись типа TStreamRec, в которой группируются некоторые важные для Turbo Vision характеристики объекта:
type PStreamRec = ATStreamRec; TStreamRec = record ObjType: Word; {Регистрационный номер объекта} VMTLink: Word; {Смещение таблицы виртуальных методов} Load: Pointer; {Адрес метода чтения} Store: Pointer; {Адрес метода записи} Next: Word; {Связь в списке} end;
Для каждого объекта Вашей программы (как стандартного, так и нестандартного) должна быть создана своя запись типа TStreamRec, если только Вы собираетесь помещать соответствующий объект в поток или получать его из потока. Однако для стандартных объектов такие записи уже существуют и Вам нет нужды создавать их заново: по принятому в Turbo Vision соглашению запись TStreamRec для стандартного объекта имеет такое же имя, как имя объекта, с заменой начальной буквы Т на R. Например, для TWindow регистрационная запись называется RWindow, для TDialog – RDialog и т.д. Имеет смысл следовать этому соглашению, определяя идентификаторы регистрационных записей для нестандартных объектов.
Итак, для каждого нестандартного объекта Вы должны подготовить запись TStreamRec, причем фактически определяются только первые четыре поля этой записи, так как поле Next используется для организации связанного списка и заполняется внутри процедуры RegisterType.
В поле ObjType Вы должны поместить константу-идентификатор объекта. В Turbo Vision константы 0…99 уже используются в стандартных регистрационных записях RXXXX, таким образом, если Вы собираетесь использовать стандартные регистрационные записи, в Вашем распоряжении остаются константы в диапазоне от 100 до 65535. Выбор констант из этого диапазона может быть произвольным, однако Turbo Vision требует, чтобы каждый объект характеризовался уникальной константой. Заметим, что Turbo Vision следит за уникальностью регистрационных констант и аварийно завершает исполнение программы (код ошибки 212), если в программе делается попытка зарегистрировать два разных объекта с одинаковыми регистрационными номерами.
Поле VMTLink должно содержать смещение адреса таблицы виртуальных методов (ТВМ) объекта. Турбо Паскаль имеет стандартную функцию TypeOf (Type: object), которая возвращает адрес ТВМ для указанного типа Type объекта, поэтому поле VMTLink обычно заполняется значением Ofs (TypeOf (TName)^), где TName – имя нестандартного объекта.
Поля Load и Store должны содержать адреса соответствующих виртуальных методов (см. п.20.3), обеспечивающих чтение объектов из потока и их запись в поток.
Например, если в программе определен объект:
type TMyWindow = object (TWindow) ….. Constructor Load(var S: TStream); Procedure Store(var S: TStream); end;
То для его регистрации создается запись:
const RMyWindow: TStreamRec = ( ObjType: 100; VMTLink: Ofs(TypeOf(TMyWindow)^); Load: @TMyWindow.Load; Store: @TMyWindow.Store);
Обычно регистрация осуществляется в конструкторе Init вновь созданного объекта, например:
Constructor TMyWindow.Init; begin RegisterType(RMyWindow); ….. end;
Однако, если в программе предполагается помещать в поток (или считывать из потока) объекты разного типа, регистрацию объектов как правило реализуют отдельной процедурой, вызываемой в конструкторе Init программы или в любом другом удобном месте, но перед фактическим обращением к потоку. Например:
Procedure RegisterMyProgram; begin RegisterType(RWindow); {Регистрация стандартного объекта} RegisterType(RMyWindow); {Регистрация нового объекта} ….. end;
Для упрощения регистрации стандартных объектов в модулях Turbo Vision предусмотрены процедуры RegisterXXXX, где ХХХХ – имя соответствующего модуля. Например, процедура RegisterDialogs осуществляет регистрацию всех неабстрактных объектов модуля Dialogs, т.е. TButton, TCluster, TInputLine и т.д.; процедура RegisterViews регистрирует объекты модуля Views и т.д.