C#Web浏览器,单击并突出显示Frame / iFrame元素

Iam正在寻找一个浏览器控件,用户可以在网页中预览帧/ iframe,然后突出显示它的元素,一旦突出显示,我就可以得到所选元素的div或id。

我们有什么方法可以做到吗?

我有答案……! 尝试使用此代码来获取驻留在网页中的iframe和框架,并为其添加文档处理程序。 它很简单,我们需要为每个帧/ iframe添加文档处理程序。

private void webBrowser1_DocumentCompleted_1(object sender, WebBrowserDocumentCompletedEventArgs e) { if (this.webBrowser1.ReadyState != WebBrowserReadyState.Complete) return; else { HtmlDocument _document = webBrowser1.Document; _document.MouseOver += new HtmlElementEventHandler(document_MouseOver); _document.MouseLeave += new HtmlElementEventHandler(document_MouseLeave); mshtml.HTMLDocumentEvents2_Event iEvent; IHTMLDocument2 currentDoc = (IHTMLDocument2)webBrowser1.Document.DomDocument; iEvent = (mshtml.HTMLDocumentEvents2_Event)currentDoc; iEvent.onclick += new mshtml.HTMLDocumentEvents2_onclickEventHandler(clickDocumentHandler); if (currentDoc.frames.length > 0) { FramesCollection FrameList = currentDoc.frames; for (int i = 0; i < FrameList.length; i++) { object id = (object)i; IHTMLWindow2 frameWindow = (IHTMLWindow2)FrameList.item(ref id); IHTMLDocument2 frameDocument = (IHTMLDocument2)frameWindow.document; iEvent = (mshtml.HTMLDocumentEvents2_Event)frameDocument; iEvent.onclick += new mshtml.HTMLDocumentEvents2_onclickEventHandler(clickDocumentHandler); } } } } private bool clickDocumentHandler(IHTMLEventObj pEvtObj) { IHTMLElement element = (mshtml.IHTMLElement)pEvtObj.srcElement; label2.Text = element.id; pEvtObj.cancelBubble = true; pEvtObj.returnValue = false; return false; } private bool clickElementHandler(IHTMLEventObj pEvtObj) { IHTMLElement element = (mshtml.IHTMLElement)pEvtObj.srcElement; label1.Text = element.id; pEvtObj.cancelBubble = true; pEvtObj.returnValue = false; return false; } private void document_MouseOver(object sender, HtmlElementEventArgs e) { HtmlElement element = e.FromElement; mshtml.HTMLElementEvents2_Event iEvent; iEvent = element.DomElement as mshtml.HTMLElementEvents2_Event; if (iEvent == null) return; iEvent.onclick += new mshtml.HTMLElementEvents2_onclickEventHandler(clickElementHandler); } private void document_MouseLeave(object sender, HtmlElementEventArgs e) { HtmlElement element = e.FromElement; mshtml.HTMLElementEvents2_Event iEvent; iEvent = element.DomElement as mshtml.HTMLElementEvents2_Event; if (iEvent == null) return; iEvent.onclick -= new mshtml.HTMLElementEvents2_onclickEventHandler(clickElementHandler); } 

为了摆脱跨框架问题我们必须在将事件处理程序附加到框架文档时更改一行代码。

  IHTMLDocument2 frameDocument = (IHTMLDocument2) CrossFrame.GetDocumentFromWindow (frameWindow); 

包括Interop.SHDocVw.dll并添加以下类:

  public class CrossFrame { // Returns null in case of failure. public static IHTMLDocument2 GetDocumentFromWindow(IHTMLWindow2 htmlWindow) { if (htmlWindow == null) { return null; } // First try the usual way to get the document. try { IHTMLDocument2 doc = htmlWindow.document; return doc; } catch (COMException comEx) { // I think COMException won't be ever fired but just to be sure ... if (comEx.ErrorCode != E_ACCESSDENIED) { return null; } } catch (System.UnauthorizedAccessException) { } catch { // Any other error. return null; } // At this point the error was E_ACCESSDENIED because the frame contains a document from another domain. // IE tries to prevent a cross frame scripting security issue. try { // Convert IHTMLWindow2 to IWebBrowser2 using IServiceProvider. IServiceProvider sp = (IServiceProvider)htmlWindow; // Use IServiceProvider.QueryService to get IWebBrowser2 object. Object brws = null; sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out brws); // Get the document from IWebBrowser2. SHDocVw.IWebBrowser2 browser = (SHDocVw.IWebBrowser2)(brws); return (IHTMLDocument2)browser.Document; } catch { } return null; } private const int E_ACCESSDENIED = unchecked((int)0x80070005L); private static Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046"); private static Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E"); } // This is the COM IServiceProvider interface, not System.IServiceProvider .Net interface! [ComImport(), ComVisible(true), Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] public interface IServiceProvider { [return: MarshalAs(UnmanagedType.I4)] [PreserveSig] int QueryService(ref Guid guidService, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject); } 

我有另一种做法……

  using System.Runtime.InteropServices; 

宣布代表

  public delegate void DOMEvent(IHTMLEventObj e); private void webBrowser1_DocumentCompleted_1(object sender, WebBrowserDocumentCompletedEventArgs e) { if (this.webBrowser1.ReadyState != WebBrowserReadyState.Complete) return; else { HTMLDocument htmlDoc = (HTMLDocument)this.webBrowser1.Document.DomDocument; DispHTMLDocument doc = (DispHTMLDocument)htmlDoc; DOMEventHandler onmousedownhandler = new DOMEventHandler(doc); onmousedownhandler.Handler += new DOMEvent(Mouse_Down); doc.onmousedown = onmousedownhandler; if (htmlDoc.frames.length > 0) { FramesCollection FrameList = htmlDoc.frames; for (int i = 0; i < FrameList.length; i++) { object id = (object)i; IHTMLWindow2 frameWindow = (IHTMLWindow2)FrameList.item(ref id); HTMLDocument frameDoc = (HTMLDocument)frameWindow.document; DispHTMLDocument frameDispDoc = (DispHTMLDocument)frameDoc; DOMEventHandler onmousedownhand = new DOMEventHandler(frameDispDoc); onmousedownhand.Handler += new DOMEvent(Mouse_Down); frameDispDoc.onmousedown = onmousedownhand; } } } } public class DOMEventHandler { public DOMEvent Handler; DispHTMLDocument Document; public DOMEventHandler(DispHTMLDocument doc) { this.Document = doc; } [DispId(0)] public void Call() { Handler(Document.parentWindow.@event); } } public void Mouse_Down(IHTMLEventObj e) { IHTMLElement element = (mshtml.IHTMLElement)e.srcElement; label1.Text = element.id; }