第一步,谷歌有文章说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