在第一次為公司的用戶端軟體定製日語版本的時候,由於軟體開發是非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)<br />{<br />//擷取該字串轉換成Unicode編碼格式需要的buffer的大小<br />DWORD dwMinSize;<br />dwMinSize = MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, NULL, 0);</p><p>if(dwSize < dwMinSize)<br />{<br />return -1;<br />}<br />//將ASCII轉換為Unicode.<br />MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, lpwszStr, dwMinSize);<br />return dwMinSize;<br />}
2、具體的使用:
void CNetAppSoftDlg::TextOutW_EX(HDC hDC, CRect cRect, CString csText)<br />{<br />wchar_t wchCaption[256];<br />ZeroMemory(wchCaption, 256);<br />char chCaption[512]= {0};<br />sprintf(chCaption, "%s", csText);</p><p>DWORD dwMinSize = -1;<br />dwMinSize = MByteToWChar(chCaption,wchCaption,256);</p><p>if (-1 == dwMinSize)<br />{<br />AfxMessageBox("Conver failed!", MB_USERDEFINE);<br />}<br />else<br />{<br />TextOutW(hDC, cRect.left, cRect.top, wchCaption, dwMinSize-1);<br />}<br />}
建議:
第一,以後編寫軟體建立工程的時候,都要採用Unicode的編碼格式,因為它對各種語言都是通用的,是軟體走向國際化的標準方式。正如Unicode的產生背景一樣,我們軟體的開發也要隨之變化以適應新的應用環境。
第二,在以後編碼的過程中,使用通用的(同時支援ANSI和Unicode,以_tcs或者lstr開頭)的字串操作函數,如_tcscpy(),lstrcpy()。