問題1:純資源DLL是什么?
答:
只包含資源(*.rc 、resource.h 和 主工程Resource Files下面的所有東東 )的DLL。主工程在啟動時通過加載這個純資源DLL來獲得所有的資源。而取代傳統(tǒng)方式的資源在主題工程之內(nèi)的形式,以達到減小主工程的體積(EXE文件大小),并實現(xiàn)模塊化與語言國際化。
問題2:上個問題中的*.rc 、resource.h 和 主工程Resource Files下面的所有東東 是從哪里來的?
答:
所有的一切,都來自與主工程,并且在主工程中移除這些文件(不是刪除),將其加入到純資源DLL工程。
提示:建議當主工程的所有代碼及其功能已經(jīng)固定,或基本完成(即將release)時,再開始制作相應(yīng)的純資源DLL。
補充說明:更深入的研究純資源DLL,跟帖就好了,嘻嘻嘻嘻~ 找一些相關(guān)的資料吧,這里做基礎(chǔ)的講解。
開發(fā)環(huán)境:WINXP\VS2005\CH(中文)
主體工程完成后,開始制作純資源DLL:
------------------------------------------------------------------------------------------
(1)新建一個win32->DLL項目,選擇默認選項創(chuàng)建即可。
(2)一個嶄新的基礎(chǔ)DLL框架就有了。
(3)將主體工程中的(a)"源文件"下的 *.rc 添加到DLL工程的"源文件"下
(b)"頭文件"下的 resource.h 添加到DLL工程的"頭文件"下
(c)"資源文件"下的 所有東東 添加到DLL工程的"資源文件"下
(4)在主體工程中移除上述的文件。(最好不要刪除,以備不時之需?。?/p>
(5)編譯一下DLL工程,理論上是不會出錯的,只要你的主體工程沒有問題。好了,一個純資源DLL就誕生了!開香檳慶祝一下!
(6)這只是一種語言的DLL
(7)把*.rc資源中的所有文字(代碼除外...)改成英文的,然后編譯... 哦也!一個英文版本的DLL產(chǎn)生了!
(8)再翻譯成德文... 一個德文版本的DLL產(chǎn)生了!
(9)... 各種語言版本的DLL產(chǎn)生了... ...
(...)
(n)已經(jīng)麻木了...
提示:建議將不同版本的DLL用不同的名字,并且COPY不同的*.rc版本,根據(jù)需要換著用,不用新建很多DLL工程。因為只有文字不一樣嘛!
-------------------------------------------------------------------------------------------
主體工程修改,以適應(yīng)新的加載資源方式:
-------------------------------------------------------------------------------------------
(1)打開主工程的"類視圖",找到那個APP類(C[你的工程名字]App,例如:CabcApp)。
(2)在InitInstance(void)函數(shù)里面加入如下代碼
//read reg and get selected language EN or CH
HKEY hKey;
DWORD dwType; //注冊表中的值類型(REG_DWORD 、REG_BINARY等等)
DWORD size = sizeof(DWORD); //注冊表中的值的size,單位BYTE(8bit),由于我們這里只用到DWORD值所以大小是sizeof(DWORD).
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, HKEYLANGUAGEPATH, NULL, KEY_ALL_ACCESS, &hKey))
//#define HKEYLANGUAGEPATH "SOFTWARE\\MYPROGRAM" 注冊表鍵路徑
//#define HKEYLANGUAGE "Language" 注冊表鍵值名稱
{//m_language 是在App類中新建的 protected: DWORD m_hDll成員變量
if (ERROR_SUCCESS != RegQueryValueEx(hKey, HKEYLANGUAGE, NULL, &dwtType, (LPBYTE)&m_language, &size))
{
MessageBox(NULL, "Can't read registration information !", NULL, MB_OK);
RegCloseKey(hKey);
return FALSE;
}
RegCloseKey(hKey);
}
else
{
hKey = HKEY_LOCAL_MACHINE;
DWORD nbf = 0;
DWORD size = sizeof(m_language);
if (!LoadLibrary("EnUI.dll")) //EnUI.dll not exist
{
if (!LoadLibrary("ChmUI.dll")) //ChmUI.dll not exist
{
MessageBox(NULL, "Application was damaged, please reinstall !", NULL ,MB_OK);
return FALSE;
}
else
{
m_language = DISPLAY_CHINASE; //DISPLAY_CHINASE DWORD 1
}
}
else
{
m_language = DISPLAY_ENGISH; //DISPLAY_ENGISH DWORD 0
}
FreeLibrary(m_hDll);
//create new reg key
RegCreateKeyEx(hKey, HKEYLANGUAGEPATH, 0, "", REG_OPTION_NON_VOLATILE,
KEY_READ|KEY_WRITE, NULL, &hKey, &nbf);
RegSetValueEx(hKey, HKEYLANGUAGE, 0, REG_DWORD, (LPBYTE)&m_language, size);
}
m_hDll = NULL; //m_hDll是在App類中新建的 protected: HINSTANCE m_hDll成員變量
//here used if..else, you can use switch..case here instead for more different language case.
if (DISPLAY_CHINASE == m_language) //CH
{
m_hDll = LoadLibrary("ChmUI.dll"); //我們剛剛制作的中文版DLL
}
else if (DISPLAY_ENGISH == m_language)//EN
{
m_hDll = LoadLibrary("EnUI.dll"); //我們剛剛制作的英文版DLL
}
if (NULL == m_hDll)
{
MessageBox(NULL, "ChmUI.dll or EnUI.dll not exist !", NULL, MB_OK); //警告信息
return FALSE;
}
else
{
AfxSetResourceHandle(m_hDll);
}
//...若干代碼
FreeLibrary(m_hDll); //此行加在return FALSE之前
至此,DLL已經(jīng)加載成功了!
然后所有的資源都會自動的關(guān)聯(lián)到主程序,萬事大吉??!哦也?。?!
編譯、調(diào)試...
等等...
貌似有些同學(xué)出現(xiàn)問題了,有一部分圖片、圖標沒有加載進來?!
別急,如果你的主工程代碼中有類似:
hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 32, 32, 0);
的代碼時,只要將LoadImage的第一個參數(shù)改成::AfxGetResourceHandle()就可以了,類似的LoadIcon等等,都是如此!
編譯、生成...
再等等... 主工程生成的EXE怎么沒有圖標了?!變成白板了...
現(xiàn)在在已經(jīng)完全移除原有資源的工程里,向"資源文件"中添加圖標資源(EXE圖標),這時會自動生成新的*.rc等等(一般會是*1.rc 、recources1.h),建議把新生成的這些文件改名(比如*.rc -->ProgramIcon.rc 、resources.h-->ProgramIcon.h )。然后更改rc文件里的"#include "resources.h"--->#include "ProgramIcon.h""。當然不改也一樣,只是這樣容易讓人理解。然后在"資源"視圖將剛剛添加的圖標改成"IDR_MAINFRAME"名字(我指的是圖標ID)。
編譯、生成...
于是和以前一樣,什么都正常了~
PS:
別忘了將做好的DLL放進主工程的DEBUG目錄哦~
新添加的rc資源不會與DLL中的資源沖突,放心使用吧!當然也可以繼續(xù)添加比如版本信息等等。
如果發(fā)現(xiàn)"資源視圖"有顯示不正確的現(xiàn)象,關(guān)閉VS,重啟VS就OK了!
OK,再有新的心得時繼續(xù)發(fā)帖!