Создание собственных редакторов свойств
Перед тем как создавать собственный редактор свойств компонента, рассмотрим сначала имеющиеся в Delphi редакторы свойств. Их достаточно легко видеть в окне инспектора объектов, когда вы пытаетесь изменить какое-либо свойство компонента. Например, когда вы изменяете свойство Color для того или иного компонента, вы видите редактор свойства цвета. Важно заметить, что все свойства компонентов имеют свои редакторы, даже такие простейшие свойства, как Caption, Height, Enabled. Особенностью этих редакторов является то, что компоненты "не знают", какие редакторы вы используете для изменения их свойств. Это может навести на мысль взять собственный редактор свойств вместо предопределенного. Например, можно написать редактор свойства width, который будет ограничен каким-либо числом.
Редакторы свойств имеют свою иерархию. Рассмотрим ее.
Базовым классом в иерархии редакторов свойств является TPropertyEditor. Названия классов говорят сами за себя. Например, класс TColorProperty отвечает за свойство цвета компонента, класс TlntegerProperty связан с теми свойствами, которые имеют тип integer и т. д. На листинге 2.15 приведен код, определяющий базовый класс TPropertyEditor.
Листинг 2.15
TPropertyEditor = class
private
FDesigner: TFormDesigner;
FPropList: PInstPropList;
FPropCount: Integer;
constructor Create(ADesigner: TFormDesigner; APropCount: Integer);
function GetPrivateDirectory: string;
procedure SetPropEntry(Index: Integer; AInstance: TComponent;
APropInfo: PPropInfo};
protected
function GetPropInfо: PPropInfo;
function GetFloatValue: Extended;
function GetFloatValueAt(Index: Integer): Extended;
function GetMethodValue: TMethod;
function GetMethodValueAt(Index: Integer): TMethod;
function GetOrdValue: Longint;
function GetOrdValueAt(Index: Integer): Longint;
function GetStrValue: string;
function GetStrValueAt(Index: Integer): string;
procedure Modified;
procedure SetFloatValue(Value: Extended);
procedure SetMethodValue(const Value: TMethod);
procedure SetOrdValue(Value: Longint);
procedure SetStrValue(const Value: string);
public
destructor Destroy; override;
procedure Activate; virtual;
function AllEqual: Boolean; virtual;
procedure Edit; virtual;
function GetAttributes: TPropertyAttributes; virtual;
function GetComponent(Index: Integer): TComponent;
function GetEditLimit: Integer; virtual;
function GetName: string; virtual;
procedure GetProperties(Proc: TGetPropEditProc);virtual;
function GetPropType: PTypelnfo;
function GetValue: string; virtual;
procedure GetValues(Proc: TGetStrProc); virtual;
procedure Initialize; virtual;
procedure SetValue(const Value: string); virtual;
property Designer: TFormDesigner read FDesigner;
property PrivateDirectory: string read GetPrivateDirectory;
property PropCount: Integer read FPropCount;
property Value: string read GetValue write SetValue;
end;
Методы данного класса, которые приведены ниже, можно переопределять для изменения поведения редактора свойств.
Метод Activate вызывается, когда данное свойство выбирается в окне инспектора объектов.
Метод AllEqual вызывается при выборе на форме более одного компонента.
Метод Edit вызывается при нажатии кнопки (...) или при двойном щелчке мыши на свойстве. Данный метод может вызвать диалоговое окно для редактирования свойства, например, как это происходит при редактировании свойства Font.
Метод GetAttributes возвращает множество значений типа TProperyAttributes, определяющих, каким образом свойство будет отображаться в окне инспектора объектов.
Метод Getcomponent предназначен для определения компонента по его номеру (параметр index), в случае, когда на форме выбрано несколько компонентов одновременно.
Метод GetEditLimit возвращает максимальное число символов в строке, которые пользователь может ввести при редактировании свойства.
Метод GetName предназначен для получения имени свойства. Данный метод целесообразно изменять только в том случае, когда имя свойства отличается от имени, отображаемом в окне инспектора объектов.
Метод GetPropType применяется для определения указателя на информацию о типе редактируемого свойства.
Метод Getvalue возвращает значение свойства в виде строки.
Метод initialize вызывается при создании (инициализации) редактора свойств.
Метод setvalue применяется для установки значения свойства.
В большинстве случаев, при создании нового редактора свойств нет необходимости использовать в качестве класса-предка базовый класс TPropertyEditor. Часто разработчик просто переделывает уже существующий для данного свойства редактор, переопределяя некоторые его методы.
Рассмотрим в качестве примера переработанное свойство Hint, которое применяется для показа всплывающей подсказки при задержании указателя мыши над компонентом. В стандартном случае такая подсказка имеет всего одну строку. Попробуем сделать свойство Hint многострочным. Нижеприведенный листинг 2.16 показывает, как создать новый редактор свойств THintProperty. В качестве класса-предка для данного редактора свойств выберем редактор TStringProperty.
Листинг 2.16
THintProperty = class(TStringProperty)
public
function GetAttributes: TPropertyAttributes; override;
function GetValue : String; override;
procedure Edit; override;
end;
function THintProperty.GetAttributes: TPropertyAttributes;
begin
Result := inherited GetAttributes + [paDialog, paReadOnly];
end;
function THintProperty.GetValue : string;
var i : Byte;
begin
result:=inherited GetValue;
for i:=l to Byte(resultt0]) do
if result[i]<#32 then result[i]: = '>';
end;
procedure THintProperty.Edit; var
HintEditDlg : TStrEditDlg; s : string;
begin
HintEditDlg:=TStrEditDlg.Create(Application);
with HintEditDlg do
try
Memo.MaxLength := 254;
s:=GetStrValue+#0;
Memo.Lines.SetText(@s[1]);
UpdateStatus(nil);
ActiveControl := Memo;
If ShowModal = mrOk then begin
s:=StrPas(Memo.Lines.GetText);
if s[0]>#2 then Dec(Byte(s[0]),2);
SetStrValue(s);
end; finally
Free;
end;
end;
Рассмотрим методы нового класса:
- функция GetAttributes добавляет к унаследованному множеству атрибуты paDialog (при этом появляется кнопка (...) в окне инспектора объектов) и paReadOnly (который применяется для того, чтобы редактирование данного свойства было возможно только через диалог);
- функция Getvalue заменяет символы перевода каретки (#10) -и переход на новую строку (#13) на символ больше (>).
Наконец, процедура Edit применяется для вызова диалога для ввода строк всплывающей подсказки.
Для регистрации нового редактора нужно в интерфейсной части модуля поместить объявление процедуры Register. После чего В части implementation модуля написать саму процедуру регистрации (листинг 2.17).
Листинг 2.17.
procedure Register;
begin
RegisterPropertyEditor (Typelnfо(String), TControl, 'Hint',
THintProperty);
end;
Данная процедура позволяет привязать один и тот же редактор к свойствам, в зависимости от их названия или типа. Это определяется параметрами, которые передаются процедуре RegisterPropertyEditor. Первый параметр определяет тип свойства (в нашем примере - это string), второй параметр - класс компонента. Третий параметр позволяет задать имя свойства. Четвертый параметр указывает имя редактора свойства.
Для того чтобы установить новый редактор свойств в Delphi, нужно выполнить следующие шаги:
1. Выбрать пункт меню
Options/Install Components (Настройки/Установка компонентов).
2. Нажать кнопку Add.
3. Указать имя подключаемого модуля.
После того как произойдет компиляция библиотеки, можно создать новую форму и разместить на ней какой-либо компонент. После чего установим у этого компонента свойство showHint в true и нажмем кнопку (...) в свойстве Hint. Вы видите на экране новый многострочный редактор для свойства
Hint.
Содержание раздела