版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
動(dòng)態(tài)鏈接庫(kù)和ActiveX開(kāi)發(fā)第09章本章主要內(nèi)容9.2編寫(xiě)自己的ActiveX控件9.1編寫(xiě)自己的DLL9.1編寫(xiě)自己的DLL9.1.1DLL概述9.1.2MFC中DLL的分類(lèi)9.1.3DLL中的導(dǎo)入導(dǎo)出函數(shù)9.1.4DLL中的數(shù)據(jù)與資源9.1.5DLL與應(yīng)用程序的鏈接9.1.6DLL開(kāi)發(fā)舉例9.1.1DLL概述
比較大的應(yīng)用程序都是由很多模塊組成,這些模塊分別完成相對(duì)獨(dú)立的功能,它們彼此協(xié)作完成整個(gè)軟件系統(tǒng)的工作,其中可能存在一些模塊的功能較為通用,在構(gòu)造其它軟件系統(tǒng)時(shí)仍會(huì)被使用。在構(gòu)造軟件系統(tǒng)時(shí),如果將所有模塊的源代碼都靜態(tài)編譯到整個(gè)應(yīng)用程序文件中,會(huì)帶來(lái)一些不足:一是增加了應(yīng)用程序的大小,占用更多的磁盤(pán)空間,程序運(yùn)行時(shí)也會(huì)消耗較大的內(nèi)存空間,造成系統(tǒng)資源的浪費(fèi);二是在編寫(xiě)大的應(yīng)用程序時(shí),每次修改重建都必須編譯所有的源代碼,增加了編譯過(guò)程的復(fù)雜性,也不利于階段性的單元測(cè)試。Windows平臺(tái)提供了一種較為有效的編程和運(yùn)行環(huán)境,開(kāi)發(fā)者可以將獨(dú)立的程序模塊創(chuàng)建為DLL(DynamicLinkableLibrary)文件,并可對(duì)它們進(jìn)行單獨(dú)編譯和測(cè)試。運(yùn)行時(shí),只有當(dāng)EXE程序調(diào)用這些DLL模塊時(shí),系統(tǒng)才會(huì)將它們裝載到內(nèi)存空間,這種方式不僅減少了EXE文件的大小和對(duì)內(nèi)存空間的占用,而且使這些DLL模塊同時(shí)被多個(gè)應(yīng)用程序使用,Windows自身就將一些主要功能以DLL模塊形式實(shí)現(xiàn)。9.1.1DLL概述一般來(lái)說(shuō),DLL是一種二進(jìn)制文件(通常帶有DLL擴(kuò)展名),它由全局?jǐn)?shù)據(jù)、服務(wù)函數(shù)和資源組成。在運(yùn)行時(shí)被系統(tǒng)加載到進(jìn)程的虛擬地址空間中,成為調(diào)用進(jìn)程的一部分。如果與其它DLL沒(méi)有沖突,該文件通常映射到進(jìn)程虛擬地址空間的同一地址上。DLL模塊中包含各種導(dǎo)出函數(shù),用于向外界提供服務(wù),Windows在加載DLL模塊時(shí),將進(jìn)程中的函數(shù)調(diào)用與DLL文件的導(dǎo)出函數(shù)進(jìn)行匹配。在Windows環(huán)境中,每個(gè)進(jìn)程都復(fù)制了自己的讀/寫(xiě)全局變量,如果想和其它進(jìn)程共享內(nèi)存,必須使用內(nèi)存映射文件或者聲明一個(gè)共享數(shù)據(jù)段,DLL模塊需要的內(nèi)存都是從運(yùn)行進(jìn)程的堆棧中分配的。
DLL編程越來(lái)越容易了,Windows大大簡(jiǎn)化了其編程模式,而且有各種向?qū)Ш蚆FC類(lèi)庫(kù)支持,下面主要討論如何在VS2010環(huán)境中使用MFC編寫(xiě)DLL。9.1.2MFC中DLL的分類(lèi)帶靜態(tài)鏈接MFC的規(guī)則DLL
使用共享MFCDLL的規(guī)則DLLMFC擴(kuò)展DLLVS2010MFCDLL向?qū)?duì)話框1、帶靜態(tài)鏈接MFC的規(guī)則DLL使用
該類(lèi)DLL采用靜態(tài)方式連接到MFC的動(dòng)態(tài)連接庫(kù),它的特點(diǎn)是在源文件里有一個(gè)繼承自CWinApp的類(lèi)。這種DLL應(yīng)用程序的導(dǎo)出函數(shù)可以被任何Windows應(yīng)用程序調(diào)用,因?yàn)樵搫?dòng)態(tài)庫(kù)包含了它所使用的所有MFC函數(shù)。其導(dǎo)出函數(shù)具有如下形式:
extern“C”EXPORTYourExportedFunction();
如果沒(méi)有extern“C”修飾,導(dǎo)出函數(shù)僅能被C++代碼調(diào)用,DLL應(yīng)用程序從CWinApp派生,但沒(méi)有消息循環(huán)。它自動(dòng)生成def文件,在派生類(lèi)的InitInstance和ExitInstance成員函數(shù)中完成初始化和結(jié)束工作。2.使用共享MFCDLL的規(guī)則DLL
它和靜態(tài)鏈接的DLL一樣,也是內(nèi)部使用MFC的DLL,導(dǎo)出函數(shù)是標(biāo)準(zhǔn)的C語(yǔ)言接口,可以被MFC和非MFC應(yīng)用程序使用,具有def文件,在CWinApp派生類(lèi)的InitInstance和ExitInstance成員函數(shù)中進(jìn)行初始化和結(jié)束工作。這種DLL建立時(shí)使用的是MFC的動(dòng)態(tài)共享庫(kù),但它的導(dǎo)出函數(shù)可以被任何Windows應(yīng)用程序所調(diào)用,包括使用MFC的應(yīng)用程序。所有從DLL導(dǎo)出的函數(shù)應(yīng)該加上如下語(yǔ)句:AFX_MANAGE_STATE(AfxGetStaticModuleState())該宏用于正確切換MFC模塊狀態(tài),AfxGetStaticModuleState函數(shù)用于獲取模塊狀態(tài),這個(gè)宏必須出現(xiàn)在任何調(diào)用MFC語(yǔ)句之前,包括聲明對(duì)象、變量之前,因?yàn)樗鼈兊臉?gòu)造函數(shù)可能會(huì)調(diào)用MFCDLL,該宏在調(diào)用MFCDLL導(dǎo)出函數(shù)時(shí)保證模塊狀態(tài)的正確以及能訪問(wèn)到有效資源(如DLL中的對(duì)話框等),而且MFC模塊結(jié)束時(shí),自動(dòng)恢復(fù)到以前的模塊狀態(tài)。提示:AFX_MANAGE_STATE宏不能用在靜態(tài)鏈接的MFCDLL和MFC擴(kuò)展DLL中。如果要在動(dòng)態(tài)鏈接MFCDLL中使用MFCOLE功能,則必須在DLL的InitInstance中調(diào)用AfxOleInitModule。同樣,如果使用MFC數(shù)據(jù)庫(kù)或DAO支持,必須調(diào)用AfxDbInitModule,使用MFCSocket支持,則要調(diào)用AfxNetInitModule。3.MFC擴(kuò)展DLL
MFC擴(kuò)展DLL,用來(lái)導(dǎo)出從MFC繼承的類(lèi),也就是說(shuō),用這種類(lèi)型的動(dòng)態(tài)連接庫(kù),可以用來(lái)導(dǎo)出一個(gè)從MFC繼承的類(lèi)。它的導(dǎo)出函數(shù)只可以被使用MFC且動(dòng)態(tài)鏈接到MFC的應(yīng)用程序所使用。可以從MFC繼承用戶所需要的類(lèi),并把它提供給客戶應(yīng)用程序,也可給客戶應(yīng)用程序提供MFC或MFC繼承類(lèi)的對(duì)象指針。MFC擴(kuò)展DLL使用MFC動(dòng)態(tài)鏈接方式創(chuàng)建,而且只能用于MFC類(lèi)庫(kù)所編寫(xiě)的應(yīng)用程序。MFC擴(kuò)展DLL和前兩種DLL不同,它沒(méi)有從CWinApp派生應(yīng)用程序類(lèi)。因此,程序員必須在DllMain函數(shù)(DLL的主函數(shù))中為自己的動(dòng)態(tài)鏈接庫(kù)編寫(xiě)代碼以實(shí)現(xiàn)DLL的初始化和結(jié)束清理工作??傊琈FC擴(kuò)展DLL具有幾個(gè)方面特征:(1)沒(méi)有應(yīng)用程序?qū)ο螅ㄅ缮訡WinApp);(2)必須有一個(gè)DllMain函數(shù);(3)DllMain必須調(diào)用AfxInitExtensionModule函數(shù),并且檢查其返回值,如果返回0,DllMmain也返回0;(4)如果想導(dǎo)出CRuntimeClass類(lèi)型的對(duì)象或者資源(Resources),則需要提供一個(gè)初始化函數(shù)用來(lái)創(chuàng)建CDynLinkLibrary對(duì)象,并且初始化函數(shù)也要導(dǎo)出;(5)使用MFC擴(kuò)展DLL的MFC應(yīng)用程序必須有一個(gè)CWinApp派生類(lèi),在該派生類(lèi)的InitInstance成員函數(shù)中調(diào)用MFC擴(kuò)展DLL的初始化函數(shù)。9.1.3DLL中的導(dǎo)入導(dǎo)出函數(shù)
在動(dòng)態(tài)鏈接庫(kù)中,定義的函數(shù)有兩種:導(dǎo)出函數(shù)(exportfunction)和內(nèi)部函數(shù)(internalfunction),導(dǎo)出函數(shù)可以被其它模塊調(diào)用,內(nèi)部函數(shù)只能在動(dòng)態(tài)庫(kù)內(nèi)部使用。DLL文件中包含一個(gè)導(dǎo)出函數(shù)表,這些導(dǎo)出函數(shù)通過(guò)它們的符號(hào)名和整型標(biāo)識(shí)號(hào)與外界聯(lián)系,函數(shù)表中還包含了DLL中函數(shù)的地址。當(dāng)應(yīng)用程序加載DLL模塊時(shí),它并不知道調(diào)用函數(shù)的實(shí)際地址,但它知道函數(shù)的符號(hào)名和標(biāo)識(shí)號(hào),動(dòng)態(tài)鏈接在加載DLL模塊時(shí)動(dòng)態(tài)建立一個(gè)函數(shù)調(diào)用與函數(shù)地址的對(duì)應(yīng)表,如果重新編譯DLL文件,并不需要修改應(yīng)用程序,除非改變了導(dǎo)出函數(shù)的符號(hào)名和參數(shù)列表。簡(jiǎn)單的DLL文件只為應(yīng)用程序提供導(dǎo)出函數(shù),復(fù)雜的DLL文件除了提供導(dǎo)出函數(shù)外,還調(diào)用其它DLL文件中的函數(shù),這樣,一個(gè)動(dòng)態(tài)鏈接庫(kù)既有導(dǎo)出函數(shù),又有導(dǎo)入函數(shù)。這并不會(huì)產(chǎn)生任何問(wèn)題,因?yàn)閯?dòng)態(tài)鏈接過(guò)程可以正確處理交叉引用。從DLL中導(dǎo)出函數(shù)(1)使用DEF文件(2)使用關(guān)鍵字_declspec(dllexport)(3)使用AFX_EXT_CLASS宏 使用關(guān)鍵_declspec(dllexport)不但能導(dǎo)出函數(shù),而且可以導(dǎo)出數(shù)據(jù)、類(lèi)或者類(lèi)的成員函數(shù),AFX_EXT_CLASS宏主要用來(lái)導(dǎo)出類(lèi)。(1)使用DEF文件
1.模塊定義文件(DEF)是由一個(gè)或多個(gè)用于描述DLL屬性的語(yǔ)句組成的文本文件:
NAME語(yǔ)句:指出生成DLL的文件名
LIBRARY語(yǔ)句:指出DLL的內(nèi)部名字,這個(gè)語(yǔ)句告訴鏈接器生成的是DLL
DESCRIPTION語(yǔ)句:描述DLL的用途
STACKSIZE語(yǔ)句:設(shè)置堆棧大小
SECTIONS語(yǔ)句:設(shè)置段屬性
VERSION語(yǔ)句:給出DLL的版本號(hào)
;:是注釋語(yǔ)句。(2)使用關(guān)鍵字_declspec(dllexport)
2.使用關(guān)鍵字_declspec(dllexport),可以從DLL中導(dǎo)出數(shù)據(jù)、函數(shù)、類(lèi)或者類(lèi)的成員函數(shù)。在DLL代碼中,必須明確聲明導(dǎo)出函數(shù)。__declspec(dllexport)intMyFunction(intn);相應(yīng)地,在客戶應(yīng)用程序中,也必須明確聲明相應(yīng)的導(dǎo)入函數(shù):__declspec(dllimport)intMyFuncition(intn);這個(gè)關(guān)鍵字不僅可以導(dǎo)出函數(shù),而且可以導(dǎo)出類(lèi)。用于導(dǎo)出類(lèi)時(shí),將導(dǎo)出類(lèi)中所有public成員函數(shù)和成員變量。class_declspec(dllexport)CMyExportClass:publicCObject{ //…}僅有導(dǎo)入和導(dǎo)出聲明,并不能使客戶應(yīng)用程序的函數(shù)調(diào)用鏈接到相應(yīng)的DLL文件,客戶應(yīng)用程序必須為鏈接程序指定所需要的輸入庫(kù)(LIB文件),而且客戶應(yīng)用程序至少包含對(duì)DLL中函數(shù)的一次調(diào)用。(3)使用AFX_EXT_CLASS宏
3.使用AFX_EXT_CLASS宏,MFC擴(kuò)展DLL使用AFX_EXT_CLASS宏導(dǎo)出類(lèi),鏈接這種DLL的客戶應(yīng)用程序或者其它DLL,也必須使用這個(gè)宏導(dǎo)入類(lèi)。MFC向?qū)傻膽?yīng)用程序框架支持在DLL和客戶應(yīng)用程序中使用這個(gè)宏。利用AFX_EXT_CLASS宏,MFC擴(kuò)展DLL和客戶應(yīng)用程序就可以使用相同的頭文件,給開(kāi)發(fā)工作帶來(lái)了便利。這個(gè)宏可以導(dǎo)出整個(gè)類(lèi),如:
classAFX_EXT_CLASSCMyExportClass:putlicCObject{….}也可以導(dǎo)出類(lèi)中的某個(gè)成員:
classCExampleDialog:publicCDialog
{
public:
AFX_EXT_CLASSCExampleDialog();
AFX_EXT_CLASSintDoModal();
………….
//
………….
}9.1.4DLL中的數(shù)據(jù)與資源
DLL既可以導(dǎo)出函數(shù)、類(lèi),也可以導(dǎo)出數(shù)據(jù)和資源供客戶應(yīng)用程序使用。導(dǎo)出數(shù)據(jù)。數(shù)據(jù)導(dǎo)出一般采用以下兩種方法。(1)使用DEF文件的DATA關(guān)鍵字導(dǎo)出(2)用_declspec(dllexport)關(guān)鍵字導(dǎo)出(1)使用DEF文件的DATA關(guān)鍵字導(dǎo)出(1)使用DEF文件的DATA關(guān)鍵字導(dǎo)出,在DEF文件導(dǎo)出語(yǔ)句中,除了NONAME標(biāo)志外,還有一個(gè)DATA標(biāo)志,表明前面導(dǎo)出的不是函數(shù),而是一個(gè)數(shù)據(jù)。例如:在DLL中定義了一個(gè)變量:
intnVariable=0;在DEF文件中用下列語(yǔ)句導(dǎo)出:
EXPORTS
nVariable@5DATA在客戶應(yīng)用程序中,用以下語(yǔ)句來(lái)使用DLL導(dǎo)出的數(shù)據(jù):
externintnVariable; //必須和DLL導(dǎo)出的名字相同
printf(“Dll中的nVariable=%d”,*(int*)nVariable);這種方法使用的并不是變量本身,而是DLL中導(dǎo)出變量的指針,應(yīng)用程序必須通過(guò)強(qiáng)制指針類(lèi)型轉(zhuǎn)換來(lái)使用,在客戶應(yīng)用程序中也可以使用_declspec(dllimport)關(guān)鍵字來(lái)導(dǎo)入DLL導(dǎo)出的變量。提示:在VisualC++早期版本中,用戶也可以使用CONSTANT關(guān)鍵字導(dǎo)出數(shù)據(jù),用法和DATA關(guān)鍵字一樣。在VS2010中,建議使用DATA關(guān)鍵字。(2)用_declspec(dllexport)關(guān)鍵字導(dǎo)出
用_declspec(dllexport)關(guān)鍵字導(dǎo)出,可以不使用DEF文件,在源程序中使用_declspec(dllexport)關(guān)鍵字來(lái)修飾要導(dǎo)出的變量。在客戶應(yīng)用程序中使用_declspec(dllimport)關(guān)鍵字來(lái)導(dǎo)入DLL中導(dǎo)出的變量??梢钥闯?,使用_declspec(dllexport)和_declspec(dllimport)導(dǎo)出導(dǎo)入數(shù)據(jù)是最簡(jiǎn)單的方法。DLL和客戶應(yīng)用程序一樣,也可以擁有自己的資源。如果編寫(xiě)的DLL程序僅僅是用于存放共享資源,供其它程序使用,也就是說(shuō),在DLL中只有資源,如:圖標(biāo)、位圖、字符串、聲音、視頻、對(duì)話框等,那么,這種DLL就屬于純資源DLL。使用這種純資源DLL可以縮減可執(zhí)行文件的大小,而且DLL中的資源可以被其它應(yīng)用程序所共享,提高了性能。純資源DLL編寫(xiě)比普通DLL編寫(xiě)要簡(jiǎn)單得多,首先創(chuàng)建一個(gè)WIN32DLL項(xiàng)目,注意,不是MFCDLL,然后創(chuàng)建一個(gè)資源文件(.RC),并將其添加到資源DLL項(xiàng)目中,最后添加一個(gè)初始化DLL的C++文件。
(2)用_declspec(dllexport)關(guān)鍵字導(dǎo)出extern"C"BOOLWINAPIDllMain(HINSTANCEhInstance,DWORDdwReason,LPVOID){return1;}這是純資源DLL所必需的代碼,保存這個(gè)文件為C++源文件,編譯這個(gè)資源DLL。在客戶應(yīng)用程序中調(diào)用這個(gè)DLL時(shí),使用LoadLibrary函數(shù)裝入資源DLL,使用FindResource和LoadResource裝入各種資源,或者使用下列的特定的資源裝入函數(shù)裝入特定的資源:FormatMessage、LoadAccelerators、LoadBitmapLoadCursor、LoadIcon、LoadMenu、LoadString當(dāng)資源使用結(jié)束時(shí),應(yīng)用程序必須調(diào)用FreeLibrary函數(shù)釋放資源。9.1.5DLL與應(yīng)用程序的鏈接
DLL不能單獨(dú)執(zhí)行,必須和客戶應(yīng)用程序鏈接才能使用??蛻魬?yīng)用程序的導(dǎo)入函數(shù)與DLL文件中的導(dǎo)出函數(shù)有2種鏈接方式:隱式鏈接(ImplicitLinking)和顯式鏈接(ExplicitLinking)。所謂隱式鏈接是指在應(yīng)用程序中不必指明DLL文件的存儲(chǔ)路徑,程序員也不必關(guān)心DLL文件的實(shí)際裝載,而顯式鏈接正好相反。
1.隱式鏈接方式(ImplicitLinking)
2.顯式鏈接方式(ExplicitLinking)
1.隱式鏈接方式(ImplicitLinking)
程序員在建立DLL文件時(shí),鏈接程序會(huì)自動(dòng)生成一個(gè)與之對(duì)應(yīng)的LIB導(dǎo)入文件,該文件包含了每一個(gè)導(dǎo)出函數(shù)的符號(hào)名和可選的標(biāo)識(shí)號(hào),但并不包含實(shí)際代碼。LIB文件作為DLL的替代文件被編譯到客戶應(yīng)用程序項(xiàng)目中。當(dāng)通過(guò)動(dòng)態(tài)鏈接方式編譯生成應(yīng)用程序時(shí),應(yīng)用程序中的調(diào)用函數(shù)與LIB文件中的導(dǎo)出符號(hào)相匹配,這些符號(hào)或標(biāo)識(shí)號(hào)就進(jìn)入到生成的EXE文件中。LIB文件中也包含了對(duì)應(yīng)的DLL文件名(不是完整的路徑名),鏈接程序?qū)⑵浯鎯?chǔ)在EXE文件內(nèi)部。在應(yīng)用程序運(yùn)行過(guò)程中,需要加載DLL文件時(shí),Windows就會(huì)根據(jù)這些信息發(fā)現(xiàn)并加載DLL,然后通過(guò)符號(hào)名或標(biāo)識(shí)號(hào)實(shí)現(xiàn)對(duì)DLL中函數(shù)的動(dòng)態(tài)鏈接。
2.顯式鏈接方式(ExplicitLinking)
這種方式對(duì)于集成化的開(kāi)發(fā)語(yǔ)言(例如VC、VB)比較適合。有了顯式鏈接,使用DLL的程序就不必使用導(dǎo)入文件,而是用LoadLibrary或MFC提供的AfxLoadLibrary顯式的將需要的動(dòng)態(tài)鏈接庫(kù)裝入內(nèi)存,這兩個(gè)函數(shù)的參數(shù)就是動(dòng)態(tài)鏈接庫(kù)的文件名,接下來(lái)用GetProcAddress()函數(shù)得到導(dǎo)出函數(shù)的地址,也就是導(dǎo)入的函數(shù),GetProcAddress函數(shù)將符號(hào)名或標(biāo)識(shí)號(hào)轉(zhuǎn)換為DLL內(nèi)部地址。至此,就可以像使用應(yīng)用程序自身的函數(shù)一樣,自由地調(diào)用導(dǎo)入函數(shù)了,在應(yīng)用程序退出之前,需要用FreeLibrary或MFC提供的AfxFreeLibrary函數(shù)釋放動(dòng)態(tài)鏈接庫(kù)。例如,有這樣一個(gè)導(dǎo)出函數(shù):extern"C"__declspec(dllexport)doubleSquareRoot(doubled);下面的代碼就是在客戶應(yīng)用程序中對(duì)該導(dǎo)出函數(shù)的顯式鏈接。typedefdouble(SQRTPROC)(double);HINSTANCEhInstance;SQRTPROC*pFunction;VERIFY(hInstance=::LoadLibrary("c:\\winnt\\system32\\mydll.dll"));VERIFY(pFunction=(SQRTPROC*)::GetProcAddress(hInstance,"SquareRoot"));doubled=(*pFunction)(81.0); //調(diào)用該DLL中的函數(shù)在隱式鏈接方式中,所有被應(yīng)用程序調(diào)用的DLL文件都會(huì)在應(yīng)用程序文件加載時(shí)被加載到內(nèi)存,如果采用顯式鏈接方式,程序員就可以決定何時(shí)加載DLL、何時(shí)卸載DLL。例如,應(yīng)用程序可以根據(jù)用戶選擇的語(yǔ)種,加載與之對(duì)應(yīng)的DLL文件,對(duì)于選擇了英語(yǔ)的用戶,加載英語(yǔ)字符串資源DLL,對(duì)于選擇了西班牙語(yǔ)的用戶,則加載西班牙語(yǔ)字符串資源。
Windows遵循下列的次序來(lái)搜索和定位DLL:(1)EXE文件所在目錄(2)進(jìn)程當(dāng)前工作目錄(3)Windows系統(tǒng)目錄(4)Windows目錄(5)列在Path環(huán)境變量中的一系列目錄在使用MFC開(kāi)發(fā)DLL相關(guān)應(yīng)用程序時(shí),對(duì)于初學(xué)者,建議采用隱式鏈接。9.1.6DLL開(kāi)發(fā)舉例
在這個(gè)實(shí)例中,需要開(kāi)發(fā)3個(gè)應(yīng)用程序模塊:(1)S9_1是一個(gè)DLL程序,它導(dǎo)出一個(gè)函數(shù)。(2)S9_2也是一個(gè)DLL程序,它導(dǎo)出一個(gè)類(lèi)。(3)S9_3是一個(gè)客戶應(yīng)用程序,在它里面,調(diào)用了S9_1、S9_2導(dǎo)出的函數(shù)和類(lèi)。在開(kāi)發(fā)過(guò)程中,通過(guò)具體操作對(duì)本章的基本概念和理論進(jìn)行詳細(xì)說(shuō)明,幫助讀者理解和掌握這些概念和技術(shù)。
1.S9_1使用“帶靜態(tài)鏈接MFC規(guī)則的DLL導(dǎo)出函數(shù)(1)用MFCDLL向?qū)?chuàng)建動(dòng)態(tài)鏈接庫(kù)項(xiàng)目S9_1。在VS2010主界面菜單上選擇“文件|新建|項(xiàng)目”菜單項(xiàng),打開(kāi)“新建項(xiàng)目”對(duì)話框,在左側(cè)選擇VisualC++,右側(cè)選擇MFCDLL,項(xiàng)目名稱(chēng)輸入S9_1,點(diǎn)擊“確定”按鈕,彈出“MFCDLL向?qū)А睂?duì)話框,選中“帶靜態(tài)鏈接MFC的規(guī)則DLL”單選框,如圖9-2所示,其余保持默認(rèn),點(diǎn)擊“完成”按鈕,生成MFCDLL應(yīng)用程序框架。
(2)修改所生成項(xiàng)目的頭文件S9_1,加入對(duì)導(dǎo)出函數(shù)的聲明。
(3)修改所生成項(xiàng)目的實(shí)現(xiàn)文件S9_1.cpp,添加導(dǎo)出函數(shù)的實(shí)現(xiàn)。(4)編譯鏈接,生成動(dòng)態(tài)鏈接庫(kù),所生成的DLL文件在后面的S9_3項(xiàng)目中使用。
2.S9_2使用MFC擴(kuò)展DLL導(dǎo)出一個(gè)類(lèi),導(dǎo)出類(lèi)使用AFX_EXT_CLASS宏。(1)利用MFCDLL向?qū)?chuàng)建S9_2動(dòng)態(tài)鏈接庫(kù)項(xiàng)目。(2)設(shè)計(jì)CDrawText類(lèi)。(3)為CDrawText類(lèi)添加成員變量。(4)為CDrawText類(lèi)添加成員函數(shù)。(5)編譯鏈接,生成S9_2.DLL動(dòng)態(tài)鏈接庫(kù),供S9_3應(yīng)用程序使用。3.S9_3項(xiàng)目的創(chuàng)建步驟(1)創(chuàng)建S9_3項(xiàng)目。(2)將當(dāng)前項(xiàng)目所需要的S9_1.dll、S9_2.dll、S9_1.lib、S9_2.lib文件加入進(jìn)來(lái)。(3)添加菜單資源,并添加命令消息響應(yīng)函數(shù)。(4)導(dǎo)入S9_1.dll中的函數(shù)AddFunction()。(5)向S9_3項(xiàng)目導(dǎo)入S9_2.dll中的類(lèi)CDrawText。(6)修改CS9_3Doc類(lèi)的頭文件和C++文件,為使用CDrawText類(lèi)的對(duì)象作準(zhǔn)備。(7)使用從S9_2導(dǎo)出的類(lèi)CDrawText。(8)修改CS9_3View::OnDraw函數(shù)。運(yùn)行界面讀者可以把S9_2.dll的功能擴(kuò)充,在編寫(xiě)程序的同時(shí),要注意DLL的特點(diǎn),只要DLL對(duì)外提供的接口(導(dǎo)出函數(shù)、類(lèi)、數(shù)據(jù)以及供其它程序使用的資源等)保持不變,其內(nèi)部實(shí)現(xiàn)就不會(huì)影響客戶應(yīng)用程序的開(kāi)發(fā)和實(shí)現(xiàn)。9.2編寫(xiě)自己的ActiveX控件9.2.1ActiveX控件的事件、屬性和方法9.2.2ActiveX控件開(kāi)發(fā)實(shí)例9.2.1ActiveX控件的事件、屬性和方法
ActiveX是Microsoft的一個(gè)術(shù)語(yǔ),它指一組包括控件、DLL、ActiveX文檔的組件,通常以動(dòng)態(tài)鏈接庫(kù)的形式存在,ActiveX控件必須提供屬性名、方法名以及參數(shù),以便容器可以存取和改變ActiveX控件的屬性,ActiveX控件的數(shù)據(jù)輸入和函數(shù)調(diào)用必須通過(guò)容器,因此ActiveX控件具備以下特點(diǎn)。1.屬性表示ActiveX控件狀態(tài)的變量。ActiveX控件的屬性有兩種訪問(wèn)方式:使用成員變量和使用Get/Set方法,其屬性又分為2種:固有屬性(Stockproperties):固有屬性是已經(jīng)被COleControl類(lèi)實(shí)現(xiàn)了的屬性,在VS2010中,應(yīng)用向?qū)еС值墓逃袑傩杂校篈ctiveX控件背景色(BackColor)、標(biāo)題(Caption)等,固有屬性是帶有普遍性的一些屬性。自定義屬性(Customproperties):程序員自己定義的屬性,是和具體控件相關(guān)的屬性。例如,如果編寫(xiě)了播放avi文件的控件,則當(dāng)前播放的文件名就是自定義屬性。2.方法:控件容器可以調(diào)用的ActiveX控件方法。其方法分為2種:固有方法:已經(jīng)被COleControl類(lèi)實(shí)現(xiàn)的方法。COleControl類(lèi)支持兩個(gè)固有方法:DoClick方法和Refresh方法,其中,DoClick方法用于發(fā)送一個(gè)Click事件,而Refresh方法則用于立即更新ActiveX控件窗口。自定義方法:程序員自己定義的方法。例如,對(duì)于播放avi文件的控件,Play、Stop等均為自定義方法。3.事件:由ActiveX控件發(fā)送給控件容器的通知消息,ActiveX控件通過(guò)事件告訴控件容器某個(gè)事件發(fā)生了,如屬性參數(shù)改變、用戶單擊、雙擊動(dòng)作等,容器根據(jù)具體事件作出不同的響應(yīng),事件也分為2種:固有事件:已經(jīng)由COleControl定義的事件,共有10種,典型的固有事件如Click事件,該事件為用戶單擊ActiveX控件時(shí)由ActiveX控件發(fā)送的消息,COleControl類(lèi)中還為每個(gè)固有事件提供了一個(gè)發(fā)送事件的函數(shù),這些函數(shù)可用于模擬相應(yīng)的事件。例如,F(xiàn)ireClick()函數(shù)向控件容器發(fā)送Click事件。自定義事件:程序員自己定義的事件。例如,播放avi文件的控件,當(dāng)avi文件播放完畢后向控件容器發(fā)送一個(gè)自定義事件——播放完畢,用于通知控件容器進(jìn)行相應(yīng)處理。9.2.2ActiveX控件開(kāi)發(fā)實(shí)例1.創(chuàng)建項(xiàng)目2.添加固有屬性3.添加自定義屬性
1.創(chuàng)建項(xiàng)目(1)在VS2010中,通過(guò)菜單“文件|新建|項(xiàng)目…”,打開(kāi)“新建項(xiàng)目”對(duì)話框,項(xiàng)目模板選擇“MFCActiveX控件”,“名稱(chēng)”輸入“S9_4”,選擇項(xiàng)目保存位置,如圖9-10所示。
(2)單擊“確定”按鈕,彈出“MFCActiveX控件向?qū)А睂?duì)話框,選擇“控件名稱(chēng)”,可以看到所創(chuàng)建的ActiveX控件的名字為S9_4,如圖9-11所示,讀者也可以修改為有意義的名字,本實(shí)例不做修改,全部采用默認(rèn)值,單擊“完成”按鈕,完成ActiveX項(xiàng)目的創(chuàng)建。1.創(chuàng)建項(xiàng)目
2.添加固有屬性下面給S9_4控件添加設(shè)置背景色和前景色的功能。(1)單擊“調(diào)試|選項(xiàng)和設(shè)置”,彈出“選項(xiàng)”對(duì)話框,如圖9-12所示,選擇“WorkflowDesigner|主題”,單擊“新建”,彈出“ThemeConfiguration”對(duì)話框,如圖9-13所示。(2)選擇屬性BackColor,彈出顏色對(duì)話框,選擇合適的顏色。(3)單擊確定按鈕,返回到“選項(xiàng)”對(duì)話框,為控件增加了一個(gè)背景色屬性。(4)重復(fù)(1)—(3),為控件添加前景色屬性(ForeColor)。
(5)在控件的C++文件S9_4Ctl.cpp中,添加顏色屬性頁(yè)(6)在控件的OnDraw函數(shù)中,添加使用顏色屬性的代碼:
3.添加自定義屬性(1)在VS2010環(huán)境的“類(lèi)視圖”標(biāo)簽中展開(kāi)控件的庫(kù)文件“S9_4Lib”,如圖9-14所示,在“_DS9_4”節(jié)點(diǎn)上按鼠標(biāo)右鍵,打開(kāi)快捷菜單,從中選擇“添加|添加屬性”,打開(kāi)“添加屬性向?qū)А睂?duì)話框,如圖9-15所示,為控件添加一個(gè)TextAlign屬性,類(lèi)型為L(zhǎng)ONG,訪問(wèn)方式為成員變量。(2)單擊“完成”按鈕,返回VS2010主界面。
(3)修改控件的文本對(duì)齊方式的消息響應(yīng)函數(shù)
(4)接下來(lái),需要修改自定義屬性的對(duì)話框資源,在工作區(qū)的“資源視圖”中展開(kāi)對(duì)話框資源,雙擊Dialog|IDD_PROPPAGE_S9_4,打開(kāi)對(duì)話框資源編輯器,刪除原有的StaticText控件,添加3個(gè)單選按鈕和一個(gè)分組框控件,將第一個(gè)單選按鈕的Group屬性設(shè)為T(mén)RUE,其余兩個(gè)設(shè)置為FALSE,也就是將它們?nèi)齻€(gè)分為一組,4.為CS9_4Ctrl類(lèi)添加一些額外變量
(1)在控件的頭文件S9_4Ctl.h中添加以下私有成員變量。
(2)在控件的C++文件S9_4Ctl.cpp中,修改構(gòu)造函數(shù)CS9_4Ctrl::CS9_4Ctrl(),對(duì)以上4個(gè)變量進(jìn)行初始化。(3)修改控件的C++文件S9_4Ctl.cpp的CS9_4Ctrl::OnDraw函數(shù),實(shí)現(xiàn)控件文本信息的輸出。
5.為控件添加鼠標(biāo)移動(dòng)的消息響應(yīng)函數(shù)
在VS2010開(kāi)發(fā)環(huán)境中,通過(guò)類(lèi)向?qū)镃S9_4Ctrl類(lèi)中添加
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 升學(xué)掌舵手模板
- 七夕美食營(yíng)銷(xiāo)策略
- 基礎(chǔ)設(shè)施采購(gòu)分包合同(2篇)
- 揭秘科學(xué)實(shí)驗(yàn)
- 2024版專(zhuān)業(yè)建筑工程協(xié)議模板解析
- 建筑工程安全措施費(fèi)合同
- 2024年未經(jīng)登記房產(chǎn)轉(zhuǎn)讓協(xié)議樣式
- 2024版二手房銷(xiāo)售合同范本3篇
- 電子政務(wù)大數(shù)據(jù)平臺(tái)建設(shè)合同
- 2024年網(wǎng)絡(luò)安全防護(hù)服務(wù)合同服務(wù)內(nèi)容與責(zé)任劃分
- 《屈原列傳》同步練習(xí)(含答案) 高中語(yǔ)文統(tǒng)編版選擇性必修中冊(cè)
- 海南省2023年中考英語(yǔ)科試題及答案
- 如何平衡工作和生活的時(shí)間安排
- 蜜雪冰城新媒體營(yíng)銷(xiāo)策略分析
- 換藥室工作總結(jié)
- 四年級(jí)上冊(cè)數(shù)學(xué)乘法豎式
- 安全生產(chǎn)與環(huán)境保護(hù)通用課件
- 藥品集中采購(gòu)教育培訓(xùn)
- 《攝影入門(mén)基礎(chǔ)知識(shí)》課件
- 門(mén)禁系統(tǒng)施工規(guī)范
- 醫(yī)療器械(耗材)項(xiàng)目投標(biāo)服務(wù)投標(biāo)方案(技術(shù)方案)
評(píng)論
0/150
提交評(píng)論