zoukankan      html  css  js  c++  java
  • 使用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

  • 相关阅读:
    ASP.NET,flexpaper,SWFTools 实现简单的PDF显示(一)
    ASP.NET,flexpaper,SWFTools 实现简单的PDF显示(三)
    一个获取远程客户端真实IP的例子
    用微软Chart制作图表
    快速读取xml节点内容
    ASP.NET 网站路径【摘自MSDN】
    SqlServer连接字符串相关记录
    视图研究一二
    天大计算机研究生的求职总结
    一个计算机系研究生毕业以后的人生规划(转)
  • 原文地址:https://www.cnblogs.com/HemJohn/p/10901681.html
Copyright © 2011-2022 走看看