OLE自動化技術(shù)在Delphi與MapInfo集成地圖開發(fā)中
摘要:本文論述了利用OLE 自動化技術(shù)和可視化編程工具Delphi 來實現(xiàn)MapInfo 地圖的集
成,并通過例程的方式介紹了集成地圖的方法以及對MapInfo 的消息回調(diào)。從而實現(xiàn)了
MapInfo 集成到Delphi 應(yīng)用系統(tǒng)中,達(dá)到高效開發(fā)應(yīng)用型GIS(地理信息系統(tǒng))軟件的目的。
關(guān)鍵詞: 地理信息系統(tǒng);OLE;MapInfo;Delphi;回調(diào)
The Application Of OLE Automation Technology In Map-integration Between Delphi And MapInfo TONG Gang, SHEN Qing-hua,BI Wei-zhun (College of Automation and Electronic, Qingdao University of Science and Technology, Qingdao 266042, China)
Abstract :The method of realizing map-integration between Delphi and MapInfo using OLE automation technology is discussed, and the method of Map Integration and the Callbacks of MapInfo message is also introduced with example in this article. So MapInfo is integrated in application of Delphi to develop efficiently applied GIS(Geographical Information System).
Key words:GIS ;OLE ;MapInfo ;Delphi ;Callbacks
1 引言
在Windows系統(tǒng)中,MapInfo二次開發(fā)方法主要有兩種,即利用自身所帶的開發(fā)工具
MapBasic和利用諸如 Delphi、VC等優(yōu)秀開發(fā)工具。利用MapBasic 這樣自帶的開發(fā)工具開
發(fā)出來的程序必須在MapInfo環(huán)境中運行,系統(tǒng)資源開銷大,開發(fā)效率不高,功能也不強,
難以開發(fā)界面友好而功能強大的定制程序,他較適合擴(kuò)展MapInfo的功能。利用Delphi之類
的優(yōu)秀開發(fā)工具進(jìn)行二次開發(fā),后臺對地圖的處理依然采用MapInfo支撐軟件,但由于前臺
采用了Delphi這樣的專業(yè)開發(fā)工具,在開發(fā)效率、開發(fā)能力、漢化、移植性等方面都優(yōu)于自
帶的工具,同時能隨整個軟件開發(fā)行業(yè)的發(fā)展不斷發(fā)展[1]。此種方法的關(guān)鍵是前臺定制程序
與后臺MapInfo之間的結(jié)合方式。目前主要有利用OLE Automation 和利用MapX標(biāo)準(zhǔn)組件進(jìn)
行開發(fā)。
Delphi是美國INPRISE公司的面向?qū)ο蟮目梢暬浖_發(fā)工具,具有非常強大的功能,
可以快速、高效地開發(fā)出基于Windows環(huán)境下的各類程序,尤其是在界面設(shè)計、數(shù)據(jù)庫編程
等方面具有獨到之處。面向?qū)ο蠛涂梢暬O(shè)計是其最突出的優(yōu)點,同時,它具有強大的編譯
能力,從而大大提高了程序的執(zhí)行效率,成為眾多程序員的開發(fā)工具。
2 OLE 自動化技術(shù)
OLE(Object Linking and Embedding)是美國Atduscorporation提出的一組協(xié)議和函數(shù),
目的是為了簡化復(fù)合文件的建立和維護(hù),它是微軟Windows系統(tǒng)中最為復(fù)雜的子系統(tǒng),是進(jìn)
程間通信的一種形式。所謂對象鏈接是指一個復(fù)合文件內(nèi)含一個參考指針引用到其它應(yīng)用程
序的對象,透過OLE把Windows各個應(yīng)用程序連接起來。
利用這種能使用戶共享不同應(yīng)用程序信息資源的OLE技術(shù),可以很容易地集成各類應(yīng)用
程序。OLE自動化是一種為WINDOWS設(shè)計的交互進(jìn)程通信機制,它允許在不同的應(yīng)用程序
之間相互訪問,可以讓一個應(yīng)用程序訪問另一個應(yīng)用程序或DLL(動態(tài)鏈接庫),如在Delphi中創(chuàng)建EXCEL中的表格等,而且可以訪問這些應(yīng)用程序?qū)ο蟮姆椒ǎ∕ethod)與屬性
(Property),它克服了鏈接和嵌套中存在的缺點,即無法用編程手段對對象進(jìn)行控制,實現(xiàn)
了對OLE組件的編程式控制。OLE 自動化包括兩部分應(yīng)用程序:一個是把OLE 組件顯現(xiàn)出
來使之可控制的應(yīng)用程序,叫做OLE 自動化服務(wù)器;另一個是利用OLE服務(wù)器提供的組件,
對該對象進(jìn)行控制操作的應(yīng)用程序,叫做OLE客戶。由于OLE 自動化服務(wù)器很小,程序的
穩(wěn)定性以及開發(fā)和維護(hù)都要優(yōu)于傳統(tǒng)的大程序。對于每個OLE對象的屬性和方法,程序員可
以決定將OLE自動化服務(wù)器的某些屬性和方法通過OLE 自動化表現(xiàn)出來,而私有對象對于
外部用戶來說是不可見的,但是OLE客戶編程人員只需知道包含對象的應(yīng)用程序的名稱、對
象的類的名稱和想要使用的屬性和方法的名稱,就可以使用自動化服務(wù)器了[3]。通過OLE自
動化技術(shù),運用Delphi語言可以很方便地進(jìn)行地圖集成,此時,Delphi程序即為客戶程序。
3 利用OLE 自動化技術(shù)實現(xiàn)地圖集成
進(jìn)行 Delphi 與MapInfo 的集成開發(fā)時,可以將Delphi 作為OLE 自動化的控制方或DDE
的客戶,把MapInfo 置于后臺運行,但最好采用OLE 自動化方式,因為這種方式比DDE
方式更快、更可靠,并且在調(diào)試運行中可以獲得更多出錯信息。OLE 自動化是Windows 程
序之間相互操作的技術(shù),可以創(chuàng)建自動化客戶程序來操縱其他程序,而MapInfo 則可以作為
OLE 對象的服務(wù)器,并提供了一套相應(yīng)的方法。
3.1 實現(xiàn)Delphi 取得對MapInfo Professional 的控制和服務(wù)
Delphi 程序中通過特定的ActiveX 控制接口,執(zhí)行相應(yīng)接口方法函數(shù),MapInfo
Professional 發(fā)出控制命令,取得其服務(wù),達(dá)到操縱嵌入在Delphi 程序界面上的MapInfo 圖
形資料的目的。對于此技術(shù)點可以利用Delphi 對ActiveX(OLE)支持的函數(shù)啟動和控制
MapInfo Professional 運行。OLE 自動化是Windows 程序之間相互操作的技巧, Delphi 完全
支持OLE 自動化操作,可以創(chuàng)建自動化客戶程序來操作其他的程序,而MapInfo 則可以作
為OLE 對象的服務(wù)器,并提供了相應(yīng)的一套方法,Delphi 通過建立一個OLE 對象來創(chuàng)建客
戶自動化程序,要創(chuàng)建OLE 對象,需調(diào)用CreateOLE—Object 函數(shù)(在comObj 單元中定義),
并且把返回結(jié)果賦給一個Variant 類型的變量,以后程序就通過這個變量來訪問 OLE 對象。
這時的Delphi 程序是ActiveX (OLE)客戶應(yīng)用程序,控制MapInfo Professional 運行, 在后
臺運行的MapInfo Professional 是ActiveX (OLE)自動化服務(wù)器,為Delphi 程序提供服務(wù)。
Delphi 與MapInfo Professional 的結(jié)合方式如圖1。
圖1 Delphi 與MapInfo Professional 的結(jié)合方式
Fig.1 Combination of MapInfo Professional and Delphi
3.2 Delphi 應(yīng)用程序與MapInfo 的集成
(1)建立MapInfo 自動化對象
Delphi 創(chuàng)建客戶自動化程序是通過建立一個OLE 對象來實現(xiàn)的,要創(chuàng)建OLE 對象,需
調(diào)用CreateOLEObject 函數(shù)(在OLEAUTO 單元中定義),并把返回結(jié)果賦給一個Variant 類
型的變量,以后程序就通過這個變量來訪問OLE 對象。設(shè)變量名為Olemapinfo,其具體語句
如下:
var OleMapInfo:Variant;//在Delphi 應(yīng)用程序中聲明OLE Variant 類型的變量
Olemapinfo:=CreateOleobject(‘mapinfo.application’);//創(chuàng)建OLE 對象
(2) Delphi 應(yīng)用程序中集成MapInfo 窗口
Ole 自動化對象建立后,后臺MapInfo 成功啟動,可以使用該對象的Do 方法向MapInfo
發(fā)送命令,如:
Olemapinfo.do(’set application window ’+winhand);
Olemapinfo.do(’set next document parent’+winhand+’style l’);//重定位MapInfo 文件窗口其中,還可用來重定位其他特殊窗口或圖例,可采用 MapBasic 的”setwindow”語句;
“style1”也可以為“style2”或“style3”,它表明所創(chuàng)建窗口的類型。
完成上述設(shè)置,就可以在客戶程序中打開 MapInfo 文件了,如:
Olemapinfo.do (‘open table”city.tab”’);
Olemapinfo.do (‘map from city ’);//打開MapInfo 表直接調(diào)用MapInfo 菜單或按鈕命令對地圖窗口進(jìn)行操作,只需調(diào)用MapInfo 的
RunMenuCommand 方法,從而保留有標(biāo)準(zhǔn)的MapInfo 按鈕的功能,大大減少了重新編程的
難度而輕松實現(xiàn)MapInfo 的基本功能。具體語句如下:
Olemapinfo.runmenucommand(1705);//放大
Olemapinfo.runmenucommand(1706);//縮小
Olemapinfo.runmenucommand(1702);//漫游
(3) 終止MapInfo 程序
在調(diào)用 Delphi 的CreateOleObject0 函數(shù)來創(chuàng)建一個新的MapInfo 事件時,在釋放該對象
變量時,該MapInfo 事件就終止了,當(dāng)該對象變量為局域變量時, 當(dāng)退出局域過程時,該
MapInfo 事件就被釋放了,若為全局變量時,必將其賦值為”Unassigned”才能得以釋放。語
句如下:Olemapinfo:=Unassigned;//釋放全局變量,終止MapInfo程序Application.Terminate;//終止Delphi 程序
3.3 Delphi 中MapInfo CallBack 的實現(xiàn)
通過對集成地圖程序的設(shè)置,可以使MapInfo 能自動地向客戶程序發(fā)送信息,這種類型的標(biāo)志信息,即事件導(dǎo)致MapInfo 調(diào)用客戶程序,這種消息稱之為回調(diào)。
要使用回調(diào),客戶端程序必須能充當(dāng)OLE 自動化服務(wù)器,而利用Delphi 能很輕易實現(xiàn)。
其實現(xiàn)原理如圖2:
圖 2 Delphi 中實現(xiàn)MapInfo 的callback 的原理圖
Fig.2 The schematic diagram of realizing callback of MapInfo in Delphi
要實現(xiàn) Maplnfo 的CallBack,一般有以下幾個步驟:
1)創(chuàng)建一個類,定義若干OLE 方法(Method)。如果要得到MapInfo 的狀態(tài)欄上的內(nèi)容,
則創(chuàng)建SetStatusText 方法(帶一個字符串參數(shù));如果要取得發(fā)生變化的地圖窗口的ID 號,
則創(chuàng)建Windowcontentschanged 方法(帶一個整形參數(shù));
2)為在1)中定義的類創(chuàng)建一個對象;
3)在確認(rèn)MapInfo 已經(jīng)啟動后,調(diào)用MapInfo 的SetCallBack 方法,將OLE 自動化對象
注冊MapInfo 所發(fā)送消息的“接收器”中;
4)自定義菜單或按鈕,通過這些菜單或按鈕來調(diào)用在1)中定義的方法。
當(dāng) MapInfo 中發(fā)生一個事件時,MapInfo 就會將相應(yīng)的信息組織成一定的形式,以方法
的參數(shù)方式傳遞到客戶應(yīng)用程序。在這些方法的內(nèi)部,程序員可以對這些信息進(jìn)行處理,提
取所需的信息。以自定義客戶程序的狀態(tài)欄為例,回調(diào)的使用方法如下:
1)建一個類,定義SetStatusText 方法。此方法帶一個WideString 類型的參數(shù)StatusText。
這個參數(shù)是MapInfo 向客戶程序傳遞過來的。
在 Delphi6.0 中選擇File|New|ActiveX|Automation Object,通過啟動Automation
Object 向?qū)Т蜷_“Type Library”編輯器來實現(xiàn)。這里假設(shè)創(chuàng)建的類名為TmyCallBack。
2)應(yīng)用程序窗體中添加狀態(tài)欄。
3)使用第一步中定義的類創(chuàng)建一個對象。
varCallBack := TMyCallBack.Create;
4)調(diào)用自動OLE 對象的SetCallBack 方法傳遞參數(shù)。
oleMapInfo.SetCallback(varCallBack As IMyCallBack);
5)在SetStatusText 方法中處理由MapInfo 傳遞的StatusText 參數(shù),控制狀態(tài)欄的顯示。
procedure TMyCallBack.SetStatusText(const StatusText: WideString);
begin MainForm.StatusBar1.Panels[0].Text := StatusText;
//MainForm 是容納地圖組件的窗體,StatusBar1 是添加狀態(tài)欄的缺省名,panel,用于顯
示MapInfo 的狀態(tài)欄上的內(nèi)容;End;
4 結(jié)束語
利用 OLE 自動化技術(shù), 通過 Delphi 實現(xiàn)了MapInfo 的二次開發(fā),充分發(fā)揮了Delphi
編程工具強大的數(shù)據(jù)庫編程能力和MapInfo Professional 的圖形處理能力。而在開發(fā)過程中,
兩者是相互獨立的,Delphi 可以很方便地并不需做任何改動地調(diào)用MapBasic 代碼,實現(xiàn)通
過簡單的OLE 自動化技術(shù)提交控制命令來完成MapInfo Professional 的功能和效果,取得很
好的應(yīng)用效果。同時,在進(jìn)行MapInfo 消息回調(diào)處理方法上,也可利用OLE 自動化技術(shù)來
MapInfo Professional 的自動回調(diào)消息。