国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
在DLL中使用資源(二)

 在DLL中使用資源(二)收藏

新一篇: 在DLL中使用資源(一) | 舊一篇: 在DLL中使用資源(一)

2、動(dòng)態(tài)鏈接到MFCDLL

       在討論關(guān)于動(dòng)態(tài)鏈接到MFCDLL的模塊狀態(tài)問(wèn)題之前,先來(lái)看一個(gè)例子。本例可以通過(guò)如下步驟來(lái)完成:

 

1)在VC菜單中File->New新建一個(gè)命名為DLLSharedMFC AppWizard的工程,下一步選擇Regular DLL using shared MFC DLL

 

2)在工程中添加一個(gè)對(duì)話框資源,其ID為:IDD_ABOUTBOX。并在resource.h之中將IDD_ABOUTBOX 的數(shù)值改為100。

 

3)在DLLShared.cpp中定義如下函數(shù):

 

void ShowDlg()

{

       CDialog dlg(IDD_ABOUTBOX);

       dlg.DoModal();

}

 

4)在DLLShared.def文件中的EXPORTS語(yǔ)句中添加一行:ShowDlg,以導(dǎo)出ShowDlg函數(shù)。

 

5)編譯生成DLLShared.dllDLLShared.lib。

 

繼續(xù)使用上面的Use工程,將前面生成的DLLShared.dllDLLShared.lib兩個(gè)文件復(fù)制到工程的Debug目錄內(nèi),并將

 

extern "C" __declspec(dllexport) void ShowDlg();

#pragma comment(lib,"debug/DLLStatic")

 

這兩行改為:

 

void ShowDlg();

#pragma comment(lib,"debug/DLLShared")

 

編譯并運(yùn)行Use.exe。點(diǎn)擊按鈕,這次你看到了什么?對(duì),沒(méi)錯(cuò),這次彈出的是Use.exe的關(guān)于對(duì)話框。將上述例子的DLL類(lèi)型換成MFC Extension DLL(using shared MFC DLL)也會(huì)出現(xiàn)相同的問(wèn)題。

 

為什么會(huì)出現(xiàn)上面的問(wèn)題?這是因?yàn)樵谑褂昧?/span>MFC共享庫(kù)的時(shí)候,默認(rèn)情況下,MFC使用主應(yīng)用程序的資源句柄來(lái)加載資源模板。雖然我們調(diào)用的是DLL中的函數(shù)來(lái)顯示DLL中的對(duì)話框,并且對(duì)應(yīng)的對(duì)話框模板是存儲(chǔ)在DLL中的,但MFC仍舊在主應(yīng)用程序也就是Use.exe中尋找相應(yīng)的對(duì)話框模板。由于在DLL中所定義的對(duì)話框資源ID與主應(yīng)用程序中所定義的關(guān)于對(duì)話框的資源ID相同,所以MFC就把主應(yīng)用程序中的關(guān)于對(duì)話框顯示了出來(lái)。如果二者不同,則MFC就認(rèn)為DLL中所定義的對(duì)話框資源不存在,dlg.DoModal會(huì)返回0,也就是什么都不會(huì)顯示。

 

那么如何解決上述問(wèn)題呢?解決辦法就是在適當(dāng)?shù)臅r(shí)候進(jìn)行模塊狀態(tài)切換,以保證具有當(dāng)前狀態(tài)的模塊是我們所需要的模塊從而使用正確的資源。MFC提供了下列函數(shù)和宏來(lái)完成這些工作:

 

AfxGetStaticModuleState:這是一個(gè)函數(shù),其函數(shù)原型為:

 

AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState( );

 

此函數(shù)在堆棧上構(gòu)造AFX_MODULE_STATE類(lèi)的實(shí)例pModuleState并對(duì)其賦值后將其返回。在AFX_MODULE_STATE類(lèi)的構(gòu)造函數(shù)中,該類(lèi)獲取指向當(dāng)前模塊狀態(tài)的指針并將其存儲(chǔ)在成員變量中,然后將pModuleState設(shè)置為新的有效模塊狀態(tài)。在它的析構(gòu)函數(shù)中,該類(lèi)將存儲(chǔ)在其成員變量中的指針還原為存貯的前一個(gè)模塊狀態(tài)。

 

