李巍
天津市漢沽區(qū)公用房屋管理所 天津 300480
隨著Intranet/Intement的飛速發(fā)展,使軟件應(yīng)用置身于更加廣闊的環(huán)境中,從而對(duì)應(yīng)軟件提出了更高的要求。在這樣的環(huán)境下,面向?qū)ο蟮乃枷胍呀?jīng)難以適應(yīng)這種分布式的軟件模型,于是組件化程序設(shè)計(jì)思想得到了迅速的發(fā)展。
按照組件化程序設(shè)計(jì)的思想,復(fù)雜的應(yīng)用程序被設(shè)計(jì)成一些小的、功能單一的組件模塊,這些組件模塊可以運(yùn)行在同一臺(tái)機(jī)器上,也可以運(yùn)行在不同的機(jī)器上,甚至可以是不同的操作系統(tǒng)。為了實(shí)現(xiàn)這樣的應(yīng)用軟件,組件程序和組件程序之間需要一些極為細(xì)致的規(guī)范,只有組件程序遵守了這些共同的規(guī)范,軟件系統(tǒng)才能正常的運(yùn)行。為此,OMG(Object Management group,對(duì)象管理組織)和Microsoft分別提出了CORBA和COM(Component Object Model,組件對(duì)象模型)標(biāo)準(zhǔn),目前CORBA模型主要應(yīng)用于UNIX操作系統(tǒng)平臺(tái),而COM則主要應(yīng)用于Microsoft Windows操作系統(tǒng)平臺(tái)上。
Windows系統(tǒng)提供了一個(gè)用于注冊(cè)進(jìn)程內(nèi)組件的使用工具Regsvr32.exe,只要進(jìn)程內(nèi)組件提供了相應(yīng)的入口函數(shù),則Regsvr32就可以完成注冊(cè)或稱(chēng)注銷(xiāo),而Regsvr32程序本身并不進(jìn)行注冊(cè)工作。
除了利用Regsvr32程序進(jìn)行注冊(cè)之外,還有其他一些安裝程序在安裝或卸載的過(guò)程中也可以調(diào)用組件程序中的DLLRegisterServer函數(shù)和DLLUnregisterServer函數(shù)完成組件程序的注冊(cè)和注銷(xiāo)操作。
COM本身除了規(guī)范以外,也有實(shí)現(xiàn)的部分,其中包括一些核心的系統(tǒng)級(jí)代碼,也正是這部分核心代碼,才使得對(duì)象和客戶(hù)之間可通過(guò)接口在二進(jìn)制代碼級(jí)進(jìn)行交互。在Microsoft Windows操作系統(tǒng)環(huán)境下,這些庫(kù)以.DLL文件的形式存在,其中包括以下內(nèi)容:
(1)提供了少量的API函數(shù)實(shí)現(xiàn)客戶(hù)和服務(wù)器端COM應(yīng)用的創(chuàng)建過(guò)程。在客戶(hù)端,主要是一些創(chuàng)建函數(shù);而在服務(wù)器端,提供一些對(duì)對(duì)象的訪(fǎng)問(wèn)支持。
(2)COM通過(guò)注冊(cè)表查找本地服務(wù)器即EXE程序,以及程序名與CLSID的轉(zhuǎn)換等。
(3)提供了一種標(biāo)準(zhǔn)的內(nèi)存控制方法,使應(yīng)用控制進(jìn)程中內(nèi)存的分配。
設(shè)計(jì)接收器對(duì)象與連接點(diǎn)對(duì)象之間如何建立關(guān)系的過(guò)程,這個(gè)過(guò)程是由客戶(hù)方控制的,所以客戶(hù)首先詢(xún)問(wèn)對(duì)象是公為可連接對(duì)象,它只需調(diào)用對(duì)象的QueryInterface成員函數(shù),請(qǐng)求IConnection pointContainer接口,如果請(qǐng)求成功,則表明為可連接對(duì)象,并返IConnection pointContainer接口指針,否則說(shuō)明對(duì)象不是可連接對(duì)象??蛻?hù)得到了IConnection pointContainer接口后,調(diào)用其成員函數(shù)獲取出接口的連接點(diǎn)對(duì)象,如果對(duì)象支持此出接口,則可以得到連接點(diǎn)對(duì)象,然而調(diào)用連接點(diǎn)對(duì)象的IConnection point接口的成員函數(shù)建立連接。如果客戶(hù)要取消連接,同樣調(diào)用IConnection point接口的成員函數(shù)即可。
首先在應(yīng)用類(lèi)的InitInstance成員函數(shù)中加入COM或OLB庫(kù)初始化函數(shù),InitInstance函數(shù)開(kāi)始處理調(diào)用AfxOleInit輔助函數(shù)代碼如下:
BOOL CTestCtrlApp::InitInstance()
{
// Initialize OLE libraries
if(!AfxOleInit())
{
AfxMessageBox("Initializing OLE library failed");
return FALSE;
}
AfxEnableControlContainer();
為對(duì)話(huà)框類(lèi)加入內(nèi)嵌的接受對(duì)象,因?yàn)閷?duì)話(huà)框類(lèi)也是從CCmdtarget派生而來(lái)的,所以在對(duì)話(huà)框類(lèi)中可以使用BEGIN_INTERFACE_PART/END_INTERFACE_PART宏定義接受器對(duì)象類(lèi)。定義接受器對(duì)象類(lèi):
BEGIN_INTERFACE_PART(EventSink,IDispatch)
INIT_INTERFACE_PART(CTestCtrlDlg,EventSink)
STDMETHOD(GetTypeInfoCount)(unsigned int*);
STDMETHOD(GetTypeInfo)(unsigned int,LCID,ITypeInfo**);
STDMETHOD(GetIDsOfNames)(REFIID,LPOLESTR*,unsigned int,LCID,DISPID*);
STDMETHOD(Invoke)(DISPID,REFIID,LCID,unsigned short,DISPPARAMS*,
VARIANT*,EXCEPINFO*,unsigned int*);
END_INTERFACE_PART(EventSink)
對(duì)話(huà)框的操作,首先,在InitInstance成員函數(shù)中加入如下創(chuàng)建源對(duì)象的代碼:
GUID sourceobjCLSID;
HRESULThResult=::CLSIDFromProgID(L"SourceComp.S ourceObj",&sourceobjCLSID); if(FAILED(hResult))
{
return FALSE;
}
hResult = CoCreateInstance(sourceobjCLSID,NULL,
CLSCTX_INPROC_SERVER,IID_IDispatch,(void**)&m_pDispatch);
if(FAILED(hResult))
{
return FALSE;
}
按照消息控制函數(shù)0nConnection和OnDisconnection分別調(diào)用輔助函數(shù)Connection和Disconnection作為響應(yīng),并根據(jù)不同的返回值進(jìn)行不同的處理。
按鈕消息控制Onsetproperty為源對(duì)象的屬性賦值,在賦值之后,源對(duì)象會(huì)引發(fā)事件。
所以,在連接已經(jīng)建立的狀態(tài)下,當(dāng)用戶(hù)按下“設(shè)置屬性”按鈕時(shí),會(huì)出現(xiàn)事件響應(yīng)消息框。
最后我們還必須對(duì)對(duì)話(huà)框類(lèi)的析構(gòu)函數(shù)中的清除工作,包括斷開(kāi)連接、釋放源對(duì)象等操作。在CTestCtrlDlg析構(gòu)函數(shù)加入下面代碼:
if(m_pDispatch != NULL){
if(m_dwCookie != 0)
Disconnection();
m_pDispatch->Release();
}
在VC++環(huán)境下COM的編程,VC++對(duì)CO3M開(kāi)發(fā)提供了很好的支持,技術(shù)非常成熟,功能非常強(qiáng)大,使用VC++可以開(kāi)發(fā)出功能強(qiáng)大,接口集合度高,占用資源少的應(yīng)用程序。使用VC++的MFC類(lèi),模板類(lèi),以及AppWizard,ClassWizard等用于產(chǎn)生應(yīng)用程序的特點(diǎn),加快應(yīng)用程序的設(shè)計(jì),用組件技術(shù)可以很好地開(kāi)發(fā)出一個(gè)完整的應(yīng)用程序。
[1]蘇長(zhǎng)齡.C/C++程序設(shè)計(jì)教程.中國(guó)水利水利出版社.2007.
[2][美]帕拉特著.COM精髓.信達(dá)工作室譯.2001.
[3]吳金平.VisualC++6.0編程與實(shí)踐.中國(guó)水利水電出版社.2001.