unit as1
{
一、 概 述
1、 前言
Delphi的IDE擴展是一般程式員很少涉足的領域,不管是網上還是書店里,這方面的資料都是鮮有所見。Delphi7自帶的幫助檔案是我們最容易找到的資料,為了方便CnPack開發組成員以及對IDE擴展感興趣的朋友對這一領域有更多的認識,我花了點時間把Delphi7中IDE擴展部分的幫助翻譯成中文發布,希望對大家有所幫助。
2、 術語串列
以下是本檔案翻譯時使用的術語對照表:
插件(Add-in),以設計期包或DLL形式被設計期的IDE呼叫的擴展工具。
專家(Wizard),實作了IOTAWizard介面的IDE插件工具。
倉庫專家(Repository Wizard),用來創建新的單元、表單或工程的專家。
包(Package),Delphi中使用的特殊的元件。
設計期包(Design-time Package),被編譯為允許IDE在設計期裝載的包。
運行期包(Runtime Package),被編譯為允許DLL在運行期呼叫的包。
介面(Interface),Delphi中使用的COM風格的介面。
通知器(Notifier),由用戶實作特定介面并由IDE在特定事件中呼叫的用戶物件。
創建器(Creator),由用戶實作特定介面的用于創建新的單元、表單或工程的用戶物件。
工程(Project),Delphi中的Project。
單元(Unit),Delphi中的Unit。
模塊(Module),對應著一組在IDE中打開的邏輯上關聯的檔案集,可以是一個單元、包含表單的單元、工程檔案等物件。
編輯器(Editor),IDE中用來設計和編輯模塊的物件。
其它如IDE、DLL、Action、Tools API這樣的術語則沿用英文,不作翻譯。
二、 擴展Delphi的IDE
1、 IDE擴展
通過使用Open Tools API(通常縮寫為Tools API),你可以用你自己的選單項、工具列按鈕、動態的表單創建專家以及更多的東西來擴展和定制IDE。Tools API是一套超過100個用于關聯以及控制IDE的介面,包括主選單、工具列、主Action串列以及影像串列、源代碼編輯器內部緩沖區、鍵盤宏及鍵盤系結、表單設計器中的表單及其上面的組件、除錯器和正在被除錯的行程、代碼完成、訊息視圖,以及任務串列。
使用Tools API是一件容易的事情,只要寫幾個實作了特定介面的類,并呼叫由另一些介面提供的服務即可。你的Tools API代碼必須編譯并作為一個設計期包或DLL裝載到設計期的IDE中。這樣,撰寫一個Tools API擴展有些類似撰寫一個屬性或組件編輯器。在閱讀這份材料之前,請確信你已經對基本的 用包來作業 和 注冊組件 比較熟悉了。
下面這些主題描述了怎樣使用Tools API:
Tools API概述
撰寫一個專家類
獲得Tools API服務
對檔案和編輯器的操作
創建表單和工程
IDE的專家事件通知
2、 Tools API概述
所有的Tools API宣告都在這一個單元里:ToolsAPI。要使用Tools API,你通常要參考designide這個包,這意味著你需要將你的Tools API插件作為設計期包或使用了運行期包的DLL來構建。關于包和庫的問題,參閱 安裝專家包。
撰寫一個Tools API擴展的主要介面是IOTAWizard,故大部分IDE插件都稱為專家(Wizards)。在絕大多數情況下,C++Builder和Delphi的專家可以通用。你可以在Delphi中撰寫和編譯一個專家,然后在C++Builder中使用,反之亦然。這種共用的作業最好在同一個IDE版本號之間,但同樣也可能撰寫一個專家并且他們能在兩種產品的將來版本里都可使用。要使用Tools API,你可以撰寫一個專家類并實作在ToolsAPI單元中定義的一個或多個介面。專家可以利用在Tools API中提供的服務,每個服務都是一個提供一組相關函式的介面,介面的實作部分被隱藏在IDE里面。Tools API只公布了介面,你可以利用它們來撰寫你的專家,而不必關心那些介面的實作細節。這些不同的介面提供了對源代碼編輯器、表單設計器、除錯器等的訪問。怎樣在你的專家中使用這些介面包含的服務,參閱 獲得Tools API服務。
這些服務和其它的介面被劃分為兩個基本的分類,你可以按照用為型別名稱的前綴來區分它們:
NTA(native tools API)本地的Tools API允許直接訪問實際的IDE物件,如IDE的TMainMenu物件。當使用這些介面時,專家必須參考Borland的包,這意味著專家將限制于特定的IDE版本中。這類專家可以放在一個設計期包或使用了運行期包的DLL中。
OTA(open tools API)開放的Tools API不需要參考包,只能通過介面訪問IDE。在理論上,如果你能支持Delphi的函式呼叫約定以及類似于AnsiString這樣的Delphi型別,則你能夠使用任何支持COM風格介面的語言來撰寫專家,但是幾乎所有的Tools API功能都只能通過OTA介面獲得。如果一個專家只使用OTA介面,則它有可能寫成一個不依賴于特定IDE版本的DLL。
Tools API有兩種型別的介面:一種是作為程式員的你必須實作的介面,另一種是IDE已經實作了的介面。大部分的介面屬于后者的分類:介面定義了IDE的功能而隱藏了真正的實作。你必須實作的介面可分為以下三類:專家(Wizards)、通知器(Notifiers)以及創建器(Creators):
在前面的主題中提到,一個專家類要實作IOTAWizard介面以及可能的派生介面。
通知器是Tools API中另一種型別的介面。IDE使用通知器在某些你關注的事情發生時回呼你的專家。你可以撰寫一個類來實作通知器介面,并使用Tools API注冊該通知器,當用戶打開一個檔案、編譯源代碼、修改表單、開始除錯會話及其它情況時,IDE會回呼你的通知器物件。通知器的介紹見 IDE的專家事件通知。
創建器是你必須實作的另一種型別的介面。Tools API使用創建器來創建新的單元、工程或檔案,或用來打開一個已存在的檔案。關于創建器的內容請查看 創建表單和工程 部分。
其它的重要介面是模塊(Module)和編輯器(Editor)。一個模塊介面代表了一個打開的單元,包含一個或多個檔案。一個編輯器介面代表一個打開的檔案。不同型別的編輯器介面提供給你對IDE中不同方面的訪問:源代碼編輯器(Source Editor)對應著源代碼檔案,表單設計器(Form Designer)對應著表單檔案,另外還有工程資源(Project Resource)對應資源檔案。關于模塊和編輯器的內容請查看 對檔案和編輯器的操作 部分。
3、 撰寫一個專家類
一共有四種型別的專家,專家的型別依賴于專家類所實作的介面。下面的表格描述了這四種型別的專家:
四種型別的專家
介面 描述
IOTAFormWizard 用來創建新的單元、表單或其它檔案
IOTAMenuWizard 自動增加到Help選單中
IOTAProjectWizard 用來創建一個新的應用程式工程。
IOTAWizard 不適合放在其它分類中的各種專家
這四種型別的專家區別僅在于用戶怎樣呼叫專家:
選單型專家(Menu Wizard)將增加到IDE的Help選單中。當用戶選擇該選單項時,IDE將呼叫該專家的Execute方法。普通的專家表現得更為靈活,故選單型專家通常只在原型和除錯時使用。
表單和工程專家又叫倉庫專家,因為他們被放在物件倉庫(Object Repository)中。用戶在新建專案對話框中呼叫這些專家,用戶也能在物件倉庫(通過選擇Tools|Repository選單項)中看到這些專家。用戶可以為一個表單專家選中“New Form”檢查框,這將通知IDE當用戶從主選單中選擇“File|New Form”時,將自動呼叫這個表單專家。用戶同樣可以選擇“Main Form”檢查框,這將通知IDE使用這個表單專家來生成新應用程式默認的主表單。用戶還可以為一個工程專家選擇“New Project”檢查框,當用戶選擇“File|New Application”時,IDE將呼叫選擇的工程專家。
第四種型別的專家用于不能放到其它分類時的情況。一個普通的專家自身不能做任何事,取而代之的是,你必須自己定義專家怎樣被呼叫。
Tools API并不對專家作任何強制性的約束,比如并不是必須要有個工程專家才能創建工程。你可以很容易地寫一個工程專家來創建一個表單以及寫一個表單專家來創建工程(如果你確實想要這樣做的話)。
下面的主題詳細說明了怎樣實作和安裝專家:
實作專家介面
安裝專家包
4、 實作專家介面
每一個專家類至少必須實作IOTAWizard介面,同樣,也要求實作它的父介面:IOTANotifier和IInterface。 表單和工程專家必須實作他們的所有父介面,即:IOTARepositoryWizard、IOTAWizard、IOTANotifier和IInterface。
你對IInterfac的實作必須遵循Delphi介面的一般規則,這同樣也是COM介面的規則。即,QueryInterface執行型別匹配,_AddRef和_Release管理參考計數。你可能會想使用一個公共的基類來簡化專家和通知器類的撰寫。出于這個考慮,ToolsAPI單元定義了一個類,TNotifierObject,它實作了IOTANotifier介面并使用了空方法體。
盡管專家繼承自IOTANotifier,而且因此必須實作它定義的所有函式,但IDE通常并不使用這些函式,所以你的實作可以為空(它們在TNotifierObject中實作)。因此,當你撰寫你的專家類時,你只需要宣告并實作那些在專家介面中引入的方法就行了,默認使用TNotifierObject對IOTANotifier的實作。
5、 安裝專家包
類似于其它的設計期包,一個專家包(Wizard Package)也必須實作一個Register函式。(關于Register函式的詳細說明見 注冊組件。)在Register函式中,通過呼叫RegisterPackageWizard,你可以注冊任意多的專家,并傳遞一個專家物件作為唯一的引數,如下所示:
procedure Register;
begin
RegisterPackageWizard(MyWizard.Create);
RegisterPackageWizard(MyOtherWizard.Create);
end;
同樣,你也可以注冊屬性編輯器、組件等等,作為同一個包的一部分。
請記住,設計期包是Delphi主程式的一部分,這意味著所有表單的名稱在整個應用程式和所有其它的設計期包中都應該是唯一的。這是使用包方式主要的一個缺點:你并不知道其它人會怎樣命名他們的表單。
在開發中,安裝包專家類似于其它的設計期包:在包管理器中點擊Install按鈕。IDE將編譯和連接該包并嘗試裝載它。如果裝載包成功,IDE會顯示一個對話框通知你。
(譯注:如果是DLL型別的專家,需要在注冊表中注冊,例如在Delphi7中注冊一個名稱MyWizard的專家,可以在注冊表HKEY_CURRENT_USER\Software\Borland\Delphi\7.0\Experts中增加一個字串項:MyWizard,值為DLL的完整路徑檔案名)
6、 獲得Tools API服務
為了做一些有用的作業,專家需要訪問IDE:它的編輯器、表單、選單等等,這些是服務介面的任務。Tools API包括很多的服務,例如用Action服務執行檔案Action操作,用編輯器服務訪問源代碼編輯器,用除錯器服務訪問除錯器,等等。下面的表格總結了所有的服務介面:
Tools API服務介面
介面 描述
INTAServices 提供對本地IDE物件的訪問:主選單、Action串列、影像串列和工具列。
IOTAActionServices 實作基本的檔案操作:打開、關閉、保存和重裝載檔案。
IOTACodeCompletionServices 提供對代碼完成的訪問,允許專家安裝自定義的代碼完成管理器。
IOTADebuggerServices 提供對除錯器的訪問。
IOTAEditorServices 提供對源代碼編輯器及其內部緩沖區的訪問。
IOTAKeyBindingServices 允許專家注冊自定義的鍵盤系結。
IOTAKeyboardServices 提供對鍵盤宏和系結的訪問。
IOTAKeyboardDiagnostics 切換按鍵除錯。
IOTAMessageServices 提供對訊息視圖(Message View)的訪問。
IOTAModuleServices 提供對打開的檔案的訪問。
IOTAPackageServices 查詢已安裝的包及他們的組件的名稱。
IOTAServices 其它的服務。
IOTAToDoServices 提供對To-Do串列的訪問,允許專家安裝自己的To-Do串列管理器。
IOTAToolsFilter 注冊工具過濾通知器(Tools Filter Notifiers)。
IOTAWizardServices 注冊及洗掉專家。
要使用服務介面,使用在SysUtils單元中定義的全域的Supports函式將BorlandIDEServices變數轉換為目標服務介面。例如:
}
procedure set_keystroke_debugging(debugging: Boolean);
var
diag:
IOTAKeyboardDiagnostics
begin
if Supports(BorlandIDEServices, IOTAKeyboardDiagnostics, diag) then
diag.KeyTracing := debugging;
end;
{
如果你的專家頻繁地使用一個特定的服務,你可以將這個服務的指標作為一個資料成員保存在你的專家類中。
下面的主題討論了使用Tools API服務介面來作業時一些特定的事項:
使用本地IDE物件
除錯專家
介面版本號
7、 使用本地IDE物件
專家可以完全地訪問IDE的主選單、工具列、Action串列和影像串列。(注:IDE的很多彈出選單不能直接通過Tools API來訪問。)
對IDE本地物件的操作以INTAServices介面為起點,你可以使用這個介面來增加影像到影像串列,增加Action到Action串列,添加選單項到主選單,以及在工具列上添加按鈕。你也可以關聯Action到選單項和工具列按鈕。當專家釋放的時候,它必須清除那些由它自己創建的物件,但是不能洗掉它增加到影像串列中的影像,因為洗掉影像可能會打亂所有在該專家之后增加的其它影像的索引號。
下面的主題闡述了如何執行這些操作:
增加影像到影像串列
增加Action到Action串列
洗掉工具列按鈕
專家操作的是IDE中真實的TMainMenu、TActionList、TImageList和TToolBar物件,故你可以象在撰寫其它應用程式那樣寫代碼。這同樣意味著你有很大的機會讓IDE崩潰或者禁用掉一些重要的功能,例如洗掉檔案選單。除錯專家 討論了當你發現類似這樣的問題時,怎樣除錯你的專家的方法。
8、 增加影像到影像串列
假如你打算增加一個選單項來呼叫你的專家,你同樣也會允許用戶增加一個工具列按鈕來呼叫這個專家。第一個步驟是增加一個影像到IDE的影像串列,然后你增加的影像的索引號就可以在Action中使用,隨后也就可在選單項和工具列中使用。使用影像編輯器(Image Editor)創建一個包含16X16位圖資源的資源檔案,然后在你的專家構造器中加上下面的代碼:
}
constructor MyWizard.Create;
var
Services: INTAServices;
Bmp: TBitmap;
ImageIndex: Integer;
begin
inherited;
Supports(BorlandIDEServices, INTAServices, Services);
{ Add an image to the image list. }
Bmp := TBitmap.Create;
Bmp.LoadFromResourceName(HInstance, 'Bitmap1');
ImageIndex := Services.AddMasked(Bmp, Bmp.TransparentColor,
'Tempest Software.intro wizard image');
Bmp.Free;
end;
{
請確認使用你在資源檔案中指定的名稱或ID來裝載位圖。你必須選擇一個顏色來作為影像的背景顏色。如果你不想要背景顏色,可以選擇一個在位圖中不存在的顏色。
9、 增加Action到Action串列
在 增加影像到影像串列 中獲得的影像索引號可以用來創建Action,如下所示。專家使用OnExecute和OnUpdate事件。在專家中常用的方法是在OnUpdate事件中啟用或禁用Action,請確認OnUpdate事件能很快的回傳,否則用戶將會發現在裝載你的專家后,IDE變得慢如蝸牛。Action的OnExecute事件類似于專家的Execute方法。如果你使用選單項來呼叫一個表單或工程專家,你甚至可能希望讓OnExecute直接呼叫Execute方法。
}
NewAction := TAction.Create(nil);
NewAction.ActionList := Services.ActionList;
NewAction.Caption := GetMenuText();
NewAction.Hint := 'Display a silly dialog box';
NewAction.ImageIndex := ImageIndex;
NewAction.OnUpdate := action_update;
NewAction.OnExecute := action_execute;
// 選單項可以設定它的Action屬性為新創建的Action。創建一個新的選單項時比較復雜的部分是要知道它應該被插入到哪兒。下面的例子查找View選單,并且創建一個新的選單項作為第一項插入到View選單下。(通常,依賴于絕對位置不是個好主意:你無法知道還有哪些其它的專家會將自己插入到選單中。另外,將來版本的Delphi也可能會調整選單項的順序。一個更好的方法是使用特定的名稱查找指定的選單項。下面的簡單例子僅用來說明概念。)
for I := 0 to Services.MainMenu.Items.Count - 1 do
begin
with Services.MainMenu.Items[I] do
begin
if CompareText(Name, 'ViewsMenu') = 0 then
begin
NewItem := TMenuItem.Create(nil);
NewItem.Action := NewAction;
Insert(0, NewItem);
end;
end;
end;
{
增加Actoin到IDE的Action串列中后,用戶就能在定制工具列時看到這個Action了。用戶可以選擇Action并把它作為按鈕增加到工具列上。這在你的專家被卸載時會帶來一些問題:所有這些指向已經不存在的Action的工具列按鈕和它們的OnClick事件句柄都將被懸空。為了防止訪問違規錯誤,你的專家必須查找所有參考了它的Action的工具列按鈕,并且洗掉它們。
10、 洗掉工具列按鈕
此處沒有直接的函式來從工具列中洗掉按鈕,你必須自己發送CM_CONTROLCHANGE訊息。訊息的第一個引數是要修改的控制元件,第二個引數為零表示從工具列中洗掉(非零是添加)。洗掉工具列按鈕后,專家析構器洗掉Action和選單項,洗掉這些物件將自動把它們從IDE的ActionList和MainMenu中移除。
}
procedure remove_action(Action: TAction; ToolBar: TToolBar);
var
I: Integer;
Btn: TToolButton;
begin
for I := ToolBar.ButtonCount - 1 downto 0 do
begin
Btn := ToolBar.Buttons[I];
if Btn.Action = Action then
begin
{ Remove "Btn" from "ToolBar" }
ToolBar.Perform(CM_CONTROLCHANGE, WPARAM(Btn), 0);
Btn.Free;
end;
end;
end;
destructor MyWizard.Destroy;
var
Services: INTAServices;
Btn: TToolButton;
begin
Supports(BorlandIDEServices, INTAServices, Services);
{ Check all the toolbars, and remove any buttons that use this action. }
remove_action(NewAction, Services.ToolBar[sCustomToolBar]);
remove_action(NewAction, Services.ToolBar[sDesktopToolBar]);
remove_action(NewAction, Services.ToolBar[sStandardToolBar]);
remove_action(NewAction, Services.ToolBar[sDebugToolBar]);
remove_action(NewAction, Services.ToolBar[sViewToolBar]);
remove_action(NewAction, Services.ToolBar[sInternetToolBar]);
NewItem.Free;
NewAction.Free;
end;
{
11、 除錯專家
Tools API為你的專家與IDE之間的互動提供了極大的靈活性。然而,這種靈活性也帶來了風險,很容易因為空指標和訪問違規導致錯誤。
當使用本地
uj5u.com熱心網友回復:
繼續啊,怎么沒有后續了?轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/12689.html
標籤:VCL組件開發及應用
上一篇:element ui 合計行