AFX_MANAGE_STATE:這是一個(gè)宏,其原型為:

 

AFX_MANAGE_STATE( AFX_MODULE_STATE* pModuleState )

 

該宏用于將pModuleState(指向包含模塊全局?jǐn)?shù)據(jù)也就是模塊狀態(tài)的AFX_MODULE_STATE結(jié)構(gòu)的指針)設(shè)置為當(dāng)前的即時(shí)作用空間中(the remainder of the immediate containing scope的有效模塊狀態(tài)。在離開(kāi)包含該宏的作用空間時(shí),前一個(gè)有效的模塊狀態(tài)自動(dòng)還原。

 

AfxGetResourceHandle:這個(gè)函數(shù)的原型為:

 

       HINSTANCE AfxGetResourceHandle( );

 

       該函數(shù)返回了一個(gè)保存了HINSTANCE類(lèi)型的、應(yīng)用程序默認(rèn)所加載資源的模塊的句柄。

 

AfxSetResourceHandle:這個(gè)函數(shù)的原型為:

 

void AfxSetResourceHandle( HINSTANCE hInstResource );

 

該函數(shù)將hInstResource所代表的模塊設(shè)置為具有當(dāng)前狀態(tài)的模塊。

 

通過(guò)使用上述四個(gè)函數(shù)或宏就可以正確的在動(dòng)態(tài)鏈接到MFCDLL中切換模塊狀態(tài)。接下來(lái)我們將通過(guò)修改上面出現(xiàn)問(wèn)題的那個(gè)例子來(lái)介紹如何使用上述四個(gè)函數(shù)或宏。先來(lái)看看Regular DLL using shared MFC DLL類(lèi)型:

 

在上述例子的第三步的ShowDlg函數(shù)的第一條語(yǔ)句前加上如下語(yǔ)句(要確保該語(yǔ)句在函數(shù)實(shí)現(xiàn)的第一行):

 

AFX_MANAGE_STATE(AfxGetStaticModuleState());

 

之后重新編譯生成DLLShared.dllDLLShared.lib,并將這兩個(gè)文件重新拷貝到Use工程的Debug目錄內(nèi)。這次編譯生成Use.exe并運(yùn)行,點(diǎn)擊按鈕,可以看到彈出的時(shí)我們?cè)?/span>DLL中所加入的那個(gè)對(duì)話框,而不再是Use.exe的關(guān)于對(duì)話框了。

 

通過(guò)上面的講解,相信你已經(jīng)知道該語(yǔ)句的作用了。在函數(shù)ShowDlg的第一行加上這么一句后,每次調(diào)用DLL的應(yīng)用程序使用該函數(shù)的時(shí)候,MFC庫(kù)都會(huì)自動(dòng)切換當(dāng)前模塊狀態(tài),這樣就保證了資源讀取的正確性。

 

AFX_MANAGE_STATE(AfxGetStaticModuleState());是自動(dòng)切換當(dāng)前模塊狀態(tài),也可以通過(guò)使用AfxGetResourceHandleAfxSetResourceHandle來(lái)手動(dòng)切換當(dāng)前模塊狀態(tài)。具體使用方法如下:

 

在上述例子的第三步的ShowDlg函數(shù)的第一條語(yǔ)句前加上如下語(yǔ)句(要確保該語(yǔ)句在函數(shù)實(shí)現(xiàn)的第一行):

 

HINSTANCE save_hInstance = AfxGetResourceHandle();

       AfxSetResourceHandle(theApp.m_hInstance);

 

在調(diào)用對(duì)話框成功之后,也就是dlg.DoModal();之后,添加:

 

