当一个文档完整的完成下载Internet Explorer 激发DocumentComplete 事件. 仅仅当此事件激发后 文档对象才可安全使用.在一个无帧的Web页情形中文档对象是IHTMLDocument2 对象, 我们以后会讨论. 当文档对象准备好可用,他的状态为READYSTATE_COMPLETE.
关于 DocumentComplete 事件以西击点需要注意:
· 在没有帧的web页, DocumentComplete 事件在下载完成后激发一次.
VB中实现以上四点及其容易.仅需要检查发送给事件的pDisp 参数事一个WebBrowser 对象. Visual Basic小心检查这些对象的 Iunknown否为同一个对象.此处为VB代码::
Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant) If (pDisp Is WebBrowser1.Object) Then MsgBox "The document is finished loading." End If End Sub |
实现以上四点在Visual C++ 应用程序里较困难一点,但你可以做到! 首先在DocumentComplete 事件的宏中如下声明:
ON_EVENT(CMfcWebHostView, IDC_WEBBROWSER, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete, VTS_DISPATCH VTS_PVARIANT) |
接下来声明OnDocumentComplete 方法作为事件处理句柄
void OnDocumentComplete(LPDISPATCH lpDispatch, VARIANT FAR* URL); |
最后,实现该方法以检测 是否页面已经下载,我们得到我们宿主控制bBrowser 控件的IUnknown. (注意我们不是简单获取指向 IUnknown ,而是要调用GetControlUnknown 方法. GetControlUnknown方法返回的IUnknown 指针 实际上并不等于被宿主话的 WebBrowser控件的IUnknown. 那将返回IOleObject 接口指针.) 下一步, 获取IUnknown 指针,如果QueryInterface 查询得到的Dispatch 参数同Iunknown接口是同一对象,则页面完成整个下载。.
void CMfcWebHostView::OnDocumentComplete(LPDISPATCH lpDispatch, VARIANT FAR* URL) { HRESULT hr; LPUNKNOWN lpUnknown; LPUNKNOWN lpUnknownWB = NULL; LPUNKNOWN lpUnknownDC = NULL; lpUnknown = m_webBrowser.GetControlUnknown(); ASSERT(lpUnknown); if (lpUnknown) { // Get the pointer to the IUnknown interface of the WebBrowser // control being hosted. The pointer to the IUnknown returned from // GetControlUnknown is not the pointer to the IUnknown of the // WebBrowser control. It's actually a pointer to the IOleObject. // hr = lpUnknown->QueryInterface(IID_IUnknown, (LPVOID*)&lpUnknownWB); ASSERT(SUCCEEDED(hr)); if (FAILED(hr)) return; // Get the pointer to the IUnknown of the object that fired this // event. // hr = lpDispatch->QueryInterface(IID_IUnknown, (LPVOID*)&lpUnknownDC); ASSERT(SUCCEEDED(hr)); if (SUCCEEDED(hr) && lpUnknownWB == lpUnknownDC) { // The document has finished loading. // MessageBox("The document has finished loading."); } if (lpUnknownWB) lpUnknownWB->Release(); if (lpUnknownDC) lpUnknownDC->Release(); } } |
有一点需要注意上面的代码我们在GetControlUnknown 返回的IUnknown 接口指针使用时并没有进行Release ,因为b IUnknown 指针并没有在GetControlUnknown方法中 AddRef'. GetControlUnknown 方法仅仅返回一个IOleObject 数据成员的指针,该指针由控件站点类—CcontrolSite 操纵处理. 如果你释放了IUnknown 接口指针, 载你关闭应用程序时,一个访问违例将会发生,因为MFC 将试图在对象被删除时候多释放一次.
DownloadBegin 事件通知应用程序一个导航操作开始. 一般情况下该事件在BeforeNavigate2 事件之后激发, 除非导航操作在BeforeNavigate2 事件处理过程中被取消.容器应当显示动画或者忙指示当前正处于连接的DownloadBegin事件. 每一个 DownloadBegin 事件有一个相应的DownloadComplete 事件. 在刷新页面的情形中, DownloadBegin 和 DownloadComplete 使唯一的被激发的导航事件.
DownloadComplete在一个导航操作完成时候发生, 停止, 或者失败. 不像 NavigateComplete2仅仅当成功导航才发生, DownloadComplete总是在道涵开始后激发.任何在DownloadBegin 中显示的动画或者忙指示将会在DownloadComplete 中停止.
NavigateComplete2 事件在导航到一个超连接整个窗口或者帧集合的元素全部完成时候发生. 第一此事件发生表示文档document已经准备好.在此事件发生后, 你可以通过Document 属性存取文档(document)而不接收到错误.但是能够访问一个文档不意味着你访问文档使安全的.你可以在DocumentComplete 事件激发后安全访问文档.
档你需要访问document对象但是不需要访问文档内的元素,你可以在NavigateComplete2 事件中尽可能快的处理,例如当你在文打工通过高级宿主接口. NavigateComplete2 事件有2个参数—IDispatch of 代表激发事件的对象URL 为你需要导航到的URL.