2012-07-25 107 views

回答

1

我已经得到了答案...! 尝试此代码以获取驻留在网页中的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); 
    } 
1

为了摆脱横框问题 我们的改变一行代码而附加的事件处理程序框架的文件。

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); 
} 
+0

我也期待这一点。我想要的是将事件处理程序附加到iframe中的元素。但我获得拒绝例外。我已经尝试了你的方法,但我不知道如何在我的类中实现'QueryService'方法。你可以把这些代码放在一边,或者给出一个提示。谢谢 – 2014-08-11 13:28:54

1

我有这样做的另一种方式......

  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([email protected]); 
     } 
    } 

     public void Mouse_Down(IHTMLEventObj e) 
     { 
     IHTMLElement element = (mshtml.IHTMLElement)e.srcElement; 
     label1.Text = element.id; 

     } 
相关问题