AfxSetResourceHandle(save_hInstance);

 

       這種方法在進(jìn)入ShowDlg函數(shù)之后,通過(guò)AfxGetResourceHandle來(lái)獲得并保存當(dāng)前狀態(tài)模塊的句柄。然后獲得DLL模塊的句柄theApp.m_hInstance(當(dāng)然,也可以使用GetModuleHandle函數(shù)來(lái)獲得DLL模塊的句柄),并使用AfxSetResourceHandle函數(shù)來(lái)將其設(shè)置為當(dāng)前狀態(tài)狀態(tài)。最后在調(diào)用對(duì)話框成功之后再用恢復(fù)AfxSetResourceHandle資源句柄,將當(dāng)前模塊狀態(tài)恢復(fù)。

 

       這樣做有些麻煩,但是有一點(diǎn)好處是可以在完成使用資源的任務(wù)之后就可以立即恢復(fù)資源句柄。而AFX_MANAGE_STATE(AfxGetStaticModuleState());的方法只能等函數(shù)的作用空間結(jié)束之后才恢復(fù)資源句柄。由于可執(zhí)行文件必須重畫(huà)工具條等原因,因此建議只要有可能就必須恢復(fù)資源句柄,否則可能會(huì)遇到許多問(wèn)題。比如說(shuō),如果用戶移動(dòng)DLL的對(duì)話框,而此時(shí)資源句柄仍然為DLL的資源,那么程序就會(huì)崩潰。最好的恢復(fù)句柄的時(shí)機(jī)在對(duì)話框響應(yīng)WM_INITDIALOG消息的時(shí)候,因?yàn)檫@時(shí)對(duì)話框的模板等已經(jīng)讀出了。

 

       對(duì)于MFC Extension DLL(using shared MFC DLL)類(lèi)型的MFC DLL,切換當(dāng)前模塊狀態(tài)的方法與Regular DLL using shared MFC DLL類(lèi)型的MFC DLL所使用的方法很相似,這里不再舉例實(shí)現(xiàn)。二者不同的地方如下:

 

       MFC擴(kuò)展DLL中使用AFX_MANAGE_STATE(AfxGetStaticModuleState());時(shí),會(huì)產(chǎn)生如下錯(cuò)誤:

 

mfcs42d.lib(dllmodul.obj) : error LNK2005: __pRawDllMain already defined in dllextend.obj

mfcs42d.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in dllextend.obj

mfcs42d.lib(dllmodul.obj) : error LNK2005: __pRawDllMain already defined in dllextend.obj

 

因此在MFC擴(kuò)展DLL中需要將AFX_MANAGE_STATE(AfxGetStaticModuleState());換成AFX_MANAGE_STATE(AfxGetAppModuleState());才能正確切換當(dāng)前模塊狀態(tài)。

 

MFC擴(kuò)展DLL中使用AfxGetResourceHandleAfxSetResourceHandle的方法與在Regular DLL using shared MFC DLL類(lèi)型的MFC DLL中所使用的方法相同。并且,DLL模塊的句柄可以通過(guò)MFC提供的DlgextentDLL這個(gè)結(jié)構(gòu)的hModule成員來(lái)獲得。即使用AfxSetResourceHandle(DlgextentDLL.hModule);語(yǔ)句。

 

當(dāng)然,對(duì)于動(dòng)態(tài)鏈接到MFCDLL,也可以在調(diào)用該DLLMFC應(yīng)用程序中使用AfxGetResourceHandleAfxSetResourceHandle兩個(gè)函數(shù)來(lái)切換當(dāng)前狀態(tài)模塊。該DLL模塊的句柄可以用GetModuleHandle函數(shù)來(lái)獲得。在此不再贅述。

 

連載:在DLL中使用資源(一)

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
VC++動(dòng)態(tài)鏈接庫(kù)編程之MFC規(guī)則DLL
第九章 MFC的狀態(tài)
AFX
WINDOWS動(dòng)態(tài)鏈接庫(kù)
使用 DEF 文件從 DLL 導(dǎo)出
DLL(Dynamic Link Libraries)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服