Как полностью уничтожить элемент управления WebBrowser - PullRequest
4 голосов
/ 26 ноября 2011

Я использую ATL в VisualC ++ 10 для управления браузером.Мой код похож на этот пример: http://msdn.microsoft.com/en-us/library/9d0714y1(v=vs.80).aspx

Разница в том, что у меня есть главное окно, а затем дочернее окно содержит элемент управления браузера.Через 2 минуты мне нужно закрыть браузер, чтобы полностью убить браузер activeX, но это дочернее окно должно быть живым и сделать что-то еще.Но каким-то образом этот элемент управления браузера все еще остается там, я могу видеть полосы прокрутки или что-то еще.

Я также пытался создать дочернее окно для существующего дочернего окна, и во время закрытия браузера я затем уничтожил этот дочерний элемент.ребенка - но все равно это не работает!

Вот как я закрываюсь:

CLOSE()
{
    m_spIWebBrowser2->Navigate(bstrURL, &vEmpty, &vEmpty, &vEmpty, &vEmpty);
    m_spIWebBrowser2->Stop();
    m_spIWebBrowser2->put_Visible(VARIANT_FALSE);
    m_spIWebBrowser2->Quit();
    DestroyWindow(m_wndChild.m_hWnd);
}

Спасибо!

Ответы [ 3 ]

10 голосов
/ 01 февраля 2013

У меня было много проблем с «нарушением прав доступа» при закрытии веб-браузера, вот эти шаги, которые работали для меня:

  1. Отмена любых ранее рекомендованных событий (DWebBrowserEvents2 в моем случае).
  2. Если вы прикрепили события клика, отсоедините их следующим образом: _variant_t v; v.vt = VT_DISPATCH; v.pdispVal = 0; IHTMLDocument2->put_onclick(v);
  3. IWebBrowser2->Stop()
  4. IWebBrowser2->ExecWB(OLECMDID_CLOSE, OLECMDEXECOPT_DONTPROMPTUSER, 0, 0) - при закрытии окна браузера через window.external.CloseWindow () Iбыли необработанные исключения, и OLECMDID_CLOSE исправил его.
  5. IWebBrowser2->put_Visible(VARIANT_FALSE)
  6. IWebBrowser2->Release()
  7. IOleInPlaceObject->InPlaceDeactivate()
  8. IOleInPlaceObject->Release()
  9. IOleObject->DoVerb(OLEIVERB_HIDE, NULL, IOleClientSite, 0, windowHandle_, NULL)
  10. IOleObject->Close(OLECLOSE_NOSAVE)
  11. OleSetContainedObject(IOleObject, FALSE)
  12. IOleObject->SetClientSite(NULL)
  13. CoDisconnectObject(IOleObject, 0)
  14. IOleObject->Release()

IWebBrowser2->Quit() не следует вызывать для элемента управления WebBrowser (CLSID_WebBrowser), он предназначен только для объекта Internet Explorer (CLSID_InternetExplorer).

Почему он должен быть таким сложным?

0 голосов
/ 30 ноября 2011

Если я использую DialogBox и добавляю в него IEControl как ресурс, а DialogBox является производным от CAxDialogImpl <> - тогда, когда я вызываю DestroyWindow () dialogBox, он автоматически выполняет cleanup () - что мне и требовалось.Но изначально я хотел избавиться от самого DialogBox и использовать IEControl непосредственно в моем окне, похоже, нет ..

0 голосов
/ 28 ноября 2011

Мой опыт показывает, что для правильной работы некоторых звонков может потребоваться обработка сообщений. Попытайтесь накачать некоторые сообщения между вашими вызовами на Navigate, Stop и т. Д. При работе с интерфейсами веб-браузера я PostMessage сам часто запускаю следующий шаг, чтобы убедиться, что предыдущий шаг успел завершиться.

Возможно, проблема связана с вашей дочерней веткой. Вы не можете получить доступ к интерфейсам веб-браузера между потоками без дополнительной работы. COM необходимо инициализировать как однопотоковую квартиру (STA). И вам нужно следовать правилам STA :

  • Каждый объект должен жить только в одном потоке (в однопоточной квартире). Инициализируйте библиотеку COM для каждого потока.
  • Маршал все указатели на объекты при прохождении их между квартирами.
  • Каждая однопоточная квартира должна иметь цикл обработки сообщений для обработки вызовов из других процессов и квартир в рамках одного и того же процесса. Однопоточные квартиры без объектов (только клиент) также нуждаются в цикле сообщений для отправки широковещательных сообщений, которые используются некоторыми приложениями.
  • ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...