C++ 如何彻底销毁WebBrowser控件
我正在VisualC++10中使用ATL来主持浏览器控件。 我的代码与此示例类似: 区别在于我有主窗口,然后子窗口托管浏览器控件。 2分钟后,我必须关闭浏览器,完全关闭浏览器activeX,但此子窗口应处于活动状态,并执行其他操作。但不知何故,这个浏览器控件仍然保留在那里,我可以看到滚动条或其他东西 我也尝试过在现有的子窗口中创建子窗口,在关闭浏览器时,我会销毁子窗口的这个子窗口,但仍然不起作用 这就是我结束的方式:C++ 如何彻底销毁WebBrowser控件,c++,visual-studio-2010,webbrowser-control,atl,iwebbrowser2,C++,Visual Studio 2010,Webbrowser Control,Atl,Iwebbrowser2,我正在VisualC++10中使用ATL来主持浏览器控件。 我的代码与此示例类似: 区别在于我有主窗口,然后子窗口托管浏览器控件。 2分钟后,我必须关闭浏览器,完全关闭浏览器activeX,但此子窗口应处于活动状态,并执行其他操作。但不知何故,这个浏览器控件仍然保留在那里,我可以看到滚动条或其他东西 我也尝试过在现有的子窗口中创建子窗口,在关闭浏览器时,我会销毁子窗口的这个子窗口,但仍然不起作用 这就是我结束的方式: CLOSE() { m_spIWebBrowser2->Navi
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);
}
谢谢 根据我的经验,有些调用可能需要消息处理才能正常运行。尝试在调用
导航
、停止
等之间发送一些消息。在使用web浏览器界面时,我经常会触发下一步,以确保前一步有时间完成
问题可能与您的子线程有关。如果不做一些额外的工作,就无法访问线程之间的web浏览器接口。COM需要初始化为单线程单元(STA)。你需要遵循:
- 每个对象应该只存在于一个线程上(在单线程单元中)。 为每个线程初始化COM库
- 在单元之间传递对象时,封送所有指向对象的指针。
- 每个单线程单元必须有一个消息循环,以处理来自同一进程内其他进程和单元的调用。没有对象的单线程单元(仅限客户端)还需要一个消息循环来调度某些应用程序使用的广播消息李>
\u variant\u t v;v、 vt=vt_调度;v、 pdispVal=0;IHTMLDocument2->put_onclick(v)代码>
IWebBrowser2->Stop()
IWebBrowser2->ExecWB(OLECMDID\u CLOSE,OLECMDEXECOPT\u DONTPROMPTUSER,0,0)
-通过window.external.CloseWindow()关闭浏览器窗口时,我有未处理的异常,OLECMDID\u CLOSE修复了它IWebBrowser2->put\u Visible(变量\u FALSE)
IWebBrowser2->Release()
IOleInPlaceObject->InPlaceDeactivate()
IOleInPlaceObject->Release()
IOleObject->DoVerb(OLEIVERB\u HIDE,NULL,IOleClientSite,0,windowHandle\u,NULL)
IOleObject->Close(OLECLOSE\u NOSAVE)
OleSetContainedObject(IOleObject,FALSE)
IOleObject->SetClientSite(空)
CoDisconnectObject(IOleObject,0)
IOleObject->Release()
IWebBrowser2->Quit()
,它仅用于Internet Explorer对象(CLSID\u InternetExplorer)
为什么这么难?我记得关闭webbrowser控件时出现了一个问题,原因是“本地”COM初始化/取消初始化。要支持beast的异步特性,需要在
main
中调用CoInitialize。但想必你已经有了?是的那些东西被掩盖了。。我们还在对话框上使用IE控件-这些控件工作正常。我通过主线程在mainwindow上创建了IE控件,然后main生成了一个新线程,从那里我调用navigate()并显示网页,一分钟后我从子线程调用上述close()函数,浏览器控件消失,但仍然存在,原因是有时可以看到IEControl滚动条,并且iexplore.exe(out of)进程也在运行。进程的生存期由引用计数控制。你没有破坏你的智能指针。谢谢,但是:IWebBrowser2*iw;g_spWebBrowser2->查询接口(&iw);ULONG ul=iw->Release();AtlAxWinTerm();不过,它还在继续。谢谢你的意见。但是,编组btw线程没有问题——线程能够成功地控制IE(导航),在多次调用IE控制之间没有问题——工作正常。我刚刚用一个新的Win32应用程序测试了相同的场景,在这两种情况下,主线程和工作线程IE都不会终止。如果线程没有创建浏览器控件,则不允许在不进行编组的情况下从该线程调用浏览器控件。也许编组是在幕后进行的,但这是必要的。只是打个电话可能看起来有用,但谁知道会丢失哪些信息。但是你是说在单线程场景中问题仍然存在吗?是的。如果我使用DialogBox并在其上放置一个IECControl作为资源,DialogBox是从CAxDialogImpl派生的,那么DialogBox的destroywindow()会自动进行清理();投票前一段时间,但需要说的是:这个职位是黄金。在多次打开/关闭后帮助我防止嵌入式浏览器崩溃。是否(5)应该在(3)之前?(5) 防止来自用户的任何新输入。(3) 停止任何正在进行的浏览器活动。考虑用户可能导致浏览器再次在(3)和(5)之间做一些事情,例如通过点击浏览器窗口中的某个地方。在我看来,这是一个潜在的竞争条件。@mitty调用(3)和(4)应该立即执行,我认为它们是在主UI上执行的