Основные положения
Далее по тексту "особенностью" (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 - особенность только для чтения (не работает в случае, когда особенность является методом).
Инспектор обрабатывает элементы управления специального вида, которые умеют генерировать массивы особенностей и принимать особенности:
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 - осуществляет приём изменённой особенности из Инспектора.
- ExternalObject - указатель на внешний объект, оболочкой которому служит данный элемент управления;
- WMEraseBkgnd и CreateParams - перекрыты для обеспечения прозрачности;
- Refresh - обеспечивает перерисовку при изменении размеров оболочки.
Элементы управления TParticulControl обрабатываются только одним способом - щелчок мышью (с нажатой клавишей Shift или без неё). При щелчке без нажатия Shift элемент добавляется в список активных элементов (т. е. тех, которые обрабатываются в настоящий момент Инспектором) Actives: TList, который предварительно очищается. При щелчке при нажатой Shift элемент также добавляется в Actives, но без предварительной его очистки.
Для того чтобы особенности отображались в Инспекторе, они должны быть предварительно зарегистрированы процедурой: RegisterData(Data: Word; AEditor: TParticulEditorClass; AExecutor: TExecutor); где
- Data - уникальный номер для регистрируемого типа;
- AEditor - ссылка (указатель на класс) на класс редактора (см. ниже);
- AExecutor - обрабатывающая процедура (см. ниже).
К каждой особенности, благодаря регистрации, привязывается редактор определённого класса и процедура обработки следующего типа: TExecutor = function(Code, Info: string; var Changed: Boolean; ReadMode: Boolean = False): string; где
- Code - кодированные данные из TParticul.Code;
- Info - дополнительные кодированные данные из TParticul.Info;
- Changed - булева переменная, показывающая, были ли сделаны изменения (True) или нет (False);
- ReadMode - запрещение изменения Code (по умолчанию - False).
Применение этой процедуры будет показано ниже.
Редактор особенностей представляет собой наследника от класса TParticulEditor, описание которого дано ниже: TParticulEditor = class protected FOldCode: string; FParticul: TParticul; FExecutor: TExecutor; procedure Init(AControl: TWinControlClass); procedure SetParticul(Value: TParticul); virtual; public Control: TWinControl; property Executor: TExecutor read FExecutor write FExecutor; property Particul: TParticul read FParticul write SetParticul; constructor Create; virtual; destructor Destroy; override; procedure Make; end; TParticulEditorClass = class of TParticulEditor; где
- Init - процедура, создающая редактор класса AControl, строго обязательна в конструкторе;
- Control - то, что будет отображено в Инспекторе (собственно редактор);
- Partucul - редактируемое свойство;
- Executor - процедура-обработчик типа TExecutor;
- Make - обновление Инспектора.