码迷,mamicode.com
首页 > 编程语言 > 详细

【MFC】CHtmlView::GetSource中文乱码的问题

时间:2018-04-04 16:18:41      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:cto   结果   tle   unlock   获取   网页   测试   length   set   

在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中文乱码的问题

标签:cto   结果   tle   unlock   获取   网页   测试   length   set   

原文地址:https://www.cnblogs.com/yvqvan/p/8717515.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!