摘要:在探討自動化和窗體嵌入方法的基礎上,提出了通過自動化和窗體嵌入進行復雜系統集成的方法#65377;該方法通過自動化實現系統的功能集成,通過窗體嵌入實現系統的圖形用戶界面(GUI)集成,給出了基于自動化的系統集成模型,探討了窗體嵌入中的跨進程窗體捕獲#65380;嵌入以及控制等關鍵問題#65377;利用該方法可以非常容易地實現不同語言平臺下開發的應用程序的功能和界面無縫集成,不僅可以充分地利用已有資源,減少重復開發,而且大大降低了系統設計的復雜度,提高了系統的健壯性和可維護性#65377;
關鍵詞:自動化;圖形用戶界面;嵌入窗體;系統集成
中圖分類號:TP311.1文獻標志碼:A
文章編號:1001-3695(2007)04-0268-02
在復雜的軟件系統的設計中,常常根據功能的需求按照逐步求精的思想對系統進行模塊細分#65377;對于某些子系統,通常用已經開發完成的成熟系統,這些系統常常基于不同的語言平臺開發,因此采取何種簡單有效的方式對各個子系統進行集成,既實現功能的集成,又能對基于圖形用戶界面(GUI)的各子系統實現界面的無縫集成,成為系統設計中必須考慮的一個問題#65377;本文在研究自動化與跨進程窗體控制的基礎上,對基于自動化(Automation)與跨進程控制的系統集成方法進行了研究#65377;
1自動化簡介[1~3]
組件對象模型(COM)是Microsoft開發的一種以組件為單元的平臺獨立#65380;分布式#65380;面向對象#65380;可重用的二進制對象模型,是Microsoft OLE#65380;ActiveX等技術的基礎#65377;COM既不是一種語言,也不是一種程序設計方法,而是一種對象交互標準#65377;COM對象通過定義良好的接口進行耦合#65377;
自動化是COM接口IDispatch的通俗說法#65377;Automation可以使應用程序將自身的功能開放給其他應用程序使用#65377;Microsoft Office系列均通過自動化功能提供了具有層次結構的對象供其他應用程序調用#65377;其他如Surfer#65380;AutoCAD#65380;MapInfo等軟件也提供了自動化功能#65377;自動化對象可以在C/C++#65380;Visual Basic#65380;Delphi#65380;Java#65380;.NET等多種語言下開發,同樣自動化程序不僅可以在上述平臺下被調用,而且可以被一些解釋型的腳本語言如VBScript#65380;JScript等調用#65377;
自動化的核心為IDispatch接口,其定義如下:
從IDispatch接口的定義可以看出,該接口本身不提供任何功能,只是功能組件的代理,充當客戶與功能組件之間的管道,客戶程序通過IDispatch∷Invoke來激活組件中的特定方法#65377;而IDispatch的調度程序是基于類型庫進行的,所以其僅支持自動化兼容的數據類型#65377;
盡管自動化的實現看起來很復雜,但多數的集成開發環境(IDE)如Visual Basic#65380;Delphi#65380;Visual C++#65380;.NET等均提供了自動化支持,使得開發自動化應用程序變得非常容易#65377;系統中的各個子系統模塊,不管在何種語言平臺下開發,均可以按照自動化的方式進行封裝,并提供具有層次結構的對象供其他程序調用,只要實現既定的功能接口,就可以很容易地實現集成調用#65377;基于自動化的系統功能集成模型如圖1所示#65377;
2窗體嵌入方法[4~6]
雖然通過自動化可以實現對各個子系統模塊程序的集成控制,但在通過圖形用戶界面完成復雜操作的子模塊中,用戶的交互操作對圖形用戶界面具有極大的依賴性#65377;因此為了實現系統的完善集成必須進行圖形用戶界面的集成,通過對窗體的嵌入研究實現了圖形用戶界面的集成#65377;
2.1跨進程的Windows窗體的獲取方法
在Windows系統基于GUI的應用中,通常都有一個頂層主窗體和多個以其為父窗體的子窗體#65377;其生命周期為應用的生命周期,即隨著子系統應用的啟動而創建,隨著應用的結束而銷毀;同時還有多種動態生成的窗體,其生命周期是不確定的,如各種對話框窗體#65377;對各種生命周期不同的窗體通常有各種不同的獲取方法:
(1)主窗體的獲取#65377;Windows AP中提供了一種獲取應用程序主窗體的方法,其接口函數為HWND FindWindow(LPCTSTRlpClassName,LPCTSTR lpWindowName)#65377;通過該API接口函數的定義知道,只要知道所要獲取的窗體的窗體名稱就可以獲得相應的頂層主窗體句柄#65377;
(2)子窗體的獲取#65377;在獲取了應用的主窗體后,子窗體的獲取就變得比較簡單,通過GetWindow( HWND hWnd, UINT uCmd )可獲取相應的子窗體,如果已知窗體的標志ID,也可通過GetDlgItem(HWND hDlg,int nIDDlgItem)直接獲取相應的子窗體#65377;
(3)動態窗體的獲取#65377;動態窗體因為其生命周期的不確定性而決定了其獲取的復雜性,因為窗體的生成在另一個與主控進程完全不同的分離的地址空間,所以需要一種能全局監控Windows系統窗體生成的方法#65377;通過Windows系統提供的鉤子機制可以實現上述功能#65377;
通過設置WH_CBT系統鉤子過程,可以監控目標進程窗體的生成#65380;激活#65380;銷毀等,從而可以動態地獲取窗體并對其進行控制#65377;設置方法如下:
需要注意的是,為了實現跨進程的窗體監控,鉤子過程必須在Windows動態鏈接庫中實現,這樣才能實現鉤子過程到目標進程的映射;否則由于進程地址空間的隔離性,上述過程無法完成#65377;
2.2跨進程的Windows窗體的嵌入
窗體的嵌入過程就是改變窗體父窗體的過程,也即把被控制的目標窗體的父窗體設置為控制窗體的過程,同時使被控的目標窗體隨著控制窗體的位置#65380;尺寸的改變而動態改變#65377;因此跨進程窗體的嵌入分成兩部分:①設置被控目標窗體的父窗體為控制窗體,可以通過Windows API HWND SetParent(HWND hWndChild, HWND hWndNewParent)完成,對于頂層窗體隨時通過改變窗體的屬性使之不作為頂層窗體;②使目標窗體隨動控制窗體,這可以通過接管控制窗體的WM_SIZE消息處理過程,在消息處理過程中通過Windows API BOOL MoveWindow(HWND hWnd, int X, int Y, int nWidth,int nHeight, BOOL bRepaint)動態改變目標窗體的位置#65377;
2.3跨進程的Windows窗體的控制方法
在獲取了目標進程窗體后,可以通過各種窗體控制API來對窗體進行控制,如通過API BOOL ShowWindow( HWND hWnd, int nCmdShow )控制窗體的可見性;同時因為Windows系統是基于消息的系統,所以可以通過:
#65377;
3基于自動化和窗體嵌入的BTEX系統集成
BTEX系統是處理由激光單分子技術所測海底淺層沉積物中的低環芳香烴指標:苯(B)#65380;甲苯(T)#65380;乙苯(E)#65380;二甲苯(X)等數據,并結合海洋地質#65380;構造#65380;物探和測井等資料對油氣化探異常(BTEX)進行綜合評價,預測海底油氣藏的數據倉系統#65377;該系統按基于GIS的數據倉模式進行設計#65380;開發,主要包含了以下功能模塊包:數據倉主題管理#65380;數據抽取#65380; 數據倉管理#65380;數據處理挖掘#65380;聯機分析展示#65380;綜合評價#65380;評價結果展示及成圖#65380;輔助圖形工具等#65377;系統的主要部分是在.NET平臺下以C#語言實現的,處理與評價功能模塊分別采用了Fortran#65380;C/C++和Delphi等語言開發的已經過測試的成熟模塊(如各種數據處理#65380;異常分析#65380;背景分析模塊),有些模塊利用了第三方應用,如等值線成圖模塊引用了Surfer軟件的功能(具有完善的自動化體系)#65377;為此,在系統的集成中使用了基于自動化與窗體嵌入的系統集成技術,通過對已有的模塊進行自動化擴展和新模塊的自動化設計完成了系統的集成,大大提高了系統的開發效率#65377;
下面以等值線成圖模塊的集成控制過程為例介紹基于自動化與窗體嵌入的系統集成過程#65377;集成效果如圖2所示#65377;
4結束語
Windows系統平臺下自動化技術被越來越多的應用系統所支持,通過對開發的程序增加自動化功能,使其可以輕松地為需要該功能的程序所集成,同時也可以集成其他具有自動化功能的應用程序#65377;通過對窗體嵌入方法的研究可以實現對依賴圖形用戶界面完成復雜交互操作的子模塊實現界面集成#65377;
本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文。