許多細心的人也許已經注意到,在VC的集成編譯環境 (IDE)中有一個功能,你可以選中一個資源,在上面點擊鼠標右鍵,選擇Insert Copy,選擇一個不同的Condition。然而我用VC十多年,一直沒有用過這個特性,也從來不知道他是干嗎的。前兩天有個網友問我這個東西是干嗎的,才下決心去研究一下。仔細研究之后,才發現他是用于資源DLL的。
?
對于提供國際化解決方案的程序設計者而言,根據用戶地區設置來顯示對應的語言界面,將是非常有意義的。本文的目的是提供一個step by step的建議,讓沒有做過資源dll的人可以從中受益。由于我也沒做過資源dll,研究這個也就半天時間,因此如果有什么錯誤,也很正常。請發現錯誤的朋友直接發郵件給我。對于你的幫助,我將非常感謝。
?
主工程的要求
對于一個需要使用資源dll實現國際化的工程,我們必須保證每個展現給用戶的界面元素都必須從資源里獲得。這主要指得是名目繁多的字符串。程序設計者喜歡用AfxMessageBox顯示信息。在單語言情況下,這當然沒有問題。但是如果是多語言環境,這樣做就很難控制這個顯示信息和當前的區域設置匹配。
?
另外,主工程的設計應該在創建資源dll之前完成。這樣做的原因是,資源dll設計很簡單,花不了多少時間。而如果資源的修改,如果沒有正確反映到代碼上,有時候程序會莫名其妙的崩潰了,而你需要花很長的時間來找到原因。我自己的一個例子是:我在icon中插入了一個65535色的圖片,程序一直起不來,后來找了很久才找到原因。如果我們按照普通方式設計主工程,并經過測試證明他工作正常,此時再做資源dll,就會避免在兩個工程之間調試并找原因。
?
實際上對于增量開發情況,這種資源dll和主工程并存的情況可能難以避免,這時就需要增刪資源特別小心,避免導致錯誤。
?
為了簡化起見,我創建一個缺省的對話框工程來做測試,步驟如下:
- 啟動Microsoft Visual Studio 6.0
- 點擊File, New
- 選擇Microsoft AppWizard(exe)工程,輸入工程名test,點擊OK
- 選擇Dialog Based,并在What language would you like your resources in?下選擇中文(此時選擇自己最喜歡的語言即可,我不熟悉英文,就選擇中文了)
- 點擊Finish創建工程
?創建資源dll工程
我們可以按照下述步驟創建一個資源DLL:
?
- 創建一個普通的WIN32 Dynamic-Link Library(這里取名testdll)
- 把主工程中的所有資源相關的文件(rc,rc2,ico等)加入這個dll工程
- 點擊菜單Build, Configurations,此時,我們應該有Release和Debug兩個配置
- 點擊Add按鈕,以Debug為模板創建DebugEN和DebugCN
- 重復上述步驟,以Release為模板,創建ReleaseEN和ReleaseCN
- 刪除原來的Debug和Release配置,然后點擊Close退出配置對話框
- 按組合鍵ALT+F7彈出Project Settings對話框
- 選擇Resources頁
- 左側選擇All Configurations
- 在Preprocessor Definitions中添加如下宏AFX_RESOURCE_DLL
- 左側選擇Multiple Configurations,選中DebugEN和ReleaseEN
- 重復第10步,輸入AFX_TARG_ENU宏(這是為美國英語而定義的宏English U.S)
- 重復11,12步,為DebugCN和ReleaseCN添加AFX_TARG_CHS宏(這是為簡體中文的宏Chinese Simplified)
- 選擇Link頁,為每個配置指定輸出文件名(我這里分別為testdll_end.dll, testdll_enr.dll, testdll_cnd.dll,testdll_cnr.dll,分別表示英文debug,英文release和中文相關文件)
- 關閉Project Settings對話框
- 選中Resource View
- 在每個資源ID上右擊,選擇Insert Copy,改變Language為English(U.S)
- 如果為同一種語言你還希望提供根據某個自定義的宏而選擇不同的界面(如UI模式和Service模式),在Condition中輸入你用以區分的宏名,如SERVICE_DLL。
- 打開每個新創建的資源,根據自己的需要修改資源(注意:這里只建議修改文字、字體,必須嚴格保證不刪除任何資源)
- 保存修改
- 編譯資源DLL
修改主工程
由于我們打算用資源dll來提供資源信息,我們必須對主工程做如下修改:
- 打開工程
- 選擇File View,刪除rc,rc2,ico等和資源密切相關的文件。resource.h請不要刪除
- 在CWinApp中添加一個私有的HMODULE類型的變量m_hResource
- 在InitInstance函數開頭添加如下代碼:
?LANGID id = ::GetUserDefaultLangID(); ?switch(id) ?{ ?case 0x804://中文 #ifdef _DEBUG ?? m_hResource = LoadLibrary(_T("D:\\projects\\testdll\\DebugCN\\testdllcnd.dll")); #else ?? m_hResource = LoadLibrary(_T("D:\\projects\\testdll\\ReleaseCN\\testdllcnr.dll")); #endif ?? break; default: #ifdef _DEBUG ?? m_hResource = LoadLibrary(_T("D:\\projects\\testdll\\DebugEN\\testdllend.dll")); #else ??m_hResource = LoadLibrary(_T("D:\\projects\\testdll\\ReleaseCN\\testdllenr.dll")); #endif ?} ?if(m_hResource == NULL) ?{ ?? return FALSE; ?}else{ ?? AfxSetResourceHandle((HINSTANCE)m_hResource); ?}
?此后再做一點簡單的調試,應該就可以了。具體調試,就已經超出我這篇文章所能討論的范圍了。
|