使用mfc CHtmlView内存泄露解决方法

Posted hemjohn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用mfc CHtmlView内存泄露解决方法相关的知识,希望对你有一定的参考价值。

第一步,谷歌有文章说ChtmlView部分api使用BSTR没释放:

解决方法是重写一下接口:

CString GetFullName() const;
CString GetFullName() const;
CString GetType() const;
CString GetLocationName() const;
CString GetLocationURL() const;
void Navigate(LPCTSTR URL, DWORD dwFlags = 0,
LPCTSTR lpszTargetFrameName = NULL,
LPCTSTR lpszHeaders = NULL, LPVOID lpvPostData = NULL,
DWORD dwPostDataLen = 0);
BOOL LoadFromResource(LPCTSTR lpszResource);
BOOL LoadFromResource(UINT nRes);
CString CHtmlViewEx::GetFullName() const
{
    ASSERT(m_pBrowserApp != NULL);

    BSTR bstr;
    m_pBrowserApp->get_FullName(&bstr);
    CString retVal(bstr);

    SysFreeString(bstr); // Added this line to prevent leak.
    return retVal;
}

CString CHtmlViewEx::GetType() const
{
    ASSERT(m_pBrowserApp != NULL);

    BSTR bstr;
    m_pBrowserApp->get_Type(&bstr);

    CString retVal(bstr);

    SysFreeString(bstr); // Added this line to prevent leak.
    return retVal;
}

CString CHtmlViewEx::GetLocationName() const
{
    ASSERT(m_pBrowserApp != NULL);

    BSTR bstr;
    m_pBrowserApp->get_LocationName(&bstr);
    CString retVal(bstr);

    SysFreeString(bstr); // Added this line to prevent leak.
    return retVal;
}

CString CHtmlViewEx::GetLocationURL() const
{
    ASSERT(m_pBrowserApp != NULL);

    BSTR bstr;
    m_pBrowserApp->get_LocationURL(&bstr);
    CString retVal(bstr);

    SysFreeString(bstr); // Added this line to prevent leak.
    return retVal;
}

void CHtmlViewEx::Navigate(LPCTSTR lpszURL, DWORD dwFlags /*= 0*/, LPCTSTR lpszTargetFrameName /*= NULL*/, LPCTSTR lpszHeaders /*= NULL*/, LPVOID lpvPostData /*= NULL*/, DWORD dwPostDataLen /*= 0*/)
{
    CString strURL(lpszURL);
    BSTR bstrURL = strURL.AllocSysString();

    COleSafeArray vPostData;
    if (lpvPostData != NULL)
    {
        if (dwPostDataLen == 0)
            dwPostDataLen = lstrlen((LPCTSTR)lpvPostData);

        vPostData.CreateOneDim(VT_UI1, dwPostDataLen, lpvPostData);
    }

    m_pBrowserApp->Navigate(bstrURL, COleVariant((long)dwFlags, VT_I4), COleVariant(lpszTargetFrameName, VT_BSTR),
        vPostData, COleVariant(lpszHeaders, VT_BSTR));

    SysFreeString(bstrURL); // Added this line to prevent leak.
}

BOOL CHtmlViewEx::LoadFromResource(LPCTSTR lpszResource)
{
    HINSTANCE hInstance = AfxGetResourceHandle();
    ASSERT(hInstance != NULL);

    CString strResourceURL;
    BOOL bRetVal = TRUE;
    LPTSTR lpszModule = new TCHAR[_MAX_PATH];

    if (GetModuleFileName(hInstance, lpszModule, _MAX_PATH))
    {
        strResourceURL.Format(_T("res://%s/%s"), lpszModule, lpszResource);
        Navigate(strResourceURL, 0, 0, 0);
    }
    else
        bRetVal = FALSE;

    delete[] lpszModule;
    return bRetVal;
}

BOOL CHtmlViewEx::LoadFromResource(UINT nRes)
{
    HINSTANCE hInstance = AfxGetResourceHandle();
    ASSERT(hInstance != NULL);

    CString strResourceURL;
    BOOL bRetVal = TRUE;
    LPTSTR lpszModule = new TCHAR[_MAX_PATH];

    if (GetModuleFileName(hInstance, lpszModule, _MAX_PATH))
    {
        strResourceURL.Format(_T("res://%s/%d"), lpszModule, nRes);
        Navigate(strResourceURL, 0, 0, 0);
    }
    else
        bRetVal = FALSE;

    delete[] lpszModule;
    return bRetVal;
}

 

第二步,由于加载页面js脚本并没有释放js变量所分配的内存,有两种解决方法:第一种,调用本地html文件,调用CollectGarbage()接口回收变量的内存,html文件代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head> 

<body>
    <script type="text/javascript">
        if (typeof window.CollectGarbage === function) {
            CollectGarbage()
        }
    </script>

</body>
</html> 

第二种:如果不需要调用html页面的js代码,可以直接关闭IE浏览器的js脚本功能:https://jingyan.baidu.com/article/48206aead44e53216ad6b397.html 

转载请注明出处,from博客园hemjohn

以上是关于使用mfc CHtmlView内存泄露解决方法的主要内容,如果未能解决你的问题,请参考以下文章

PHP CURL内存泄露的解决方法

MFC误报内存泄露的修复

MFC误报内存泄露的修复

MFC 程序退出方法

如何用Java编写一段代码引发内存泄露

什么是内存泄露?内存泄露如何解决?