none
使用SHDocVw.InternetExplorer编程时遇到的问题 RRS feed

  • 问题

  • 用IE访问网页后,希望用代码将显示窗口移动到指定的位置,就如webBrowser1 .Document.Window .ScrollTo (new Point (100,100));所实现的那样。

    因为SHDocVw.InternetExplorer和WebBrowser都是IWebBrowser2接口,所以我在IE.DocumentComplete事件响应中写代码IE.Document.Window .ScrollTo (new Point (100,100));希望能达到目的。

    但是VS智能提示Window属性:“(动态表达式)此操作将在运行时解析”,这和WebBrowser的情况就不一样了!再运行调试,则引发异常:“mshtml.HTMLDocumentClass”未包含“Window”的定义。

    我的代码没写对吗?谢谢指教!

    2011年10月15日 3:37

答案

  • 是的,C#不是后期绑定的语言,而且类型库里也没有说Docuent一定是HTMLDocument,在运行的时候用户可能浏览到PDF或者Office文件,或者浏览到图片文件。

    你不应该使用后期绑定的类型库,而应该使用IHTMLDocument2这样的接口。后期绑定的类型库是不保证兼容多个IE版本的。

    另外不能直接写IWebBrowser2.Document.Window, IWebBrowser2 .Document这里可以有各种各样的原因返回Null,比如没下载完网页、文档不是网页等等。



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    • 已标记为答案 JSHZP 2011年10月17日 6:30
    2011年10月15日 15:17
    版主
  • 这是很正常的,你没有等Navigate完成就访问了文档。你应该等DocumentCompleted之后再访问。



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    • 已标记为答案 JSHZP 2011年10月17日 6:30
    2011年10月16日 5:23
    版主
  • 转成 IHTMLDocument2

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    • 已标记为答案 JSHZP 2011年10月17日 6:30
    2011年10月16日 6:40
    版主
  •  mshtml.IHTMLDocument2  doc = IE.Document; doc.parentWindow.scrollTo(100,100);                
    这两句用Form.Invoke调用吧。


    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    • 已标记为答案 JSHZP 2011年10月17日 6:30
    2011年10月16日 14:00
    版主
  • 这是因为调用IE_DocumentComplete时,网页并未加载完

    IE.Navigate("http://www.163.com");
     while (IE.ReadyState != SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE)
                {

                }

                mshtml.IHTMLDocument2 doc = IE.Document;
                doc.parentWindow.scrollTo(100, 1000);

     

    void IE_DocumentComplete(object pDisp, ref object URL)
            {
                Console.WriteLine(URL);
              
               
            }


    http://feiyun0112.cnblogs.com/
    2011年10月17日 4:11
    版主

