【MFC】CHtmlView::GetSource中文亂碼的問題
阿新 • • 發佈:2018-04-04
需要 style spp creates let clas document amp LG
在MFC的SDI中,使用CHtmlView::GetSource來獲取網頁源碼,保存到本地,發現中文中的一部分亂碼,有些中文正常。自己先試著轉碼等各種嘗試,發現一無所獲。網上也沒有正確的解決方案。
自己跟蹤CHtmlView::GetSource函數內,在ViewHtml.cpp文件的1083行處,有如下代碼:
bRetVal = TRUE; TRY { refString = CString(pstr, statStg.cbSize.LowPart); } CATCH_ALL(e) { bRetVal = FALSE; DELETE_EXCEPTION(e); }
關鍵處在:refString = CString(pstr, statStg.cbSize.LowPart);
其實就是在UNICODE情況下,CString在構造時,使用了LPCSTR或者char*來構造CString時的構造函數。但是在構造這個CString內部,會調用到如下函數:
static void __cdecl ConvertToBaseType( _Out_writes_(nDestLength) LPWSTR pszDest, _In_ int nDestLength, _In_ LPCSTR pszSrc, _In_ int nSrcLength = -1) throw() { // nLen is in wchar_ts::MultiByteToWideChar( _AtlGetConversionACP(), 0, pszSrc, nSrcLength, pszDest, nDestLength ); }
內部有對LPCSTR或char*進行字符轉換。
中文的一部分亂碼,正是由這個地方產生的。
別奢望用CStringA str(strHtml)來轉換回來,轉了之後的內容,依然有一部分的中文亂碼。
我的解決辦法是,將CHtmlView::GetSource的代碼Copy出來,直接返回CStringA的內容,並用CStringA的內容,來保存文件。結果就正常了。
我的代碼如下:
BOOL CMFCBrowserView::GetMySource(CStringA& strRef) { BOOL bRetVal= FALSE; CComPtr<IDispatch> spDisp; m_pBrowserApp->get_Document(&spDisp); if ( spDisp == NULL ) { return bRetVal; } HGLOBAL hMemory; hMemory = GlobalAlloc(GMEM_MOVEABLE, 0); if ( hMemory == NULL ) { return bRetVal; } CComQIPtr<IPersistStreamInit> spPersistStream = spDisp; if ( spPersistStream == NULL ) { GlobalFree(hMemory); return bRetVal; } CComPtr<IStream> spStream; HRESULT hRes = CreateStreamOnHGlobal(hMemory, TRUE, &spStream); if ( FAILED(hRes) ) { GlobalFree(hMemory); return bRetVal; } spPersistStream->Save(spStream, FALSE); STATSTG statStg; spStream->Stat(&statStg, STATFLAG_NONAME); LPCSTR pstr = static_cast<LPCSTR>(GlobalLock(hMemory)); if ( pstr == NULL ) { GlobalFree(hMemory); return bRetVal; } // Stream is expected to be ANSI (CP-ACP). CString constructor // will convert implicitly, and truncate to correct length. bRetVal = TRUE; CStringA strV(pstr, statStg.cbSize.LowPart); strRef = strV; GlobalUnlock(hMemory); GlobalFree(hMemory); return bRetVal; }
主要問題:就出在CString內部構造時,對字符串的轉換。如果需要CString的字符串,可能需要自己來轉換成寬字符,然後賦值給CString。這個只是猜測,沒有進行測試。
【MFC】CHtmlView::GetSource中文亂碼的問題