日志 最近的項(xiàng)目中用到這個(gè)東西,周末自己研究了一下,雖然網(wǎng)上有相關(guān)的資料,但是對(duì)初學(xué)者還是有點(diǎn)隱晦,不是很明白;避免大家像我一樣走彎路,小小總結(jié)一下:
一般的程序 exe文件中都包含了資源, 舉例: 如飛鴿傳說就只有一個(gè)exe文件; 1,所以 exe 中是包含有資源的! 而我們理解的 Dll有什么什么呢? 2, Dll其實(shí)是令一種"exe"了,簡(jiǎn)單的可以這么理解,所以,我們的目的就是把Exe中這部分要加載資源的任務(wù) 扔給另一個(gè)Dll兄弟去做;好了, 目的明白了,現(xiàn)在開始動(dòng)手! 1, 很簡(jiǎn)單,先建立一個(gè)MFC 程序,簡(jiǎn)單起見 Base Dialog的 Main (工程名); 2, 刪除該工程中的 resource.h main.rc(資源文件);注意,是在VC 工程見面中刪除,并沒有在硬盤資源管理器上刪除,(注意:VC2005刪除的時(shí)候會(huì)提示要 Remove 還是 Delete,當(dāng)然是Remove了); 3, 建立一個(gè)Mfc擴(kuò)展Dll工程,工程名 english; 4, 這一步最重要, 我們的目的是要把Exe的資源轉(zhuǎn)嫁到Dll中,最后用Exe去調(diào)用Dll, 所以,把Dll工程中的resource.h 文件干掉(刪除點(diǎn),并切在硬盤上也刪除點(diǎn)); 把exe工程中的resource.h文件和main.rc文件,Res文件夾中的文件統(tǒng)統(tǒng)Copy到Dll工程對(duì)應(yīng)的位置,并且添加到工程當(dāng)中; 此時(shí)不用多說,大家都明白為何了吧? 5, 編譯Dll工程,得到Dll文件; 6, 在Exe工程的App文件中, A) main.h文件中,注釋點(diǎn)原來的Resource.h ; 改成我們的Dll工程的 resource.h(注意路徑) 添加變量 HINSTANCE m_hResourceDll; B) 在。cpp文件中的InitInstance()中最前面(注意是最前面)添加 m_hResourceDll = AfxLoadLibrary(_T("english.dll")); if( m_hResourceDll ) { AfxSetResourceHandle(m_hResourceDll); } else { return FALSE; } 在ExitInstance()中 添加: AfxFreeLibrary(m_hResourceDll); (干完活了,當(dāng)然要人家休息了不是?) 至于為什么要加, 跟我一起跟入MFC源碼查看究竟: 我們知道, 在Exe工程中,顯示我們主Dialog的代碼為 CMainDlg dlg; m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); 注意這個(gè)DoModal函數(shù),F(xiàn)12, 再“go”, LPCDLGTEMPLATE lpDialogTemplate = m_lpDialogTemplate; HGLOBAL hDialogTemplate = m_hDialogTemplate; HINSTANCE hInst = AfxGetResourceHandle(); if (m_lpszTemplateName != NULL) { hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG); HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG); hDialogTemplate = LoadResource(hInst, hResource); } 這其中最關(guān)鍵的函數(shù): AfxGetResourceHandle();又是做什么呢? _AFXWIN_INLINE HINSTANCE AFXAPI AfxGetResourceHandle() { ASSERT(afxCurrentResourceHandle != NULL); 原來只是取得一個(gè)ResourceHandle而已,所有資源的活水源在這里開始; 既然有Get 肯定有 Set; 所以: 如果我們不想要默認(rèn)的ResourceHandle,想要我們自己做的資源,就要Set一下嘍(在它調(diào)用默認(rèn)的資源前,先偷梁換柱,換成我們的), 這也就是為什么用AfxSetResourceHandle 函數(shù)的原因,也是為什么把我們的代碼放在InitInstance()最前面的原因,準(zhǔn)確的說是在Domal()前面的原因;不知道我解釋清楚沒有,呵呵; 7, 好了,編譯,運(yùn)行; 是不是可以了? 總結(jié): 很簡(jiǎn)單,不是嗎? 就是把資源任務(wù)抽出來,給別人干,別人干完的陳果(Dll文件),我們拿來一用而已;理解這個(gè)概念就明白為什么我們要Delete這個(gè),Add那個(gè)了; 題外話: 在軟件工程中,很多項(xiàng)目要做成這樣,因?yàn)橘Y源是資源,邏輯是邏輯,我們?yōu)榱烁玫牡婉詈希?也為了更好地編寫” 多語言“版本的軟件; 做成這樣是很有必要的;起碼我接觸過的C++項(xiàng)目都是這樣子的; 第一次寫技術(shù)博客,寫的不好,大家多扔磚頭; 轉(zhuǎn)載請(qǐng)表明出處 |
|