Статьи Королевства Дельфи

         

Основные положения


Далее по тексту "особенностью" (Particularity) я буду называть свойство, событие или метод, заменяя тем самым словосочетание одним словом. Особенность - краеугольный камень реализации Инспектора. Физически особенность представляет собой запись TParticul: TParticulKind = (pkProperty, pkMethod, pkEvent); TParticul = record Name: string; Kind: TParticulKind; Data: Word; Enabled: Boolean; Visible: Boolean; Code: string; Info: string; ReadMode: Boolean; end; где

  • Name - имя особенности, отображаемое в Инспекторе, можно (и желательно!) на русском, каждая особенность обладает уникальным именем;
  • Kind - тип особенности, т. е. свойство это, метод или событие;
  • Data - шифр типа данных, служит для назначения данному событию определённого редактора (см. далее);
  • Enabled - показывает, разрешена особенность или запрещена;
  • Visible - показывает, видима особенность или нет (в основном для внутреннего использования, но можно использовать и в явном виде);
  • Code - кодированные данные в виде строки;
  • Info - дополнительные кодированные данные (например, для целых чисел - диапазон), не редактируются Инспектором;
  • ReadMode - особенность только для чтения (не работает в случае, когда особенность является методом).
В дальнейшем понадобится понятие массива данных TParticulList = class(TList). Этот класс - простой контейнер особенностей; при добавлении в него особенности он сразу же сортирует весь массив по именам особенностей. Также при добавлении особенности метод TParticulList.Add проверяет имя особенности (TParticul.Name) на уникальность; если особенность с таким именем уже содержится в массиве, создаётся исключительная ситуация EParticul.

Инспектор обрабатывает элементы управления специального вида, которые умеют генерировать массивы особенностей и принимать особенности:

TParticulControl = class(TCustomControl) private FCaption: string; protected function GetTypeName: string; virtual; abstract; function GetParticuls: TParticulList; virtual; abstract; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; public property Caption: string read FCaption write FCaption; property TypeName: string read GetTypeName; property Particuls: TParticulList read GetParticuls; function FullText: string; procedure SetParticul(Value: TParticul); virtual; abstract; end; где

  • Caption - имя элемента управления, отображаемое в Инспекторе (аналог свойства Name: TComponentName в Инспекторе Delphi);
  • GetTypeName - функция, выдающая название типа элемента управления (можно на русском!), также отображаемое в Инспекторе;
  • GetParticuls - функция, формирующая список особенностей данного элемента управления для передачи его в Инспектор;
  • MouseDown - обработчик щелчка мышью на элементе (далее будет рассмотрен подробнее);
  • FullText - формирует строку для отображения списка редактируемых объектов в Инспекторе (Result := FCaption + ': ' + GetTypeName);
  • SetParticul - осуществляет приём изменённой особенности из Инспектора.
Элементы TParticulControl можно использовать двумя способами. Первый - прямое использование; создаётся наследник, перекрывается, например, его метод Paint и элемент можно использовать. Этот способ подходит, например, в САПРах, где вся работа заключается только в редактировании элементов. Второй - косвенное использование; при этом способе TParticulControl служит как бы оболочкой для какого-либо другого элемента (не являющегося наследником TParticulControl и, вообще говоря, даже не являющегося наследником TControl). Для второго способа существует более удобный класс: TExternalControl = class(TParticulControl) private FExternalObject: TObject; procedure SetExternalObject(Value: TObject); procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND; protected procedure CreateParams(var Params: TCreateParams); override; procedure Paint; override; public property ExternalObject: TObject read FExternalObject write SetExternalObject; procedure Refresh; end; где
  • ExternalObject - указатель на внешний объект, оболочкой которому служит данный элемент управления;
  • WMEraseBkgnd и CreateParams - перекрыты для обеспечения прозрачности;
  • Refresh - обеспечивает перерисовку при изменении размеров оболочки.
Элемент TExternalControl построен таким образом, что если редактируемый объект является наследником TControl, то при редактировании отображается именно он (в силу прозрачности TExternalControl), а если не является - отображается симпатичный квадратик (подобно как в Delphi отображаются невизуальные компоненты).



Содержание  Назад  Вперед