第八章 對象鏈接與嵌入
對象鏈接和嵌入(Object Linking and Embeding)是一組服務(wù)功能,它提供了一種用源于不同應(yīng)用程序的信息創(chuàng)建復(fù)合文檔的強(qiáng)有力方法。 對象可以是幾乎所有的信息類型,如文字、位圖、矢量圖形,甚至于聲音注解和錄像剪輯等。
Windows附件組中的書寫器是應(yīng)用OLE的實(shí)例,使用單擊“對象 | 插入”菜單項, 書寫器彈出插入對話框,對話框中列出了多個OLE服務(wù)器程序,如公式編輯工具,繪圖工具,報表生成工具。用戶雙擊鼠標(biāo)左鍵,可激活一個OLE服務(wù)器。在OLE服務(wù)器中可編輯OLE對象,當(dāng)用戶返回到書寫器中時,在書寫器文檔中將出現(xiàn)OLE對象。
Delphi支持OLE技術(shù),Delphi1.0可以創(chuàng)建OLE應(yīng)用程序,Delphi2.0可創(chuàng)建OLE自動化服務(wù)器和控制器程序。本章通過例程介紹對象鏈接與嵌入的基本概念,Delphi創(chuàng)建OLE對象的方法,OLE自動化的概念以及如何開發(fā)OLE自動化服務(wù)器和控制器。
8.1 OLE簡介
8.1.1 OLE1.0和OLE2.0
迄今為止,有兩種版本的OLE:OLE1.0和OLE2.0。當(dāng)用戶在OLE1.0 服務(wù)器中激活OLE對象,服務(wù)器程序在前臺打開自己的窗體,并獲得焦點(diǎn)。OLE窗體失去焦點(diǎn),存在于單獨(dú)的窗體之中。
OLE2.0服務(wù)器采用“本地”(in place)激活方式。本地激活意味著服務(wù)器菜單與應(yīng)用程序菜單要進(jìn)行融合,服務(wù)器的狀態(tài)條更換應(yīng)用程序狀態(tài)條,服務(wù)器的工具條更換應(yīng)用程序工具條。OLE對象在應(yīng)用程序窗體中進(jìn)行編輯,但所有過程均由服務(wù)器處理。
創(chuàng)建OLE對象的服務(wù)器決定了OLE的激活方式。如果一個OLE1.0的對象在OLE2.0 編譯的應(yīng)用程序中打開,它將采用OLE1.0的方式。
8.1.2 鏈接與嵌入
鏈接對象的數(shù)據(jù)保存在OLE服務(wù)器創(chuàng)建的文件中,嵌入對象的數(shù)據(jù)保存在OLE應(yīng)用程序中。
鏈接對象必須以文件形式保存,只有對OLE服務(wù)器已經(jīng)創(chuàng)建好的OLE對象, 才能進(jìn)行OLE鏈接,鏈接的OLE對象文件可被OLE應(yīng)用程序或其它程序進(jìn)行修改,OLE 服務(wù)器和其它OLE應(yīng)用程序也可以訪問和修改OLE對象。對象數(shù)據(jù)保存在某一處,但可以被多個應(yīng)用程序訪問。
Delphi應(yīng)用程序可以得到OLE對象文件中的最新數(shù)據(jù)。當(dāng)OLE 對象數(shù)據(jù)被應(yīng)用程序修改時,這些變化將在所有包含該對象的其它應(yīng)用程序中體現(xiàn)。
嵌入對象保存在OLE應(yīng)用程序中,其它應(yīng)用程序不能訪問該對象。只有在OLE應(yīng)用程序中激活OLE對象才能對其進(jìn)行編輯。嵌入的OLE對象不需要保存在文件中,所有數(shù)據(jù)都在應(yīng)用程序中,這就確保了OLE數(shù)據(jù)不會被偶然地刪除或修改。不足之處是應(yīng)用程序的規(guī)模因為保存了OLE數(shù)據(jù)而增大了 。
如果用戶想保存對嵌入對象的修改,可以把OLE數(shù)據(jù)存入文件中,本章第3 節(jié)將詳細(xì)討論這個問題。
表8.1 使用鏈接或嵌入的原則。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
何時使用鏈接 何時使用嵌入
───────────────────────────────
想要對源對象進(jìn)行修改及將 對源對象進(jìn)行修改,并將這
這些修改反映到其他與源對 些修改反映在一個特定的應(yīng)
象鏈接的應(yīng)用程序或文本中 用程序或文本中
源對象可能被多個OLE應(yīng) 源對象不可能被一個OLE應(yīng)
用程序應(yīng)用程序頻繁修改 用程序頻繁修改
源對象的文件不會被頻繁移 源對象的文件可能被頻繁移
動,且不會被刪除 動,且不會被刪除
對象很大,一般通過網(wǎng)絡(luò)或 對象很小,或?qū)ο蠛艽髤s無法
電子郵件進(jìn)行分配 通過網(wǎng)絡(luò)或電子郵件進(jìn)行分配
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
8.1.3 設(shè)計狀態(tài)OLE對象的創(chuàng)建
在Delphi中,可分別在設(shè)計狀態(tài)或運(yùn)行狀態(tài)創(chuàng)建OLE對象,表8.2說明了兩種狀態(tài)創(chuàng)建對象的差別。
表8.2 設(shè)計、運(yùn)行狀態(tài)OLE對象的創(chuàng)建
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
設(shè)計狀態(tài)OLE對象的創(chuàng)建 運(yùn)行狀態(tài)OLE對象的創(chuàng)建
──────────────────────────────────────
對象保存在運(yùn)行文件中,增加了所需 對象保存在一個文件中或只在運(yùn)行時
編譯的程序的規(guī)!〔庞,減小了編譯程序的規(guī)模
開發(fā)者需在設(shè)計時訪問OLE服務(wù)器 開發(fā)者不需要在設(shè)計時訪問OLE服務(wù)器
運(yùn)行時OLE對象已經(jīng)創(chuàng)建,減小了 運(yùn)行時OLE對象已經(jīng)創(chuàng)建,增加了運(yùn)行
運(yùn)行時間 時間
OLE對象在設(shè)計運(yùn)行時間可行性編輯 OLE對象只能在運(yùn)行時編輯
應(yīng)用程序的OLE對象數(shù)目在設(shè)計時已 應(yīng)用程序可以在運(yùn)行時創(chuàng)建新的OLE對
經(jīng)確立 象
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
在設(shè)計狀態(tài),OLE服務(wù)器不能被本地激活,只能在自己的窗體內(nèi)激活。但在運(yùn)行狀態(tài),
只要OLE服務(wù)器支持本地激活,就可以使用這種方式。
8.1.4 OLE類、文件、項目
OLE類決定創(chuàng)建OLE對象的服務(wù)器。有些應(yīng)用程序需要創(chuàng)建多種類型的OLE對象,例如應(yīng)用程序同時鏈接或嵌入公式、圖片等。OLE類也決定OLE對象所包含的數(shù)據(jù)類型,鏈接或嵌入對象均要定義OLE類。
OLE文件是包含OLE對象數(shù)據(jù)的源文件。鏈接對象必須使用對象文件,因為鏈接對象在文件中保存。如果應(yīng)用程序從已存在的源文件中創(chuàng)建嵌入對象,也要使用OLE文件。例如,如果鏈接到QuattiPro筆記本的OLE對象TUTOR.WBI存儲在D:\DFFICE\QPW目錄下,則OLE文件就是D:\DFFICE\QPW\TUTOR.WBI。值得注意的是OLE文件只能為鏈接對象所定義,而對于嵌入對象,只需定義OLE類。
OLE項目是代表鏈接或嵌入數(shù)據(jù)的OLE文件中的一部分。當(dāng)應(yīng)用程序希望OLE對象包含比OLE文件小的數(shù)據(jù)塊時,則必須使用OLE項目。
例如,在QuattiPro筆記本中,OLE對象鏈接了GasCosts的B4 到B5 范圍的網(wǎng)格,OLE項目是$GasCosts;$B$4.$B$5。
8.2 設(shè)計狀態(tài)OLE對象的創(chuàng)建
Dephi可以在設(shè)計狀態(tài)和運(yùn)行狀態(tài)中創(chuàng)建OLE對象。本節(jié)介紹設(shè)計狀態(tài)OLE對象的創(chuàng)建。
8.2.1 TOLEContainer部件
要創(chuàng)建OLE對象,需在窗體中加入OLE包容器部件。 應(yīng)用程序部件包含鏈接或嵌入的對象。用該部件可顯示在OLE服務(wù)器編輯的數(shù)據(jù)。部件的ObjClass,ObjDoc,ObjItem 屬性分別定義OLE類、文件、項目。要定義OLE對象是否本地激活,使用InPlaceActive 屬性。如果OLE對象可以本地激活,OLE服務(wù)器菜單將與OLE應(yīng)用程序的菜單進(jìn)行融合,GroupIndex屬性的值將決定菜單融合情況。
8.2.2 OLE對象創(chuàng)建的步驟:
1.在窗體中增加OLE包容器部件;
2.在Object inspector中單擊ObjClass或ObjDoc屬性的省略按鈕,將出現(xiàn)插入對象對話框;
3.如果要插入的OLE 對象已存儲在文件中,選擇“Creat From File”,而后定義該對象的文件名和路徑名。如果是鏈接對象,則選擇鏈接檢查框。 如果是嵌入對象,選擇“Creat new”,并在對象類型列表框中選擇OLE對象;
4.選擇OK按鈕;
如果是創(chuàng)建新對象,OLE服務(wù)器將激活,則可對OLE對象進(jìn)行編輯,完成編輯后關(guān)閉OLE服務(wù)器。典型的例子是單擊服務(wù)器中的“File”或“File|Update”菜單。
5.此時ObjClass屬性中包含了相應(yīng)的值,如果OLE對象從已存在的文件中創(chuàng)建或插入一
個鏈接對象,ObjDoc屬性包含了OLE文件。
在設(shè)計對象狀態(tài)時也可以粘貼OLE對象,其步驟如下:
1.激活服務(wù)器應(yīng)用程序,選擇OLE包容器部件;
2.在服務(wù)器中,將數(shù)據(jù)或?qū)ο罂截惖郊羟邪?
3.進(jìn)入Delphi集成開發(fā)環(huán)境,選擇OLE包容器部件;
4.在 Object inspector窗體中選擇ObjItem屬性的省略(…)按鈕;
5.在列表中選擇OLE對象;
6.選擇“Paste"創(chuàng)建一個嵌入對象或選擇"Pastelink"創(chuàng)建鏈接對象;
7.選擇OK。
OLE包容器部件在此時初始化。如果粘貼一個嵌入對象,ObjClass屬性將包含適當(dāng)?shù)闹。如果粘貼一鏈接對象,ObjClass,ObjDoc,ObjItem屬性將全部定義。OLE 應(yīng)用程序部件包含代表OLE對象的圖片。
如果OLE服務(wù)器程序支持OLE對象的拖放功能,則在設(shè)計狀態(tài)從服務(wù)器中拖動對象至應(yīng)用程序,應(yīng)用程序?qū)?chuàng)建鏈接對象,具體步驟:
1.激活服務(wù)器,并Delphi集成開放環(huán)境中選擇要鏈接的對象;
2.按隹鼠標(biāo)左鍵拖動OLE對象至設(shè)計狀態(tài)的窗體;
3.松開鼠鍵釋放OLE對象。
窗體將創(chuàng)建OLE應(yīng)用程序并進(jìn)行初始化。
8.3 OLE應(yīng)用程序的開發(fā)
Delphi可以在設(shè)計狀態(tài)和運(yùn)行狀態(tài)創(chuàng)建OLE對象,上一節(jié)介紹的是在設(shè)計狀態(tài)如何創(chuàng)建OLE對象,這一節(jié)將通過例程介紹如何在運(yùn)行狀態(tài)創(chuàng)建OLE對象、粘貼對象、拖動對象,以及OLE 對象的文件操作。我們開發(fā)的 OLE.dpr是一個OLE應(yīng)用程序的實(shí)例
8.3.1 OLE應(yīng)用程序界面開發(fā)
OLE.dpr采用了多文檔界面,父窗體有菜單,工具條,狀態(tài)條,子窗體有一個OLE包容器部件,下面分別加以介紹。
8.3.1.1 OLE應(yīng)用程序的菜單
OLE應(yīng)用程序的菜單與其它應(yīng)用程序的主菜單大體一致,如果應(yīng)用程序中有支持本地激活的OLE 2.0對象,則要進(jìn)行菜單融合。查閱OLE 服務(wù)器的資料可知道服務(wù)器是否支持本地激活。
OLE應(yīng)用程序菜單的GroupIndex屬性決定融合菜單的位置,即融合菜單是更換主菜單,還是插入至應(yīng)用程序的主菜單中。
OLE服務(wù)器,將融合三組菜單:Edit,View,Help,每組菜單分配了唯一的組索引值。在OLE應(yīng)用程序中任何索引值為1,3,5的菜單組在菜單融合時被OLE服務(wù)器中具有相應(yīng)索引值的菜 單更換。在本例程中,編輯菜單項在菜單融合時被服務(wù)器的"Edit"替換。如圖8.3。 要想保存應(yīng)用程序中的菜單,分配有異于1,3,5的索引值。
表8.3 融合后的菜單
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
菜單 索引值 功能描述 來源(OLE激活時)
────────────────────────────────
文件 0 使用文件和退出程序 OLE應(yīng)用程序
Edit 1 編輯OLE對象 OLE服務(wù)器
對象 2 操作未激活的OLE對象 OLE應(yīng)用程序
View 3 修改OLE對象的觀測方式 OLE服務(wù)器
窗體 4 操縱窗體 OLE應(yīng)用程序
Help 5 訪問服務(wù)器在線幫助 OLE服務(wù)器
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
8.3.1.2 OLE工具條和狀態(tài)條
當(dāng)OLE對象被本地激活時,OLE服務(wù)器將試圖用自己的工具條和狀態(tài)條替換OLE應(yīng)用程序的。如果應(yīng)用程序想要本地激活, 就應(yīng)該在應(yīng)用程序中編寫相應(yīng)的代碼讓服務(wù)器使用工具條和狀態(tài)條。要做到這點(diǎn),必須:
● 設(shè)置工具條和狀態(tài)條
● 在應(yīng)用程序中加入狀態(tài)條
通過修改面板部件的屬性創(chuàng)建工具條和狀態(tài)條。
當(dāng)OLE對象被本地激活時,面板或其他對齊控制將與OLE服務(wù)器程序進(jìn)行協(xié)調(diào)。 這意味
OLE服務(wù)器可以替換OLE應(yīng)用程序窗體中任何對齊控制,但鎖定的控制不能被替換。例如,
如果面板的align屬性是alTop,alleft,alBottom,alIngh時,控制未鎖定,OLE服務(wù)器可以替換。要使應(yīng)用程序的工具條、狀態(tài)條不被替換,可將locked屬性設(shè)置成真值。
當(dāng)OLE 對象被激活,OLE 服務(wù)器在狀態(tài)條中顯示有關(guān)信息時,OLE 應(yīng)用程序部件的OnStatusLineEvent事件發(fā)生,一個文本字符會將從OLE服務(wù)器傳至該事件句柄。 OnStatusLineEvent事件句柄的MSG參數(shù)接受文本字符。
以下代碼用以狀態(tài)條接收OLE服務(wù)器的信息:
procedure TOLEObjectForm.OleContainerStatusLineEvent(Sender: TObject;
Msg: String);
begin
OLEFrameForm.StatusBarPanel.Caption := Msg
end;
8.3.2 插入OLE對象
運(yùn)行狀態(tài)時進(jìn)行對象鏈接與插入也要用到插入對話框,Delphi中沒有插入對話框部件,但可調(diào)用InsertOLEObjectDlg 函數(shù)來顯示對話框。
8.3.2.1 InsertOLEObjectDlg函數(shù)聲明如下:
function InsertOleObjectDlg(Form: TForm; HelpContext: THelpContext;
var PInitInfo: Pointer): Boolean;
其中參數(shù)Form是擁有插入對話框的窗體,一般將擁有OLE包容器部件的窗體名字傳給Form.
參數(shù)Helplontext為插入對象對話框定義在線幫助,如果應(yīng)用程序沒有在線幫助, HelpContext的值為零,對話框中將不出現(xiàn)幫助按鈕。
參數(shù)PInitInfo是一個無類型指針,該指針指向一個包含初始化OLE 部件信息的內(nèi)部數(shù)據(jù)結(jié)構(gòu)。InsertOLEObjectDlg修改這個指針以指向一個有效的數(shù)據(jù)結(jié)構(gòu),該結(jié)構(gòu)包含了對話框列表中被選擇的OLE 對象初始化信息。當(dāng)該指針被使用后,應(yīng)調(diào)用ReleaseOLEInitInfo過程釋放初始化信息所占用的內(nèi)存。
當(dāng)用戶選擇OK 按鈕關(guān)閉插入對象對話框,InsertOLEObjectDlg 返回真值,并把 PInitInfo指向包含OLE對象的初始化信息的數(shù)據(jù)結(jié)構(gòu)。
相關(guān)推薦:2010年9月計算機(jī)等級考試試題及答案解析專題北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |