1.获取WebBrowser加载网页的内容 WebBrowser1.Document.getElementById("kw").Value = "VB编程" WebBrowser1.Document.getElementById("f").submit '提交表单 2.往WebBrowser控件写入内容 WebBrowser1.Document.write str 3. 操作页面元素 for(i=0;iEnable(m_fForwardEnabled); } void CMfcWebHostView::OnUpdateNavigateGoBack(CCmdUI* pCmdUI) { pCmdUI->Enable(m_fBackEnabled); } DocumentComplete 当一个文档完整的完成下载Internet Explorer 激发DocumentComplete 事件. 仅仅当此事件激发后 文档对象才可安全使用.在一个无帧的Web页情形中文档对象是IHTMLDocument2 对象, 我们以后会讨论. 当文档对象准备好可用,他的状态为READYSTATE_COMPLETE . 关于 DocumentComplete 事件以西击点需要注意: · 在没有帧的web页, DocumentComplete 事件在下载完成后激发一次. 在多帧的 web 页,此事件激发多次 . 并非每一个帧激发一个事件 , 但每一个帧激发 DownloadBegin 事件将会相应激发 DocumentComplete 事件 . DocumentComplete 又一个指向 IDispatch 的指针参数 , 该参数指向激发此事件的窗口 . 此窗口可以是帧中的窗口 顶级帧在所有子帧激发了各自的 DocumentComplete 事件后激发自己的 DocumentComplete 事件。 因此 , ,要看一个 web 页是否完整下载完成 , 你需要从该事件的处理句柄中获取由事件产地过来的 IDispatch 参数的 IUnknown 接口。下一步,比较 IUnknown 接口是否指向你正宿主的 WebBrowser 控件或者自动化的 IE 的实例的 IUnknown 接口 . 如果这两个指针相同,这意味着全部 HTML, 图片 images, 控件 , 以及诸如此类在顶级帧或者子帧的全部对象元素都被下载了 . 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 DownloadBegin 事件通知应用程序一个导航操作开始. 一般情况下该事件在BeforeNavigate2 事件之后激发, 除非导航操作在BeforeNavigate2 事件处理过程中被取消.容器应当显示动画或者忙指示当前正处于连接的DownloadBegin 事件. 每一个 DownloadBegin 事件有一个相应的DownloadComplete 事件. 在刷新页面的情形中, DownloadBegin 和 DownloadComplete 使唯一的被激发的导航事件. DownloadComplete DownloadComplete 在一个导航操作完成时候发生, 停止, 或者失败. 不像 NavigateComplete2 仅仅当成功导航才发生, DownloadComplete 总是在道涵开始后激发.任何在DownloadBegin 中显示的动画或者忙指示将会在DownloadComplete 中停止. NavigateComplete2 NavigateComplete2 事件在导航到一个超连接整个窗口或者帧集合的元素全部完成时候发生. 第一此事件发生表示文档document已经准备好.在此事件发生后, 你可以通过Document 属性存取文档(document)而不接收到错误.但是能够访问一个文档不意味着你访问文档使安全的.你可以在DocumentComplete 事件激发后安全访问文档. 档你需要访问document对象但是不需要访问文档内的元素,你可以在NavigateComplete2 事件中尽可能快的处理,例如当你在文打工通过高级宿主接口. NavigateComplete2 事件有2个参数—IDispatch of 代表激发事件的对象URL 为你需要导航到的URL. NewWindow2 NewWindow2 档用户显示一个新窗口以进行新导航显示web页或者其他资源时发生.在WebBrowser控件响应柄进行预处理 (举例来说, 在响应window .open 方法). NewWindow2 也在Navigate 或者 Navigate2 方法被调用且navOpenInNewWindow 标志被设定时发生. 档采用文件菜单中的New Window按钮时并不发生(Internet Explorer帧不是一个 HTML 帧; 它是帧窗口.) 因此, WebBrowser 对象不知道什么时候新窗口将被打开. 因为 NewWindow2 有时候很难使用, 所以我们来检查它的两个参数: ppDisp and Cancel. ppDisp 参数是接口指针, 一般是接收新WebBrowser 或者 InternetExplorer 对象的IDispatch 接口指针, 是你能够创建一个Internet Explorer新实例以便能够控制来自你的应用程序导航产生的新窗口. 该实例开始为新建的, 隐藏的, (暂时)不可导航WebBrowser 或者 InternetExplorer 对象. 在NewWindow2事件句柄函数返回之前, InternetExplorer 对象激发NewWindow2 事件将配置新WebBrowser对象的导航目标位置. 另外参数, Cancel , 时取消(Cancel)标志的地址. 应用程序能够设定此参数为TRUE 以取消导航操作或者设定为FALSE 以允许新建窗口操作. 设定Cancel 为 TRUE 完全取消新建窗口操作和导航. 如果你不在NewWindow2 事件处理过程中作任何事, 新的 InternetExplorer 对象将自动建立. 一些原因你想控制NewWindow2 事件以便控制新建InternetExplorer 对象. 为什么? 因为你想限制Internet Explorer的实例数量,或者你想控制创建的实例的事件. 以下 NewWindow2 事件控制函数中; 建立了一个新的, 隐藏的, 不可导航的Internet Explorer实例; 并且设定ppDisp 参数指向新实例.如果你想,你可以加入任何接收新实例事件的代码. void CMyEvtSink::NewWindow2(LPDISPATCH* ppDisp, BOOL* Cancel) { // Note that m_pIE is a class member of type IWebBrowser2*. HRESULT hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (void**)&m_pIE); if (hr == S_OK) *ppDisp = (IDispatch*)pIE; // Do not set Cancel to TRUE. If you do, // the navigation will be completely canceled. } 另外的原因控制NewWindow2 事件是由于你想你应用程序在用户选择在新窗口打开一个url时进行控制. 如果你不进行控制NewWindow2 事件, Internet Explorer 新实例将被创建. 以下为控制新建窗口的vb代码: Private Sub WebBrowser1_NewWindow2(ppDisp As Object, Cancel As Boolean) Dim frmWB As Form1 Set frmWB = New Form1 Set ppDisp = frmWB.WebBrowser1.Object frmWB.Visible = True Set frmWB = Nothing End Sub 在此NewWindow2 事件代码中,档一个新常口需要被创建, 我们建立一个新的当前窗体Form1 的拷贝. 在此表单窗体, 相当于Internet Explorer的新实例,将处理导航. 在mfc中我们需要首先加入NewWindow2 事件的映射条目到视图类的事件映射宏. (不要忘记包含 ExDispID.h in, 那里有DISPID_NEWWINDOW2 定义.) ON_EVENT(CMfcWebHostView, IDC_WEBBROWSER, DISPID_NEWWINDOW2, OnNewWindow2, VTS_PDISPATCH VTS_PBOOL) 下一步声明OnNewWindow2 方法: void OnNewWindow2(LPDISPATCH* ppDisp, BOOL* Cancel); 最后实现OnNewWindow2 方法以创建一个新的MfcWebHost窗口实例: void CMfcWebHostView::OnNewWindow2(LPDISPATCH FAR* ppDisp, BOOL FAR* Cancel) { // Ensure that ppDisp is not NULL. // If it is NULL, you probably specified // VT_DISPATCH for the first parameter in // the ON_EVENT macro for NewWindow2 in // the event sink map. The correct parameter // type is VT_PDISPATCH. // ASSERT(ppDisp); if (!ppDisp) return; // Get a pointer to the application object // for this application. // CWinApp* pApp = AfxGetApp(); // Get the correct document template. // CDocTemplate* pDocTemplate; POSITION pos = pApp->GetFirstDocTemplatePosition(); pDocTemplate = pApp->GetNextDocTemplate(pos); ASSERT(pDocTemplate); // Create the new frame. CFrameWnd* pNewFrame = pDocTemplate->CreateNewFrame(GetDocument(), (CFrameWnd*)AfxGetMainWnd()); ASSERT(pNewFrame); // Activate the frame, and set its active view. // pDocTemplate->InitialUpdateFrame(pNewFrame, NULL); CMfcWebHostView* pWbView = (CMfcWebHostView*)pNewFrame->GetActiveView(); ASSERT(pWbView); *ppDisp = pWbView->m_webBrowser.GetApplication(); } 如果你在sid或者mdi应用程序中控制一个WebBrowser控件,实现OnNewWindow2 方法是复杂的且需要知道如何解决同文档模版如何工作. 或许, 如果你在一个给予对话框的应用程序控制一个WebBrowser控件是较为容易的.此处为示例: void CMyDlg::OnNewWindow2(LPDISPATCH FAR* ppDisp, BOOL FAR* Cancel) { m_dlgNewWB = new CMyDlg; m_dlgNewWB->Create(IDD_MYDLG_DIALOG); *ppDisp = m_dlgNewWB->m_webBrowser.GetApplication(); } 记住当你完成打开的新对话框后删除(delete) m_dlgNewWB . 且不要在CMyDlg::OnInitDialog 方法中导航, 因为这样代码将不会工作. ProgressChange ProgressChange 事件通告你的应用程序下在操作状态已经更新. ProgressChange 有两个参数: · Progress. 总计有多少进度将被展示, 如果为-1 表示整个进度已经完成 ProgressMax. 最大进度值 容器可通过此事件显示下载进度。 事件发生序列 下图展示了IE的事件发生序列.但这仅仅为不包含帧的普通网页浏览. (没有包含诸如 ProgressChange , CommandStateChange , OnToolBar , 等等事件.)不是所有事件都会被激发. 但是 BeforeNavigate2 和DocumentComplete 每次浏览都会被激发. Figure 7-5. The sequence of events fired by the WebBrowser control during a typical navigation.