全部回复

  • 是的,C#不是后期绑定的语言,而且类型库里也没有说Docuent一定是HTMLDocument,在运行的时候用户可能浏览到PDF或者Office文件,或者浏览到图片文件。

    你不应该使用后期绑定的类型库,而应该使用IHTMLDocument2这样的接口。后期绑定的类型库是不保证兼容多个IE版本的。

    另外不能直接写IWebBrowser2.Document.Window, IWebBrowser2 .Document这里可以有各种各样的原因返回Null,比如没下载完网页、文档不是网页等等。



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    • 已标记为答案 JSHZP 2011年10月17日 6:30
    2011年10月15日 15:17
    版主
  • 是的,C#不是后期绑定的语言,而且类型库里也没有说Docuent一定是HTMLDocument,在运行的时候用户可能浏览到PDF或者Office文件,或者浏览到图片文件。

    你不应该使用后期绑定的类型库,而应该使用IHTMLDocument2这样的接口。后期绑定的类型库是不保证兼容多个IE版本的。

    另外不能直接写IWebBrowser2.Document.Window, IWebBrowser2 .Document这里可以有各种各样的原因返回Null,比如没下载完网页、文档不是网页等等。



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP

    非常感谢您的讲解!

    我把代码改成了下面这样:

    SHDocVw.InternetExplorer IE = new SHDocVw.InternetExplorer(); 
    IE.Navigate("http://www.163.com"); 
    mshtml.HTMLDocument doc = IE.Document;
    doc.parentWindow.scrollTo(100,100);
    

    调试时最后一句话引发了两个异常:其一,“调用的目标发生了异常。”, 异常类型System.Reflection.TargetInvocationException  其二,“指定的转换无效。”异常类型System.InvalidCastException

    期待继续指教。。。 


    • 已编辑 JSHZP 2011年10月16日 3:40
    2011年10月16日 3:39
  • 这是很正常的,你没有等Navigate完成就访问了文档。你应该等DocumentCompleted之后再访问。



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    • 已标记为答案 JSHZP 2011年10月17日 6:30
    2011年10月16日 5:23
    版主
  • 把相关代码改到DocumentComplete事件响应中,如下:

            IE.DocumentComplete += new SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(IE_DocumentComplete);
    
            void IE_DocumentComplete(object pDisp, ref object URL)
            {
                try
                {                
                    mshtml.HTMLDocument doc = IE.Document;
                    doc.parentWindow.scrollTo(100,100);                
                }
                catch
                {                
                }
            }
    

    但是仍然会catch到“指定的转换无效。”的异常。并且,最终网页也没能移动到指定的(100,100)的位置。会是什么原因呢?

    2011年10月16日 6:35
  • 转成 IHTMLDocument2

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    • 已标记为答案 JSHZP 2011年10月17日 6:30
    2011年10月16日 6:40
    版主
  • 改成下面的代码,仍然是同样的问题:

                try
                {                
                    mshtml.IHTMLDocument2 doc = IE.Document;
                    doc.parentWindow.scrollTo(100,100);                
                }
                catch
                {                
                }
    

     



    • 已编辑 JSHZP 2011年10月16日 6:58
    2011年10月16日 6:54
  • 你的代码不会在子线程里面执行吧?IE是STA对象,应该在主线程调用。

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    2011年10月16日 7:02
    版主
  • 全部的代码,有劳蒋老师了!

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using mshtml;
    
    namespace WindowsFormsApplication18
    {
        public partial class Form1 : Form
        {
            SHDocVw.InternetExplorer IE;
    
            public Form1()
            {
                InitializeComponent();
                IE = new SHDocVw.InternetExplorer();
                IE.Navigate("http://www.163.com");
                IE.Visible = true;
                
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                IE.DocumentComplete += new SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(IE_DocumentComplete);
                this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
                this.Show();            
            }
    
            void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                try
                {
                    IE.Quit();
                }
                catch { }
            }
    
            void IE_DocumentComplete(object pDisp, ref object URL)
            {
                try
                {
                    mshtml.IHTMLDocument2  doc = IE.Document;
                    doc.parentWindow.scrollTo(100,100);                
                }
                catch
                {                
                }
            }
        }
    }
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication18
    {
        static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
        }
    }
    



    2011年10月16日 7:07
  •  mshtml.IHTMLDocument2  doc = IE.Document; doc.parentWindow.scrollTo(100,100);                
    这两句用Form.Invoke调用吧。


    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    • 已标记为答案 JSHZP 2011年10月17日 6:30
    2011年10月16日 14:00
    版主
  • 你打断点跟踪看看IE.Document到底是什么类型
    http://feiyun0112.cnblogs.com/
    2011年10月17日 1:45
    版主
  • 你打断点跟踪看看IE.Document到底是什么类型
    http://feiyun0112.cnblogs.com/

    调试中断后:名称IE.Document,值 {mshtml.HTMLDocumentClass},类型 dynamic {mshtml.HTMLDocumentClass}
    2011年10月17日 3:02
  •  mshtml.IHTMLDocument2  doc = IE.Document; doc.parentWindow.scrollTo(100,100);                
    这两句用Form.Invoke调用吧。


    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP


    这两句话修改成如下,问题果真解决了!

    this.Invoke(new EventHandler(TheMethod));
    
    void TheMethod(object sender, EventArgs e)
            {
                try
                {
                    mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)IE.Document;
                    doc.parentWindow.window.scrollTo(100, 100);
                }
                catch
                { }
            }
    

    但是没想明白其中的道理,望高手能予以解释,不胜感激!

    2011年10月17日 3:24
  • 这是因为调用IE_DocumentComplete时,网页并未加载完

    IE.Navigate("http://www.163.com");
     while (IE.ReadyState != SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE)
                {

                }

                mshtml.IHTMLDocument2 doc = IE.Document;
                doc.parentWindow.scrollTo(100, 1000);

     

    void IE_DocumentComplete(object pDisp, ref object URL)
            {
                Console.WriteLine(URL);
              
               
            }


    http://feiyun0112.cnblogs.com/
    2011年10月17日 4:11
    版主