在第一次爲公司的客戶端軟件定製日語版本的時候,由於軟件開發是非Unicode版本的,發現當加載日語後,無論是在中文操作系統還是在日語操作系統下,軟件界面上的大部分日語顯示的都是亂碼。在上網查看了相關的知識文檔和案例,結合目前我們軟件的開發環境和具體的代碼實現,找到了兩種解決辦法。
第一種:
就是將整個軟件工程變爲Unicode編碼格式。雖然這種方法能從根本上實現軟件的國際化多語言版本。但修改起來工作量相當的龐大。例如:整個軟件源碼中以前採用只支持ANSI編碼的字符串操作函數(如strcpy(),strlen())都要改爲支持Unicode的(如wcscpy(),wcslen()),或者換成ANSI和Unicode通用的字符串操作函數。
第二種:
就是具體問題具體分析。就目前出現的亂碼情況來看。主要是重載、自繪的控件出現了日語的亂碼。其解決辦法是首先對需要輸出的字符串進行編碼格式的轉換,然後將字符串輸出函數換爲後綴爲W的(即支持寬字符集的)字符串輸出函數。
問題分析:
非 UNICODE 程序在不同語言環境間移植時的亂碼
非 UNICODE 程序中的字符串,都是以某種 ANSI 編碼形式存在的。如果程序運行時的語言環境與開發時的語言環境不同,將會導致 ANSI 字符串的顯示失敗。
比如,在日文環境下開發的非 UNICODE 的日文程序界面,拿到中文環境下運行時,界面上將顯示亂碼。如果這個日文程序界面改爲採用 UNICODE 來記錄字符串,那麼當在中文環境下運行時,界面上將可以顯示正常的日文。同樣,對在中文環境下開發的非 UNICODE 程序同樣存在此問題。
解決辦法:
第二種方法的具體解決方案如下:
1、主要的字符串編碼格式轉換函數
- DWORD CNetAppSoftDlg::MByteToWChar(LPCSTR lpcszStr, LPWSTR lpwszStr, DWORD dwSize)
- {
- //獲取該字符串轉換成Unicode編碼格式需要的buffer的大小
- DWORD dwMinSize;
- dwMinSize = MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, NULL, 0);
- if(dwSize < dwMinSize)
- {
- return -1;
- }
- //將ASCII轉換爲Unicode.
- MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, lpwszStr, dwMinSize);
- return dwMinSize;
- }
2、具體的使用:
- void CNetAppSoftDlg::TextOutW_EX(HDC hDC, CRect cRect, CString csText)
- {
- wchar_t wchCaption[256];
- ZeroMemory(wchCaption, 256);
- char chCaption[512]= {0};
- sprintf(chCaption, "%s", csText);
- DWORD dwMinSize = -1;
- dwMinSize = MByteToWChar(chCaption,wchCaption,256);
- if (-1 == dwMinSize)
- {
- AfxMessageBox("Conver failed!", MB_USERDEFINE);
- }
- else
- {
- TextOutW(hDC, cRect.left, cRect.top, wchCaption, dwMinSize-1);
- }
- }
建議:
第一,以後編寫軟件創建工程的時候,都要採用Unicode的編碼格式,因爲它對各種語言都是通用的,是軟件走向國際化的標準方式。正如Unicode的產生背景一樣,我們軟件的開發也要隨之變化以適應新的應用環境。
第二,在以後編碼的過程中,使用通用的(同時支持ANSI和Unicode,以_tcs或者lstr開頭)的字符串操作函數,如_tcscpy(),lstrcpy()。