




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、第4節(jié)我們對非MFC DLL進行了介紹,這一節(jié)將詳細地講述MFC規(guī)則DLL的創(chuàng)建與使用技巧。另外,自從本文開始連載后,收到了一些讀者的e-mail。有的讀者提出了一些問題,筆者將在本文的最后一次連載中選取其中的典型問題進行解答。由于時間的關(guān)系,對于讀者朋友的來信,筆者暫時不能一一回復(fù),還望海涵!由于筆者的水平有限,文中難免有錯誤和紕漏,也熱誠歡迎讀者朋友不吝指正!5. MFC規(guī)則DLL5.1 概述MFC規(guī)則DLL的概念體現(xiàn)在兩方面:(1) 它是MFC的“是MFC的”意味著可以在這種DLL的內(nèi)部使用MFC;(2) 它是規(guī)則的“是規(guī)則的”意味著它不同于MFC擴展DLL,在MFC規(guī)則DLL的內(nèi)部雖然
2、可以使用MFC,但是其與應(yīng)用程序的接口不能是MFC。而MFC擴展DLL與應(yīng)用程序的接口可以是MFC,可以從MFC擴展DLL中導(dǎo)出一個MFC類的派生類。Regular DLL能夠被所有支持DLL技術(shù)的語言所編寫的應(yīng)用程序調(diào)用,當然也包括使用MFC的應(yīng)用程序。在這種動態(tài)連接庫中,包含一個從CWinApp繼承下來的類,DllMain函數(shù)則由MFC自動提供。Regular DLL分為兩類:(1)靜態(tài)鏈接到MFC 的規(guī)則DLL靜態(tài)鏈接到MFC的規(guī)則DLL與MFC庫(包括MFC擴展 DLL)靜態(tài)鏈接,將MFC庫的代碼直接生成在.dll文件中。在調(diào)用這種DLL的接口時,MFC使用DLL的資源。因此,在靜態(tài)鏈
3、接到MFC 的規(guī)則DLL中不需要進行模塊狀態(tài)的切換。使用這種方法生成的規(guī)則DLL其程序較大,也可能包含重復(fù)的代碼。(2)動態(tài)鏈接到MFC 的規(guī)則DLL動態(tài)鏈接到MFC 的規(guī)則DLL 可以和使用它的可執(zhí)行文件同時動態(tài)鏈接到 MFC DLL 和任何MFC擴展 DLL。在使用了MFC共享庫的時候,默認情況下,MFC使用主應(yīng)用程序的資源句柄來加載資源模板。這樣,當DLL和應(yīng)用程序中存在相同ID的資源時(即所謂的資源重復(fù)問題),系統(tǒng)可能不能獲得正確的資源。因此,對于共享MFC DLL的規(guī)則DLL,我們必須進行模塊切換以使得MFC能夠找到正確的資源模板。我們可以在Visual C+中設(shè)置MFC規(guī)則DLL是
4、靜態(tài)鏈接到MFC DLL還是動態(tài)鏈接到MFC DLL。如圖8,依次選擇Visual C+的project - Settings - General菜單或選項,在Microsoft Foundation Classes中進行設(shè)置。圖8 設(shè)置動態(tài)/靜態(tài)鏈接MFC DLL5.2 MFC規(guī)則DLL的創(chuàng)建我們來一步步講述使用MFC向?qū)?chuàng)建MFC規(guī)則DLL的過程,首先新建一個project,如圖9,選擇project的類型為MFC AppWizard(dll)。點擊OK進入如圖10所示的對話框。圖9 MFC DLL工程的創(chuàng)建圖10所示對話框中的1區(qū)選擇MFC DLL的類別。2區(qū)選擇是否支持automati
5、on(自動化)技術(shù), automation 允許用戶在一個應(yīng)用程序中操縱另外一個應(yīng)用程序或組件。例如,我們可以在應(yīng)用程序中利用 Microsoft Word 或Microsoft Excel的工具,而這種使用對用戶而言是透明的。自動化技術(shù)可以大大簡化和加快應(yīng)用程序的開發(fā)。3區(qū)選擇是否支持Windows Sockets,當選擇此項目時,應(yīng)用程序能在 TCP/IP 網(wǎng)絡(luò)上進行通信。 CWinApp派生類的InitInstance成員函數(shù)會初始化通訊端的支持,同時工程中的StdAfx.h文件會自動include 頭文件。添加socket通訊支持后的InitInstance成員函數(shù)如下:4區(qū)選擇是否由
6、MFC向?qū)ё詣釉谠创a中添加注釋,一般我們選擇“Yes,please”。圖10 MFC DLL的創(chuàng)建選項5.3 一個簡單的MFC規(guī)則DLL這個DLL的例子(屬于靜態(tài)鏈接到MFC 的規(guī)則DLL)中提供了一個如圖11所示的對話框。圖11 MFC規(guī)則DLL例子在DLL中添加對話框的方式與在MFC應(yīng)用程序中是一樣的。在圖11所示DLL中的對話框的Hello按鈕上點擊時將MessageBox一個“Hello,pconline的網(wǎng)友”對話框,下面是相關(guān)的文件及源代碼,其中刪除了MFC向?qū)ё詣由傻慕^大多數(shù)注釋(下載本工程附件):第一組文件:CWinApp繼承類的聲明與實現(xiàn)分析:在這一組文件中定義了一個繼承
7、自CWinApp的類CRegularDllApp,并同時定義了其的一個實例theApp。乍一看,您會以為它是一個MFC應(yīng)用程序,因為MFC應(yīng)用程序也包含這樣的在工程名后添加“App”組成類名的類(并繼承自CWinApp類),也定義了這個類的一個全局實例theApp。我們知道,在MFC應(yīng)用程序中CWinApp取代了SDK程序中WinMain的地位,SDK程序WinMain所完成的工作由CWinApp的三個函數(shù)完成:但是MFC規(guī)則DLL并不是MFC應(yīng)用程序,它所繼承自CWinApp的類不包含消息循環(huán)。這是因為,MFC規(guī)則DLL不包含CWinApp:Run機制,主消息泵仍然由應(yīng)用程序擁有。如果DLL
8、 生成無模式對話框或有自己的主框架窗口,則應(yīng)用程序的主消息泵必須調(diào)用從DLL 導(dǎo)出的函數(shù)來調(diào)用PreTranslateMessage成員函數(shù)。另外,MFC規(guī)則DLL與MFC 應(yīng)用程序中一樣,需要將所有 DLL中元素的初始化放到InitInstance 成員函數(shù)中。第二組文件 自定義對話框類聲明及實現(xiàn)(點擊查看附件)分析:這一部分的編程與一般的應(yīng)用程序根本沒有什么不同,我們照樣可以利用MFC類向?qū)碜詣訛閷υ捒蛏系目丶砑邮录?。MFC類向?qū)д諛訒深愃芆N_BN_CLICKED(IDC_HELLO_BUTTON, OnHelloButton)的消息映射宏。第三組文件 DLL中的資源文件分析:在
9、MFC規(guī)則DLL中使用資源也與在MFC應(yīng)用程序中使用資源沒有什么不同,我們照樣可以用Visual C+的資源編輯工具進行資源的添加、刪除和屬性的更改。第四組文件 MFC規(guī)則DLL接口函數(shù)分析:這個接口并不使用MFC,但是在其中卻可以調(diào)用MFC擴展類CdllDialog的函數(shù),這體現(xiàn)了“規(guī)則”的概類。與非MFC DLL完全相同,我們可以使用_declspec(dllexport)聲明或在.def中引出的方式導(dǎo)出MFC規(guī)則DLL中的接口。5.4 MFC規(guī)則DLL的調(diào)用筆者編寫了如圖12的對話框MFC程序(下載本工程附件)來調(diào)用5.3節(jié)的MFC規(guī)則DLL,在這個程序的對話框上點擊“調(diào)用DLL”按鈕時
10、彈出5.3節(jié)MFC規(guī)則DLL中的對話框。圖12 MFC規(guī)則DLL的調(diào)用例子下面是“調(diào)用DLL”按鈕單擊事件的消息處理函數(shù):上述例子中給出的是顯示調(diào)用的方式,可以看出,其調(diào)用方式與第4節(jié)中非MFC DLL的調(diào)用方式?jīng)]有什么不同。我們照樣可以在EXE程序中隱式調(diào)用MFC規(guī)則DLL,只需要將DLL工程生成的.lib文件和.dll文件拷入當前工程所在的目錄,并在RegularDllCallDlg.cpp文件(圖12所示對話框類的實現(xiàn)文件)的頂部添加:并將void CRegularDllCallDlg:OnCalldllButton() 改為:5.5 共享MFC DLL的規(guī)則DLL的模塊切換應(yīng)用程序進程
11、本身及其調(diào)用的每個DLL模塊都具有一個全局唯一的HINSTANCE句柄,它們代表了DLL或EXE模塊在進程虛擬空間中的起始地址。進程本身的模塊句柄一般為0x400000,而DLL模塊的缺省句柄為0x10000000。如果程序同時加載了多個DLL,則每個DLL模塊都會有不同的HINSTANCE。應(yīng)用程序在加載DLL時對其進行了重定位。 共享MFC DLL(或MFC擴展DLL)的規(guī)則DLL涉及到HINSTANCE句柄問題,HINSTANCE句柄對于加載資源特別重要。EXE和DLL都有其自己的資源,而且這些資源的ID可能重復(fù),應(yīng)用程序需要通過資源模塊的切換來找到正確的資源。如果應(yīng)用程序需要來自于DL
12、L的資源,就應(yīng)將資源模塊句柄指定為DLL的模塊句柄;如果需要EXE文件中包含的資源,就應(yīng)將資源模塊句柄指定為EXE的模塊句柄。這次我們創(chuàng)建一個動態(tài)鏈接到MFC DLL的規(guī)則DLL(下載本工程附件),在其中包含如圖13的對話框。圖13 DLL中的對話框另外,在與這個DLL相同的工作區(qū)中生成一個基于對話框的MFC程序,其對話框與圖12完全一樣。但是在此工程中我們另外添加了一個如圖14的對話框。圖14 EXE中的對話框圖13和圖14中的對話框除了caption不同(以示區(qū)別)以外,其它的都相同。尤其值得特別注意,在DLL和EXE中我們對圖13和圖14的對話框使用了相同的資源ID=2000,在DLL和
13、EXE工程的resource.h中分別有如下的宏:與5.3節(jié)靜態(tài)鏈接MFC DLL的規(guī)則DLL相同,我們還是在規(guī)則DLL中定義接口函數(shù)ShowDlg,原型如下:而為應(yīng)用工程主對話框的“調(diào)用DLL”的單擊事件添加如下消息處理函數(shù):我們以為單擊“調(diào)用DLL”會彈出如圖13所示DLL中的對話框,可是可怕的事情發(fā)生了,我們看到是圖14所示EXE中的對話框!驚訝?產(chǎn)生這個問題的根源在于應(yīng)用程序與MFC規(guī)則DLL共享MFC DLL(或MFC擴展DLL)的程序總是默認使用EXE的資源,我們必須進行資源模塊句柄的切換,其實現(xiàn)方法有三:方法一 在DLL接口函數(shù)中使用:我們將DLL中的接口函數(shù)ShowDlg改為:
14、這次我們再點擊EXE程序中的“調(diào)用DLL”按鈕,彈出的是DLL中的如圖13的對話框!嘿嘿,彈出了正確的對話框資源。AfxGetStaticModuleState是一個函數(shù),其原型為:該函數(shù)的功能是在棧上(這意味著其作用域是局部的)創(chuàng)建一個AFX_MODULE_STATE類(模塊全局數(shù)據(jù)也就是模塊狀態(tài))的實例,對其進行設(shè)置,并將其指針pModuleState返回。AFX_MODULE_STATE類的原型如下:AFX_MODULE_STATE類利用其構(gòu)造函數(shù)和析構(gòu)函數(shù)進行存儲模塊狀態(tài)現(xiàn)場及恢復(fù)現(xiàn)場的工作,類似匯編中call指令對pc指針和sp寄存器的保存與恢復(fù)、中斷服務(wù)程序的中斷現(xiàn)場壓棧與恢復(fù)以及
15、操作系統(tǒng)線程調(diào)度的任務(wù)控制塊保存與恢復(fù)。許多看似不著邊際的知識點居然有驚人的相似!AFX_MANAGE_STATE是一個宏,其原型為: 該宏用于將pModuleState設(shè)置為當前的有效模塊狀態(tài)。當離開該宏的作用域時(也就離開了pModuleState所指向棧上對象的作用域),先前的模塊狀態(tài)將由AFX_MODULE_STATE的析構(gòu)函數(shù)恢復(fù)。方法二 在DLL接口函數(shù)中使用:AfxGetResourceHandle用于獲取當前資源模塊句柄,而AfxSetResourceHandle則用于設(shè)置程序目前要使用的資源模塊句柄。我們將DLL中的接口函數(shù)ShowDlg改為:通過AfxGetResourceHandle和AfxSetResourceHandle的合理變更,我們能夠靈活地設(shè)置程序的資源模塊句柄,而方法一則只能在DLL接口函數(shù)退出的時候才會恢復(fù)模塊句柄。方法二則不同,如果將ShowDlg改為:在應(yīng)用程序主對話框的“調(diào)用DLL”按鈕上點擊,將看到兩個對話框,相繼為DLL中的對話框(圖13)和EXE中的對話框(圖14)。方法三 由應(yīng)用程序自身切換資源模塊的切換除了可以由DLL接口函數(shù)完成以外,由應(yīng)用程序自身也能完成(下載本工程附件)?,F(xiàn)在我們把DLL中的接口函數(shù)改為最簡單的:而將應(yīng)用程序的OnCalldllButton函數(shù)改為:方法三中的Win32函數(shù)GetModuleHandle
溫馨提示
- 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)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 企業(yè)培訓(xùn)課件制作指南
- 油氣管線不動火機械冷切割方案
- 企業(yè)培訓(xùn)總結(jié)課件
- 優(yōu)化維護服務(wù)策略
- 信息技術(shù)采購合同知識產(chǎn)權(quán)保護與技術(shù)創(chuàng)新條款
- 生態(tài)停車場投資建設(shè)與運營管理合同
- 餐飲行業(yè)特色飲品技術(shù)與品牌合作協(xié)議
- 餐飲連鎖品牌跨區(qū)域經(jīng)營股份合作協(xié)議
- 礦業(yè)開發(fā)項目股權(quán)交割與收益分成協(xié)議
- 車輛掛靠與汽車租賃平臺運營合同
- 2024普通高中物理課程標準解讀
- 精神分裂癥護理查房
- 建筑物聯(lián)網(wǎng)工程綜合實訓(xùn) 課件 第1-3章 物聯(lián)網(wǎng)技術(shù)導(dǎo)論、物聯(lián)網(wǎng)領(lǐng)域的關(guān)鍵技術(shù)、智能建造工程場景中的物聯(lián)網(wǎng)
- 初中數(shù)學(xué)中心對稱圖形訓(xùn)練50題(含參考答案)
- 大中小學(xué)思政課內(nèi)容一體化研究
- 下半年消防演練總結(jié)
- 乒乓球循環(huán)賽積分表決賽
- 奧妥珠單抗注射液
- 市政工程質(zhì)量創(chuàng)優(yōu)計劃
- 服務(wù)質(zhì)量分析會
- 2023學(xué)年完整公開課版《法律的特征》
評論
0/150
提交評論