四組件屬性編輯器和組件編輯器
通過上面的努力我們的組件似乎已經比較完美了可我們也忽略了一些重要的細節和一些有趣的事情這一篇我們將研究兩個很有用的組件特性
在之前開發組件核心功能時我們曾設置了兩個屬性BeginTime和WakeTime他們都是字符串型的屬性然而他們所要表示的卻是時間類型這樣就很有可能使組件使用者錯誤的編輯屬性並導致轉化字符串到時間時出錯(當然這裡只是為了文章的講解我們故意把它設置為了字符串類型)雖然通過浏覽原代碼你知道我們也做了一些代碼級別的防出錯處理使當輸入錯誤時屬性自動變成::然而這對組件使用者來講仍然顯的很不友好所以我們需要為這兩個屬性定制編輯器我們的編輯器將彈出一個窗口裡面有一個TdateTimePicker用來選擇時間在delphi中有許多這樣的例子例如大家都知道的lines屬性當你單擊它右放的省略號時為自動彈出一個文本編輯器來編輯lines這大大降低了組件使用者范錯誤的可能性
在定制完屬性編輯器以後我們將為組件本身加入一寫有趣的元素——組件編輯器這也是在delphi中經常出現的例如有些組件當你雙擊它時它並不會進入代碼編寫狀態而是彈出它自己的編輯器雖然我們的組件似乎並不需要這種特性但為了演示它我們也將它考慮近來我們給我們的組件編寫了一個版權信息和一個關於對話框當組件使用者雙擊它時彈出關於信息(當然這僅僅是種演示)上面提到的兩種特性由於它們只是會在設計時起作用所以你完全可以在新的組件包中編寫並注冊它們並將這個組件包設置為Designtime Only為了方便起見我們就直接把它們和組件的單元編寫在一起注意以下出現的一些類和方法都需要引用單元DesignEditors(delphi)或DsgnIntf(delphi)與前面說的一樣它們都屬於delphi的open tools api所以如果你沒有這寫單元請按照前文的方法安裝它們
首先來編寫屬性編輯器由於BeginTime和WakeTime是字符串類型所以我們必須從默認的字符串屬性編輯器類TstringProperty繼承並覆蓋它的一寫方法(這裡只介紹幾個重要的方法事實上所有的屬性編輯器都從TpropertyEditor繼承而來然而我們不用直接繼承這個基類)其中一個重要的方法是GetAttributes他將返回一些代表編輯器功能的值這些值將會在代碼的注釋中說明(如果你的屬性編輯器還需要一個下拉列表你還需要另外一個重要的方法GetValues具體請查看delphi幫助)另外為了使屬性編輯器為彈出的對話框我們需要覆蓋Edit方法為了可以以可視化的方式設計對話框我們可以建立一個普通工程在設計好後將窗體的類聲明復制到我們的組件單元並將窗體的dfm文件拷貝到我們的組件包目錄並在代碼中加入編譯器開關{$R *dfm}以下是窗體的類聲明這個窗體沒有任何的代碼需要編寫
TTimeEditFrm = class(TForm)
DateTimePicker: TDateTimePicker;
Button: TButton;
Button: TButton;
private
{ Private declarations }
public
{ Public declarations }
end;
以下是屬性編輯器的代碼
TClockProperty=class(TStringProperty)
public
function GetAttributes:TPropertyAttributes;override;
procedure Edit;override;
end;
實現部分
procedure TClockPropertyEdit;
var
TimeEditFrm:TTimeEditFrm;
begin
TimeEditFrm:=TTimeEditFrmCreate(Application);
try
TimeEditFrmDateTimePickerTime:=StrToTime(GetValue);
if TimeEditFrmShowModal=mrOK then
SetValue(TimeToStr(TimeEditFrmDateTimePickerTime));
//GetValue和SetValue是TStringProperty的基類方法他直接讀取和設置字符串的值
finally
TimeEditFrmFree;
end;
end;
function TClockPropertyGetAttributes: TPropertyAttributes;
begin
result:=[paDialogpaMultiselect];
//paDialog表示屬性編輯器將顯示一個對話框paMulitiselect允許多個組件選擇屬性
//除此之外如果你想讓屬性編輯器顯示下拉列表你還需要paValueList具體請查看幫助
end;
最後我們用RegisterPropertyEditor方法注冊屬性編輯器:
procedure Register;
begin
……
RegisterPropertyEditor(TypeInfo(string)TClockBeginTimeTClockProperty);
RegisterPropertyEditor(TypeInfo(string)TClockWakeTimeTClockProperty);
end;
重新編譯更新組件後我們就可以測試了可以看到組件編輯器工作得很好
接下來我們來實現組件編輯器
組件編輯器需要繼承TcomponentEditor並覆蓋一些重要的方法GetVerbCount返回設計時組件右鍵自定義菜單的數目GetVerb為每一個自定義菜單添加文字ExecuteVerb為每一個菜單項添加事件Edit為組件的缺省操作指定事件(即在設計時雙擊組件)以下是代碼
TClockEditor=class(TComponentEditor)
public
function GetVerbCount:integer;override;
function GetVerb(index:integer):string;override;
procedure ExecuteVerb(index:integer);override;
procedure Edit;override;
end;
實現部分
procedure TClockEditorEdit;
begin
ExecuteVerb(); //默認顯示關於
end;
procedure TClockEditorExecuteVerb(index: integer);
begin
case index of
//第一個顯示名字的菜單什麼都不做顯示
:showmessage(hkbarton@);
end;
end;
function TClockEditorGetVerb(index: integer): string;
begin
case index of
:result:=hkbarton;
:result:=About Clock;
end;
end;
function TClockEditorGetVerbCount: integer;
begin
result:=;//我們顯示兩條菜單一個我的名字一個關於
end;
同樣最後我們注冊組件編輯器
procedure Register;
begin
……
RegisterComponentEditor(TClockTClockEditor);
end;
同樣可以看到組件編輯器的測試情況
文章寫到這裡也該結束了雖然寫了那麼多然而在組件開發中這仍是一小部分內容本文只是拋磚引玉的作用希望對正要進入組件開發的朋友一些啟示為了方便你閱讀本文如果你想要本文所開發的這個組件的全部原文件請和我聯系
Email:hkbarton@sohucom hekphi@hotmailcom QQ
From:http://tw.wingwit.com/Article/program/Delphi/201311/24765.html