




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、Good is good, but better carries it.精益求精,善益求善。VC+動態(tài)鏈接庫編程之MFC擴展DLL-VC+動態(tài)鏈接庫編程之MFC擴展DLL資料引用:/395359.htmlDLL類型入口函數(shù)非MFCDLL編程者提供DllMain函數(shù)MFC規(guī)則DLLCWinApp對象的InitInstance和ExitInstanceMFC擴展DLLMFCDLL向?qū)蒁llMain函數(shù)對于MFC擴展DLL,系統(tǒng)會自動在工程中添加如下表所示的宏,這些宏為DLL和應(yīng)用程序的編寫提供了方便。像AFX_EXT_CLASS、AFX_EXT_API、AFX_EXT_DATA這樣的宏,在DL
2、L和應(yīng)用程序中將具有不同的定義,這取決于_AFXEXT宏是否被定義。這使得在DLL和應(yīng)用程序中,使用統(tǒng)一的一個宏就可以表示出輸出和輸入的不同意思。在DLL中,表示輸出(因為_AFXEXT被定義,通常是在編譯器的標(biāo)識參數(shù)中指定/D_AFXEXT);在應(yīng)用程序中,則表示輸入(_AFXEXT沒有定義)。宏定義AFX_CLASS_IMPORT_declspec(dlleXPort)AFX_API_IMPORT_declspec(dllexport)AFX_DATA_IMPORT_declspec(dllexport)AFX_CLASS_EXPORT_declspec(dllexport)AFX_API
3、_EXPORT_declspec(dllexport)AFX_DATA_EXPORT_declspec(dllexport)AFX_EXT_CLASS#ifdef_AFXEXTAFX_CLASS_EXPORT#elseAFX_CLASS_IMPORTAFX_EXT_API#ifdef_AFXEXTAFX_API_EXPORT#elseAFX_API_IMPORTAFX_EXT_DATA#ifdef_AFXEXTAFX_DATA_EXPORT#elseAFX_DATA_IMPORT6.2MFC擴展DLL導(dǎo)出MFC派生類在這個例子中,我們將產(chǎn)生一個名為“ExtDll”的MFC擴展DLL工程,在這個
4、DLL中導(dǎo)出一個對話框類,這個對話框類派生自MFC類CDialog。使用MFC向?qū)蒑FC擴展DLL時,系統(tǒng)會自動添加如下代碼:staticAFX_EXTENSION_MODULEExtDllDLL=NULL,NULL;externCintAPIENTRYDllMain(HINSTANCEhInstance,DWorddwReason,LPVOIDlPReserved)/RemovethisifyouuselpReservedUNREFERENCED_PARAMETER(lpReserved);/說明:lpReserved是一個被系統(tǒng)所保留的參數(shù),對于隱式鏈接是一個非零值,對于顯式鏈接值是零
5、if(dwReason=DLL_PROCESS_ATTACH)TRACE0(EXTDLL.DLLInitializing!n);/ExtensionDLLone-timeinitializationif(!AfxInitExtensionModule(ExtDllDLL,hInstance)return0;/InsertthisDLLintotheresourcechainnewCDynLinkLibrary(ExtDllDLL);elseif(dwReason=DLL_PROCESS_DETACH)TRACE0(EXTDLL.DLLTerminating!n);/Terminatetheli
6、brarybeforedestrUCtorsarecalledAfxTermExtensionModule(ExtDllDLL);return1;/ok這一段代碼含義晦澀,我們需要對其進行解讀:(1)上述代碼完成MFC擴展DLL的初始化和終止處理;(2)初始化期間所創(chuàng)建的CDynLinkLibrary對象使MFC擴展DLL可以將DLL中的CRuntimeClass對象或資源導(dǎo)出到應(yīng)用程序;(3)AfxInitExtensionModule函數(shù)捕捉模塊的CRuntimeClass結(jié)構(gòu)和在創(chuàng)建CDynLinkLibrary對象時使用的對象工廠(COleObjectFactory對象);(4)Afx
7、TermExtensionModule函數(shù)使MFC得以在每個進程與擴展DLL分離時(進程退出或使用AfxFreeLibrary卸載DLL時)清除擴展DLL;(5)第一條語句staticAFX_EXTENSION_MODULEExtDllDLL=NULL,NULL;定義了一個AFX_EXTENSION_MODULE類的靜態(tài)全局對象,AFX_EXTENSION_MODULE的定義如下:structAFX_EXTENSION_MODULEBOOLbInitialized;HMODULEhModule;HMODULEhResource;CRuntimeClass*pFirstSharedClass;C
8、OleObjectFactory*pFirstSharedFactory;由AFX_EXTENSION_MODULE的定義我們可以更好的理解(2)、(3)、(4)點。在資源編輯器中添加一個如圖15所示的對話框,并使用MFC類向?qū)槠涮砑右粋€對應(yīng)的類CExtDialog,系統(tǒng)自動添加了ExtDialog.h和ExtDialog.cpp兩個頭文件。圖15MFC擴展DLL中的對話框修改ExtDialog.h中CExtDialog類的聲明為:classAFX_EXT_CLASSCExtDialog:publicCDialogpublic:CExtDialog(CWnd*pParent=NULL);en
9、umIDD=IDD_DLL_DIALOG;protected:virtualvoidDoDataExchange(CDataExchange*pDX);DECLARE_MESSAGE_MAP();這其中最主要的改變是我們在classAFX_EXT_CLASSCExtDialog語句中添加了“AFX_EXT_CLASS”宏,則使得DLL中的CExtDialog類被導(dǎo)出。6.3MFC擴展DLL的加載6.3.1隱式加載我們在6.2工程所在的工作區(qū)中添加一個LoadExtDllDlg工程,用于演示MFC擴展DLL的加載。在LoadExtDllDlg工程中添加一個如圖16所示的對話框,這個對話框上包括一
10、個“調(diào)用DLL”按鈕。圖16MFC擴展DLL調(diào)用工程中的對話框在與圖16對應(yīng)對話框類實現(xiàn)文件的頭部添加:/LoadExtDllDlg.cpp:implementationfile/#include.ExtDialog.h#pragmacomment(lib,ExtDll.lib)而“調(diào)用DLL”按鈕的單擊事件的消息處理函數(shù)為:voidCLoadExtDllDlg:OnDllcallButton()CExtDialogextDialog;extDialog.DoModal();當(dāng)我們單擊“調(diào)用DLL”的時候,彈出了如圖15的對話框。為提供給用戶隱式加載(MFC擴展DLL一般使用隱式加載,具體原因
11、見下節(jié)),MFC擴展DLL需要提供三個文件:(1)描述DLL中擴展類的頭文件;(2)與動態(tài)鏈接庫對應(yīng)的.LIB文件;(3)動態(tài)鏈接庫.DLL文件本身。有了這三個文件,應(yīng)用程序的開發(fā)者才可充分利用MFC擴展DLL。6.3.2顯示加載顯示加載MFC擴展DLL應(yīng)使用MFC全局函數(shù)AfxLoadLibrary而不是WIN32API中的LoadLibrary。AfxLoadLibrary最終也調(diào)用了LoadLibrary這個API,但是在調(diào)用之前進行了線程同步的處理。AfxLoadLibrary的函數(shù)原型與LoadLibrary完全相同,為:HINSTANCEAFXAPIAfxLoadLibrary(L
12、PCTSTRlpszModuleName);與之相對應(yīng)的是,MFC應(yīng)用程序應(yīng)使用AfxFreeLibrary而非FreeLibrary卸載MFC擴展DLL。AfxFreeLibrary的函數(shù)原型也與FreeLibrary完全相同,為:BOOLAFXAPIAfxFreeLibrary(HINSTANCEhInstLib);假如我們把上例中的“調(diào)用DLL”按鈕單擊事件的消息處理函數(shù)改為:voidCLoadExtDllDlg:OnDllcallButton()HINSTANCEhDll=AfxLoadLibrary(ExtDll.dll);if(NULL=hDll)AfxMessageBox(MFC
13、擴展DLL動態(tài)加載失敗);return;CExtDialogextDialog;extDialog.DoModal();AfxFreeLibrary(hDll);則工程會出現(xiàn)link錯誤:LoadExtDllDlg.obj:errorLNK2001:unresolvedexternalsymbol_declspec(dllimport)public:virtual_thiscallCExtDialog:CExtDialog(void)(_imp_?1CExtDialogUAEXZ)LoadExtDllDlg.obj:errorLNK2001:unresolvedexternalsymbol_d
14、eclspec(dllimport)public:_thiscallCExtDialog:CExtDialog(classCWnd*)(_imp_?0CExtDialogQAEPAVCWndZ)提示CExtDialog的構(gòu)造函數(shù)和析構(gòu)函數(shù)均無法找到!是的,對于派生MFC類的MFC擴展DLL,當(dāng)我們要在應(yīng)用程序中使用DLL中定義的派生類時,我們不宜使用動態(tài)加載DLL的方法。6.4MFC擴展DLL加載MFC擴展DLL我們可以在MFC擴展DLL中再次使用MFC擴展DLL,但是,由于在兩個DLL中對于AFX_EXT_CLASS、AFX_EXT_API、AFX_EXT_DATA宏的定義都是輸出,這會導(dǎo)致
15、調(diào)用的時候出現(xiàn)問題。我們將會在調(diào)用MFC擴展DLL的DLL中看到link錯誤:errorLNK2001:unresolvedexternalsymbol.因此,在調(diào)用MFC擴展DLL的MFC擴展DLL中,在包含被調(diào)用DLL的頭文件之前,需要臨時重新定義AFX_EXT_CLASS的值。下面的例子顯示了如何實現(xiàn):/臨時改變宏的含義“輸出”為“輸入”#undefAFX_EXT_CLASS#undefAFX_EXT_API#undefAFX_EXT_DATA#defineAFX_EXT_CLASSAFX_CLASS_IMPORT#defineAFX_EXT_APIAFX_API_IMPORT#defi
16、neAFX_EXT_DATAAFX_DATA_IMPORT/包含被調(diào)用MFC擴展DLL的頭文件#includeCalledDLL.h/恢復(fù)宏的含義為輸出#undefAFX_EXT_CLASS#undefAFX_EXT_API#undefAFX_EXT_DATA#defineAFX_EXT_CLASSAFX_CLASS_EXPORT#defineAFX_EXT_APIAFX_API_EXPORT#defineAFX_EXT_DATAAFX_DATA_EXPORT6.5MFC擴展DLL導(dǎo)出函數(shù)和變量MFC擴展DLL導(dǎo)出函數(shù)和變量的方法也十分簡單,下面我們給出一個簡單的例子。我們在MFC向?qū)傻腗
17、FC擴展DLL工程中添加gobal.h和global.cpp兩個文件:/global.h:MFC擴展DLL導(dǎo)出變量和函數(shù)的聲明externCintAFX_EXT_DATAtotal;/導(dǎo)出變量intAFX_EXT_APIadd(intx,inty);/導(dǎo)出函數(shù)/global.cpp:MFC擴展DLL導(dǎo)出變量和函數(shù)定義#includeStdAfx.h#includeglobal.hexternCinttotal;intadd(intx,inty)total=x+y;returntotal;編寫一個簡單的控制臺程序來調(diào)用這個MFC擴展DLL:#include#include單擊此處下載本工程)。我
18、們知道static控件所對應(yīng)的CStatic類不具備設(shè)置背景和文本顏色的接口,這使得我們不能在對話框或其它用戶界面上自由靈活地修改static控件的顏色風(fēng)格,因此我們需要一個提供了SetBackColor和SetTextColor接口的CStatic派生類CMultiColorStatic。這個類的聲明如下:classAFX_EXT_CLASSCMultiColorStatic:publicCStatic/Constructionpublic:CMultiColorStatic();virtualCMultiColorStatic();/Attributesprotected:CStringm
19、_strCaption;COLORREFm_BackColor;COLORREFm_TextColor;/Operationspublic:voidSetTextColor(COLORREFTextColor);voidSetBackColor(COLORREFBackColor);voidSetCaption(CStringstrCaption);/Generatedmessagemapfunctionsprotected:afx_msgvoidOnPaint();DECLARE_MESSAGE_MAP();在這個類的實現(xiàn)文件中,我們需要為它提供WM_PAINT消息的處理函數(shù)(這是因為顏色的
20、設(shè)置依靠于WM_PAINT消息):BEGIN_MESSAGE_MAP(CMultiColorStatic,CStatic)/AFX_MSG_MAP(CMultiColorStatic)ON_WM_PAINT()/為這個類定義WM_PAINT消息處理函數(shù)/AFX_MSG_MAPEND_MESSAGE_MAP()下面是這個類中的重要成員函數(shù):/為CMultiColorStatic類添加“設(shè)置文本顏色”接口voidCMultiColorStatic:SetTextColor(COLORREFTextColor)m_TextColor=TextColor;/設(shè)置文字顏色/為CMultiColorSta
21、tic類添加“設(shè)置背景顏色”接口voidCMultiColorStatic:SetBackColor(COLORREFBackColor)m_BackColor=BackColor;/設(shè)置背景顏色/為CMultiColorStatic類添加“設(shè)置標(biāo)題”接口voidCMultiColorStatic:SetCaption(CStringstrCaption)m_strCaption=strCaption;/重畫Static,顏色和標(biāo)題的設(shè)置都依靠于這個函數(shù)voidCMultiColorStatic:OnPaint()CPaintDCdc(this);/devicecontextforpainti
22、ngCRectrect;GetClientRect(&rect);dc.SetBkColor(m_BackColor);dc.SetBkMode(TRANSPARENT);CFont*pFont=GetParent()-GetFont();/得到父窗體的字體CFont*pOldFont;pOldFont=dc.SelectObject(pFont);/選用父窗體的字體dc.SetTextColor(m_TextColor);/設(shè)置文本顏色dc.DrawText(m_strCaption,&rect,DT_CENTER);/文本在Static中心dc.SelectObject(pOldFont)
23、;為了驗證CMultiColorStatic類,我們制作一個基于對話框的應(yīng)用程序,它包含一個如圖17所示的對話框。該對話框上包括一個static控件和三個按鈕,這三個按鈕可分別把static控件設(shè)置為“紅色”、“藍色”和“綠色”。圖17擴展的CStatic類調(diào)用演示下面看看應(yīng)如何編寫與這個對話框?qū)?yīng)的類。包含這種Static的對話框類的聲明如下:#include.MultiColorStatic.h#pragmacomment(lib,ColorStatic.lib)/CCallDllDlgdialogclassCCallDllDlg:publicCDialogpublic:CCallDllD
24、lg(CWnd*pParent=NULL);/standardconstructorenumIDD=IDD_CALLDLL_DIALOG;CMultiColorStaticm_colorstatic;/包含一個CMultiColorStatic的實例protected:virtualvoidDoDataExchange(CDataExchange*pDX);/DDX/DDVsupportHICONm_hIcon;/Generatedmessagemapfunctions/AFX_MSG(CCallDllDlg)virtualBOOLOnInitDialog();afx_msgvoidOnSys
25、Command(UINTnID,LPARAMlParam);afx_msgvoidOnPaint();afx_msgHCURSOROnQueryDragIcon();afx_msgvoidOnRedButton();afx_msgvoidOnBlueButton();afx_msgvoidOnGreenButton();/AFX_MSGDECLARE_MESSAGE_MAP();下面是這個類中與使用CMultiColorStatic相關(guān)的主要成員函數(shù):voidCCallDllDlg:DoDataExchange(CDataExchange*pDX)CDialog:DoDataExchange(pDX);/AFX_DATA_MAP(CCallDllDlg)DDX_Control(pDX,IDC_C
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 漁船出售協(xié)議書范本
- 終止招標(biāo)代理協(xié)議書
- 商鋪租憑賠償協(xié)議書
- 退休人員應(yīng)聘協(xié)議書
- 設(shè)備借用清償協(xié)議書
- 買賣轉(zhuǎn)讓協(xié)議書范本
- 學(xué)校采購樹苗協(xié)議書
- 遠程監(jiān)控資料協(xié)議書
- 傭金利潤分成協(xié)議書
- 老人抱養(yǎng)協(xié)議書模板
- 礦石采購合同范本
- 2024年甘肅省煙草專賣局招聘考試真題
- 2025年龍江森工集團權(quán)屬林業(yè)局有限公司招聘筆試參考題庫含答案解析
- (二模)溫州市2025屆高三第二次適應(yīng)性考試英語試卷(含答案)+聽力音頻+聽力原文
- DeepSeek+AI組合精準賦能教師教學(xué)能力進階實戰(zhàn) 課件 (圖片版)
- 2025年纖維檢驗員(高級)職業(yè)技能鑒定參考試題庫(含答案)
- 調(diào)試報告-交換機
- 屋面防水施工技術(shù)PPT (2020,44P)
- 鐵路隧道出口支護、仰拱、防排水首件評估監(jiān)理總結(jié)
- 關(guān)于無行賄犯罪行為記錄的承諾書
- 防城港職業(yè)技術(shù)學(xué)院籌設(shè)實施方案
評論
0/150
提交評論