用VC資源動態鏈接庫解決國際化問題

發表于:2007-07-14來源:作者:點擊數: 標簽:
陳峰 隨著計算機應用的普及,應用軟件跨國使用越來越頻繁,如何實現應用軟件的國際化,成為許多 程序員 關心的問題。這種國際化問題相對使用某一種語言的用戶來說,就是 本地化 問題。本地化的含義比僅僅翻譯菜單欄和對話框的文本內容要廣泛得多,如特定文化
陳峰  

隨著計算機應用的普及,應用軟件跨國使用越來越頻繁,如何實現應用軟件的國際化,成為許多程序員關心的問題。這種國際化問題相對使用某一種語言的用戶來說,就是本地化問題。本地化的含義比僅僅翻譯菜單欄和對話框的文本內容要廣泛得多,如特定文化背景的位圖和圖標對不同的人來說,可能會有不同的含義。在Windows系統中,應用程序開發者可以通過利用VC動態鏈接庫,只用一套源代碼就能簡潔地支持多種文字。本文介紹用VC的資源動態鏈接庫解決國際化問題的具體方法和步驟。
實現技術
利用VC編程,可以把所有的可見資源封裝在一個資源動態鏈接庫中,以簡化本地化工作。一般情況下,資源包含在應用程序中,但也可以通過調用AfxSetResourceHandle函數指向一個不同的單元以完成資源的引用。本文例程就是首先調用該函數從動態鏈接庫中采集到所有的應用程序可用資源,然后通過調用GetSystemDefaultLangID函數判斷系統默認語種,以載入不同語種的資源動態鏈接庫實現界面與系統的自動適應。
為說明清楚,本文創建了一個默認語種為簡體中文的Languages應用程序。該程序不含任何資源,應用程序根據系統的語種設置連接對應的資源鏈接庫,以完成對中文和英文兩種語言的支持。
實現步驟
1.創建Languages執行體
首先,用MFC AppWizad(exe)創建新項目的工作區,選擇Simple Document類型、中國中文(其他的選項選擇缺省),并且為了明確,將工作區目錄改為“多語種支持”。
2.添加數據成員
由于要動態地裝入資源鏈接庫,所以需要保存鏈接庫的句柄以便在程序結束的時候釋放資源。將下述數據成員添加到CLanguagesApp類中:
protected:
//資源鏈接庫句柄
HINSTANCE m_hLangDLL;  
3.修改InitInstance函數
應用程序需要判別系統的缺省語種,并裝入對應的資源鏈接庫。將下面的代碼加到InitInstance函數中:
BOOL CLanguagesApp::InitInstance()
{
 AfxEnableControlContainer();
 // 判定系統缺省語種
 WORD wLangPID=PRIMARYLANGID(::GetSystemDefaultLangID());
 // 載入資源動態鏈接庫
 switch( wLangPID )
 {
  case LANG_CHINESE:
  m_hLangDLL=::LoadLibrary(“chinese.dll”);
    break ;
  default:
   m_hLangDLL=::LoadLibrary(“english.dll”);
break;
}
if( !m_hLangDLL)
{
 AfxMessageBox(_T(“無法裝載資源鏈接庫!”)) ;
  return FALSE ;
}
// 連接資源
 AfxSetResourceHandle(m_hLangDLL) ;
……
}
其中,操作系統所使用的默認語種由Win 32函數GetSystemDefaultLangID取得。宏PRIMARYLANGID取出主語言標識符進行判斷,以正確選擇應該調用的鏈接庫。鏈接庫的加載由Win 32函數LoadLibrary實現。程序中所使用的資源庫由AfxSetResourceHandle函數指定。
4.處理ExitInstance函數
程序退出時使用Win 32函數FreeLibrary卸載已經裝入的動態鏈接庫。將下列代碼添加到ExitInstance函數中:
int CLanguagesApp::ExitInstance()  
{
 // 釋放資源鏈接庫
 if(m_hLangDLL)  
  AfxFreeLibrary(m_hLangDLL);
 return CWinApp::ExitInstance();
}
5.修改OnDraw
為了說明是從資源鏈接庫中動態地獲取數據而不是從程序的執行體中獲取,該程序從資源鏈接庫中獲取了一個圖標和一個字符串,并繪制在屏幕上。下面是主要代碼:
void CLanguagesView::OnDraw(CDC* pDC)
{
CLanguagesDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//畫出從鏈接庫加載的圖標
pDC->DrawIcon(10,10,AfxGetApp()->LoadIcon(IDR_MAINFRAME));
//顯示字符串
CString strMsg;
strMsg.LoadString(IDS_HELLO);
pDC->TextOut(60,15,strMsg);
}
6.從項目中移走Languages.rc
由于本文項目自身并不需要含有任何資源,所以從項目列表文件中移走Languages.rc文件(并不刪除)。ClassWizad不允許項目不包含資源文件,所以可以創建一個空資源文件并加入到項目中,然后重建信息文件(Languages.CLW),使得ClassWizad可以繼續管理程序的消息處理。但在本例由于所有的函數都已經加入,可不必為項目創建空資源文件。
7.建立項目
修改設置,從Project菜單選擇Setting…選項。在Link標簽下將輸出文件名由\Debug\Languages.exe改為Languages.exe。編譯項目,由于應用程序中沒有任何資源,會出現找不到資源鏈接庫的錯誤,下面的一系列步驟為本項目分別創建簡體中文和美國英語的資源鏈接庫。在這兩個鏈接庫建立后,把它們放到Languages項目目錄中,程序就可以運行了。
建立中文資源鏈接庫
1.創建新項目
為了統一起見,將新創建的Language_chinese項目和Languages項目放在同一工作區內,并將項目目錄作為工作區目錄“多語種支持”的子目錄。選擇Regular DLL-based應用程序并按下Finish鍵完成創建。動態鏈接庫項目只包含資源,不需要其他文件,所以從項目中刪除所有其他文件。
2.拷貝資源文件
把Languages相關的資源文件拷貝到Language_chinese項目的對應目錄下。表1是需要拷貝的文件名。
表1
文件名稱 注釋
Languages.rc 資源描述文件
Resource.h 包含資源定義的頭文件
Res\Languages.ico 主程序圖標
Res\Languages.rc2 用于定義資源的描述文件
Res\LanguagesDoc.ico 文檔圖標
Res\Toolbar.bmp 工具條位圖
3.將資源文件添加到項目中
把Languages.rc加入到Language_chinese項目中,使得項目中的唯一文件是Languages.rc。
4.修改資源
將ID_MAINFRAME的圖標改成代表簡體中文的圖標,該圖標將在Languages應用程序顯示窗口中出現。在串資源表中添加串IDS_HELLO=200,標題為“嗨,這是中文版?!?。
5.修改連接編譯設置
從Project菜單中選擇Setting…選項。首先,將輸出文件名由\Debug\Language_chinese.dll改為..\chinese.dll,將動態鏈接庫直接建立在Languages項目目錄下。然后在鏈接命令行中添加“/NOENTRY”選項。最后,編譯并建立動態鏈接庫。
也可以建立一個初始化鏈接庫原文件,這樣就無需在鏈接命令行中添加“/NOENTRY”選項。程序主要代碼如下:
#include <windows.h>
extern “C”
BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID )
{
return 1;
}
建立英文資源動態鏈接庫
生成英文版資源文件最快捷的方法是創建一個基于英文版的臨時項目,并把資源文件拷到英文鏈接庫項目中。其處理方法類似于中文資源鏈接庫。
需要注意的是:在修改資源組件設置時,不但要將Project菜單Setting對話框中Resource標簽的缺省文字改為“英語(美國)”,還要刪除預處理定義中的“_AFXDLL”。刪除_AFXDLL預處理器,可以使用戶的鏈接庫包含通用的MFC資源。否則,應用程序會從系統安裝的MFC動態鏈接庫中收集通用的MFC資源,應用程序特定資源會被本地化。
小 結
Windows應用程序的資源一般捆綁在執行程序上,當需要時才將其裝入。當需要某資源時,需要給Windows提供兩個參數:應用程序的實例句柄和資源的標識符。當某個鏈接庫裝入時,Windows返回一個實例句柄,可以通過該句柄引用鏈接庫中的資源。
需要注意的是:由于內存不夠或其他的一些資源問題,可能會導致加載資源失敗。

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97