我遇到的狀況是這樣:我手上有一個別人做的2d繪圖庫, 可以理解為gdi的封裝. 但是他只做了ansi版本, 比如TextOut這樣的函數, 只能輸入ansi字符串, 而不是utf-16le寬字符串. 我現在的上層應用可以選擇utf-8或者utf-16le作為內部編碼, 那么就面臨一個問題, 就是當我要渲染字符串的時候, win32的ansi系列api接受的是"本地編碼", 就是GetACP返回的CodePage. 如果我每次渲染之前都使用轉換函數轉換的話, 比如我用utf-8, 就會執行這樣的過程----先把utf-8轉換成utf-16le, 再把utf-16le轉換成本地ansi編碼比如GBK, 然后傳遞給TextOut, TextOut內部會自動把GBK再傳換成utf-16le再顯示. 來來回回繞了一大圈, 未免太復雜了.我想請教的就是, 有沒有方法把進程內的ansi系列api默認編碼全部換成utf-8? 比如"SetACP"這樣類似的方法. 這樣我就可以在應用中使用utf-8傳給TextOut, 由TextOut執行一次轉換, 就可以顯示了.
2 回答

慕碼人2483693
TA貢獻1860條經驗 獲得超9個贊
Windows API 都有兩個版本,你直接用 Unicode 版本不就得了。為什么非要轉兩次呢?你轉成本地編碼,系統內部最終還是轉成 Unicode 并調用了 Unicode 版本的 API,純屬折騰。比如 TextOut,你可以顯式調用 TextOutW,調用之前,使用 MultiByteToWideChar 將 UTF-8 轉換為 Windows Unicode (UTF-16LE)。例如,將 TextOut 包裝為 GdiTextOut,分別包裝為 UTF-8 和 UTF-16LE 兩個版本:
BOOL WINAPI GdiTextOut( HDC hdc, int nXStart, int nYStart, PCWSTR lpString, int cchString ){ return ::TextOutW(hdc, nXStart, nYStart, lpString, cchString); } BOOL WINAPI GdiTextOut( HDC hdc, int nXStart, int nYStart, PCSTR lpString, int cchString ){ WCHAR wszBuffer[1024] = { 0 }; DWORD cchBuffer = sizeof(wszBuffer) / sizeof(WCHAR); int cchResult = MultiByteToWideChar(CP_UTF8, 0, lpString, -1, wszBuffer, cchBuffer); if (cchResult > 0) { return GdiTextOut(hdc, nXStart, nYStart, wszBuffer, cchResult); } BOOL bResult = FALSE; int cchNeeded = MultiByteToWideChar(CP_UTF8, 0, lpString, -1, NULL, 0); if (cchNeeded > 0) { HANDLE hHeap = GetProcessHeap(); PWSTR lpBuffer = (PWSTR)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, cchNeeded * sizeof(WCHAR)); if (lpBuffer != NULL) { int cchResult = MultiByteToWideChar(CP_UTF8, 0, lpString, -1, lpBuffer, cchNeeded); if (cchResult > 0) { bResult = GdiTextOut(hdc, nXStart, nYStart, lpBuffer, cchResult); } HeapFree(hHeap, 0, (void *)lpBuffer); } } return bResult; }
- 2 回答
- 0 關注
- 217 瀏覽
添加回答
舉報
0/150
提交
取消