Здравствуйте, <Аноним>, Вы писали:
А>Привет, ALL!
А>Bмеется MDI-приложение. В нем создаются формы со встроенным TCppWebBrowser, в него подгружаются HTML-странички большого объема. При закрытии таких окон память из-под расположенного на них TCppWebBrowser не освобождается — очень хорошо видно из диспетчера задач. Как заставить TCppWebBrowser при закрытии окна освободить память? А то программа очень сильно разбухает после создания нескольких окошек с TCppWebBrowser. Может, кто сталкивался с этим?
Встречался с описанием подобной проблемы на DelphiKingdom.
Если не ошибаюсь, там предлагали обращаться к свойствам html документа
не через методы класса TCppWebBrowser, а через COM интерфейс напрямую.
... << RSDN@Home 1.1.4 stable rev. 510>>
Здравствуйте, yuha, Вы писали:
Y>Здравствуйте, <Аноним>, Вы писали:
А>>Привет, ALL!
А>>Bмеется MDI-приложение. В нем создаются формы со встроенным TCppWebBrowser, в него подгружаются HTML-странички большого объема. При закрытии таких окон память из-под расположенного на них TCppWebBrowser не освобождается — очень хорошо видно из диспетчера задач. Как заставить TCppWebBrowser при закрытии окна освободить память? А то программа очень сильно разбухает после создания нескольких окошек с TCppWebBrowser. Может, кто сталкивался с этим?
Y>Встречался с описанием подобной проблемы на DelphiKingdom.
Y>Если не ошибаюсь, там предлагали обращаться к свойствам html документа
Y>не через методы класса TCppWebBrowser, а через COM интерфейс напрямую.
Вот, еще по теме, но для Delphi:
... Первым делом это TWebBrowser.Document:IDispatch . Через это свойство можно
получить доступ к интерфейсу IHtmlDocument2.. Далее через
этот интерфейс можно получить доступ к большинству средств по взаимодействию с
загруженным документом. То есть это очень интересное и "нужное" свойство. Но
немного забегая наперед, скажу, что если Вы попытаетесь использовать TWebBrowser.Document:IDispatch, то Вы рано или поздно заметите
довольно странную "утечку" памяти в процессе навигации. В чем же дело? После
анализа ситуации, удалось определить, что для любой интерфейсной ссылки на
документ, которая получена через этот свойство, счетчик использования
"необоснованно" увеличивается на 1 и соответствующий COM-обьект никогда не будет
освобожден. При более детальном изучении нашлась и создательница этой
проблемы — function
TOleControl.GetIDispatchProp(Index: Integer): IDispatch;, через которую и
работает TWebBrowser.Document:IDispatch (я речь веду о
Delphi5, возможно в Delphi4 все нормально, не проверял). Детальный рассказ
об этой ситуации выходит за рамки этой статьи..
К счастью эту проблему легко обойти, использовав для получения
IHtmlDocument2 альтернативные возможности, хотя бы WebBrowser1.ControlInterface.Document .
... << RSDN@Home 1.1.4 stable rev. 510>>
Здравствуйте, yuha, Вы писали:
Y>>Встречался с описанием подобной проблемы на DelphiKingdom.
Y>>Если не ошибаюсь, там предлагали обращаться к свойствам html документа
Y>>не через методы класса TCppWebBrowser, а через COM интерфейс напрямую.
Y>Вот, еще по теме, но для Delphi:
Y> К счастью эту проблему легко обойти, использовав для получения
Y>IHtmlDocument2 альтернативные возможности, хотя бы WebBrowser1.ControlInterface.Document
Через WebBrowser1.ControlInterface.Document не сработало: память не освобождается, но все равно спасибо за идею! В принципе, сделал немного не так, но в том направлении, и все заработало:
IUnknown* pUnk = NULL;
IWebBrowser2* pBrowser = NULL;
IDispatch* pDisp = NULL;
IHTMLDocument2* pDoc = NULL;
if (SUCCEEDED(HTMLedit->ControlInterface->QueryInterface(
IID_IUnknown, (LPVOID*)&pUnk)))
{
if (SUCCEEDED(pUnk->QueryInterface(
IID_IWebBrowser2, (LPVOID*)&pBrowser)))
{
pBrowser->get_Document(&pDisp);
if (pDisp) {
if (SUCCEEDED(pDisp->QueryInterface(
IID_IHTMLDocument2, (LPVOID*)&pDoc)))
{
HRESULT hresult = S_OK;
VARIANT *param;
SAFEARRAY *sfArray;
WideString ws;
ws = WideString(*text);
// Creates a new one-dimensional array
sfArray = SafeArrayCreateVector(VT_VARIANT, 0, 1);
if (sfArray == NULL ) {
goto cleanup;
}
hresult = SafeArrayAccessData(sfArray,(LPVOID*) & param);
param->vt = VT_BSTR;
param->bstrVal = BSTR(ws); //bs;
SafeArrayUnaccessData(sfArray);
hresult = pDoc->write(sfArray);
if (hresult != S_OK ) ShowMessage("Ошибка создания HTML-документа");
cleanup:
param->bstrVal = NULL;
if (sfArray != NULL) {
SafeArrayDestroy(sfArray);
}
pDoc->Release();
} // pDoc
pDisp->Release();
} // pDisp
pBrowser->Release();
} // pBrowser
pUnk->Release();
} // pUnk
else ShowMessage("Невозможно создать HTML-документ");
после этого в диспетчере задач ясно видно, что память освобождается полностью или почти полностью: после закрытия окна, содержащего TCppWebBrowser, обьем занимаемой моей программой памяти возвращается в прежнее состояние плюс-минус несколько десятков килобайт(ранее он все время увеличивался на несколько мегабайт после закрытия окна). Неточное соответствие занимаемой памяти до и после закрытия окна скорее всего объясняется тонкостями работы менеджера памяти Windows. Ну, тут я могу ошибаться, конечно.