WinForms C#:html编辑器工程源码,含直接写WebBrowser的文件流、IPersistStreamInit接口的声明和一些相关的小方法

首先多谢朋友们的捧场;

今天给大家带来一个操作WebBrowser的一些高级方法,我专门写了一个html编辑器的实现代码,有需要的朋友可以自己扩充;
功能实现是直接写流到WebBrowser内不通过临时文件,并且支持对WebBrowser的一些高级控制(其实script可以达到的均可达到,想知道怎么搞的可以阅读代码)。

其中关于IPersistStreamInit接口的声明费了翻工夫,因为以前在 delphi 中没这么麻烦,呵呵。在网络上找了大半天没找到,最后还是祭出Reflector,反编译Windows.Forms,需要的朋友可以不用辛苦的自己搞了!

我在这个演示里,制作的html编辑环境是比简单的,您可以看看,比较比较 CodeProject 上的代码;我采用的是ie自身提供的编辑方法,只是这样的方式都被运用于web方式的编辑器内,就好比这个freeTextBox

以下是主要的代码:
  1    /********************************
  2     * 初始化浏览器状态
  3     * 指向about:blank
  4     * *****************************/

  5    private void Form1_Load(object sender, System.EventArgs e) {
  6      object obj = null;
  7      this.Show();
  8      this.axWb.Navigate("about:blank",ref obj,ref obj,ref obj,ref obj);      
  9      //等待完成动作
 10      while(axWb.ReadyState < SHDocVw.tagREADYSTATE.READYSTATE_INTERACTIVE)
 11        Application.DoEvents();
 12
 13      //初始化html编辑器
 14      InitHtmlEditor();
 15    }

 16
 17    /*******************************
 18     * 这里是核心方法
 19     * 完全调用IE自身的html编辑功能
 20     * 可以看到,我采用了一种兼容的
 21     * 方式,用Frame(框架),这样
 22     * 的话,默认安装的Windows 98都
 23     * 支持html编辑功能;
 24     * 关键代码如下:
 25     * frame.document.designMode = "on";
 26     * 表示开启设计模式
 27     ******************************/

 28    private void InitHtmlEditor(){
 29      string sw = "";
 30      sw += "<html>\r\n";
 31      sw += "<script language=javascript>\r\n";
 32      sw += " function loadSet(){\r\n";
 33      sw += "  var frame=document.getElementById(\"i-frame\").contentWindow;\r\n";
 34      sw += "  frame.document.designMode = \"on\";\r\n";
 35      sw += "  frame.document.open();\r\n";
 36      sw += "  frame.document.write(\"<html><font color=red>hello 大家好啊!<br>我是S.F. <br>";
 37      sw += "  <a href=\\\"http://www.cnblogs.com/chinasf\\\">欢迎访问我的weblog</a></font></html>\");\r\n";
 38      sw += "  frame.document.close();\r\n";
 39      sw += " }\r\n";
 40      sw += " function setBlod(obj){\r\n";
 41      sw += "  document.getElementById(\"i-frame\").contentWindow.document.execCommand(\"bold\");\r\n";
 42      sw += " }\r\n";
 43      sw += "</script>\r\n";
 44      //这里加入了一个html的button,也就是说,你可以把web模式的html编辑器的代码完全copy进来
 45      sw += "<body onload=\"loadSet()\" scroll=\"yes\"><button onclick=\"setBlod(this);\">Blod</button>\r\n";
 46      sw += "<iframe id=\"i-frame\" frameBorder=\"1\" width=\"640\" height=\"480\"></iframe>\r\n";
 47      sw += "</body></html>\r\n";
 48
 49      //写入浏览器
 50      WriteHtml(sw);
 51    }

 52
 53    private void WriteHtml(string s){
 54      //内存流,用于转换string
 55      MemoryStream ms = new MemoryStream();
 56      try{
 57        byte[] htmlcode = System.Text.Encoding.Default.GetBytes(s);
 58        ms.Write(htmlcode,0,htmlcode.Length);
 59        Stream dataStream = ms;
 60        //恢复指针位置
 61        dataStream.Seek(0,0);
 62
 63        if(axWb.Document!=null){
 64          //转换接口,并转换为IStream
 65          (axWb.Document as UnsafeNativeMethods.IPersistStreamInit).Load(new UnsafeNativeMethods.ComStreamFromDataStream(dataStream));
 66        }

 67      }
finally{
 68        ms.Close();
 69      }

 70    }

 71
 72    private void button1_Click(object sender, System.EventArgs e) {
 73      //获取document,在IHTMLDocument2中取得桢
 74      mshtml.IHTMLDocument3 idoc = (mshtml.IHTMLDocument3)axWb.Document;
 75      mshtml.IHTMLFrameBase2 fb= (mshtml.IHTMLFrameBase2)idoc.getElementById("i-frame");
 76      object obj=null;
 77      fb.contentWindow.document.execCommand("bold",true,obj);
 78    }

 79
 80    private void button3_Click(object sender, System.EventArgs e) {
 81      //获取document,在IHTMLDocument2中才有body.style
 82      mshtml.IHTMLDocument2 idoc = (mshtml.IHTMLDocument2)axWb.Document;
 83      //指定为IHTMLStyle3,才可以定制滚动条颜色
 84      mshtml.IHTMLStyle3 istyle = (mshtml.IHTMLStyle3)idoc.body.style;
 85      istyle.scrollbarArrowColor = "#0099FF";
 86      istyle.scrollbar3dLightColor = "#FFFFFF";
 87      istyle.scrollbarDarkShadowColor = "#0099FF";
 88      istyle.scrollbarFaceColor = "#99CCFF";
 89      istyle.scrollbarHighlightColor = "#0099FF";
 90      istyle.scrollbarShadowColor = "#0099FF";
 91      istyle.scrollbarTrackColor = "#FFFFFF";
 92
 93    }

 94
 95    private void button2_Click(object sender, System.EventArgs e) {
 96      //查看源码,文本方式
 97      mshtml.IHTMLDocument3 idoc = (mshtml.IHTMLDocument3)axWb.Document;
 98      mshtml.IHTMLFrameBase2 fb= (mshtml.IHTMLFrameBase2)idoc.getElementById("i-frame");
 99      MessageBox.Show(fb.contentWindow.document.body.innerText);
100    }

101
102    private void button4_Click(object sender, System.EventArgs e) {
103      //查看源码,HTML方式
104      mshtml.IHTMLDocument3 idoc = (mshtml.IHTMLDocument3)axWb.Document;
105      mshtml.IHTMLFrameBase2 fb= (mshtml.IHTMLFrameBase2)idoc.getElementById("i-frame");
106      MessageBox.Show(fb.contentWindow.document.body.innerHTML);
107    }


这里下载完整工程代码。

2005年4月26日 欢迎指点批评!演示是很简陋的

posted @ 2005-04-26 17:11 萧寒 阅读(17831) 评论(34) 编辑 收藏

 回复 引用 查看   
#1楼[楼主] 2005-04-26 17:14 萧寒      
其中的getElementById("i-frame") 方法获取的是设计模式的桢,制作过web htmleditor的朋友会很熟悉。
 回复 引用   
#2楼 2005-04-27 15:25 阿良[未注册用户]
初学,不懂,可以详细说一说怎样用吗?
 回复 引用 查看   
#3楼[楼主] 2005-04-27 16:39 萧寒      
以上是实现了直接通过写WebBrowser的流;也就是说不需要装入.htm文件而直接显示内容,如果你需要这方面应用的话这个会对你有帮助。
 回复 引用   
#4楼 2005-04-30 14:06 TSL
不错,谢谢了,不过好像只能写HTML和图片的流,要是能把PDF的流抛进去能自动打开ACROBAT就好了
 回复 引用 查看   
#5楼[楼主] 2005-04-30 17:01 萧寒      
当然可以把pdf放进去,你试试看吧,打开C:\Test.pdf文件
把原来的函数替换成这样
private void InitHtmlEditor(){
string sw = "";
sw += "<html>\r\n";
sw += "<body scroll=\"yes\">\r\n";
sw += "<embed width=\"100%\" height=\"100%\" src=\"file:///C:/Test.pdf\"><noembed>你机器不支持PDF阅读!</noembed></p>\r\n";
sw += "</body></html>\r\n";

//写入浏览器
WriteHtml(sw);
}

 回复 引用   
#6楼 2005-04-30 17:44 S.F.
我大概明白你的意思了;你是指直接将PDF文件流写入浏览器吗?我做做看
 回复 引用 查看   
#7楼[楼主] 2005-05-01 23:44 萧寒      
浏览器好象是能通过文件类型判断打开;直接写入的话显示的是2进制数据,没用。
 回复 引用   
#8楼 2005-08-12 23:37 佚名[未注册用户]
感谢这篇文章,感谢作者,钦佩作者的高水平,更钦佩作者的奉献精神,榜样.
以后有项目的话争取能和作者这样的高人合作.

 回复 引用 查看   
#9楼[楼主] 2005-08-16 09:04 萧寒      
@佚名

你的评价让我惭愧,我现在再看这个笔记,发现了不少可以重构的地方:)

 回复 引用   
#10楼 2005-08-24 08:09 zhaojian[未注册用户]
谢谢,就是需要这样的工具,感觉有点复杂
 回复 引用   
#11楼 2006-01-25 15:43 dq[未注册用户]
我有一个问题请教高手一下:

以下代码是用browser打开一个文件并进行后续处理,我的问题是:如何批处理用browser打开一批文件并传递给后续处理模块?

//Get the document
CWebBrowser2 m_webBrowser;

MSHTML::IHTMLDocument2Ptr pHTMLDoc = m_webBrowser.GetDocument();

//make analysis on the document
m_pLayoutAnalyzer->Analyze4(pHTMLDoc,_variant_t((long)m_iPDOC));

thanks you !thanks you !thanks you !thanks you !thanks you !thanks you !
 回复 引用   
#13楼 2006-03-16 02:04 chinasf
告诉大家一个好消息;

visual studio 2005 提供的webBrowser组件可以不需要这样麻烦的写入HTML内容了;

方法很简单:
webBrowser.document.Write("<html>.................</html>"); //如此即可。

 回复 引用   
#14楼 2006-03-16 12:26 赵瑜[未注册用户]
请问如何声明IPersistInit呢?能否详细地说说?非常谢谢,我最近在做这方面的工作,但不知如何声明,望回复
怎么在编辑窗口内的控件上右击鼠标时对控件的属性进行设置呢,哪位兄弟指教下我在做个编辑器,就是这里过不了,万分感谢
我写的就是以这个示例来开始的,谢谢发贴的兄弟
 回复 引用   
#17楼 2006-04-14 10:12 蛐蛐[未注册用户]
如果涉及到字体和颜色,应如何写呢?
 回复 引用   
#18楼 2006-04-19 20:59 xiaoyi0314[未注册用户]
楼主:
有个问题哈,我不想用frame可以么,那以下这句话
mshtml.IHTMLFrameBase2 fb= (mshtml.IHTMLFrameBase2)idoc.getElementById("i-frame");
该换成什么接口呢,多谢

 回复 引用   
#19楼 2006-04-19 21:00 xiaoyi0314[未注册用户]
楼主:
有个问题哈,我不想用frame可以么,那以下这句话
mshtml.IHTMLFrameBase2 fb= (mshtml.IHTMLFrameBase2)idoc.getElementById("i-frame");
该换成什么接口呢,多谢

 回复 引用   
#20楼 2006-05-18 20:39 hpv[未注册用户]
在vs 2005中,用2句话可以实现HTML编辑功能。

第一步:
在窗体中添加webBrowser1控件(.net 2.0新增控件),

第二步
在Form_Load中添加代码如下:

webBrowser1.Navigate("about:blank");
webBrowser1.Document.DomDocument.GetType().GetProperty("designMode").SetValue(webBrowser1.Document.DomDocument, "On", null);

 回复 引用   
#21楼 2006-06-02 12:03 袁生[未注册用户]
您好,我想问一下怎么给文本设字体,颜色啊。望回c#

我的邮箱:yuanzhihua520@163.com

 回复 引用   
#22楼 2006-07-07 15:24 webcool
请问(axWb.Document as UnsafeNativeMethods.IPersistStreamInit).Load(new UnsafeNativeMethods.ComStreamFromDataStream(dataStream));
转换为vb.net怎么写啊?

 回复 引用 查看   
#23楼 2006-07-13 00:00 U2U      
除了说作者强,无语……刚好这就是我需要的,作者——I Love U!我要与你联系!!!!
 回复 引用   
#24楼 2006-07-27 18:14 huahau[未注册用户]
2003 怎么在对freetextbox付值?
 回复 引用 查看   
#25楼[楼主] 2006-07-31 21:59 萧寒      
@huahau
没有研究过对freetextbox赋值

@U2U
认识你很高兴

 回复 引用   
#26楼 2006-09-30 21:33 peter[匿名][未注册用户]
这个好像和codeProject的例子很像
 回复 引用   
#27楼 2006-10-22 12:07 Rong[匿名][未注册用户]
thank you ..我找这个东西找很久了~.
怎么在编辑窗口内的控件上右击鼠标时对控件的属性进行设置呢,哪位兄弟指教下我在做个编辑器,就是这里过不了,万分感谢
 回复 引用   
#29楼 2006-12-29 17:40 Michael[匿名][未注册用户]
不得不佩服!真好在找这个!
 回复 引用   
#30楼 2007-03-26 16:03 freebird911[未注册用户]
请问,如果要修改文本筐中的内容应该怎么做呀?
 回复 引用   
#31楼 2007-09-14 13:57 郭杰[未注册用户]
感谢楼主这么好的文章!我有个问题希望楼主予以解答
功能:有TextBox、Button、WebBrower控件。TextBox中输入URL地址,点击Button后实现将URL赋给WebBrower的Navigate,并在WebBrower显示URL的页面内容。
代码如下:
Wb.Navigate("www.google.cn");//Wb是个WebBrower控件
//设置WebBrower控件可编辑状态
Wb.Document.DomDocument.GetType().GetProperty("designMode").SetValue(Wb.Document.DomDocument, "On", null);
程序执行后就可以在Wb中删除/添加文字等操作。若此时为Wb.Navigate重定向,如:www.baidu.com。此时系统会弹出对话框,提示:“该文档已被修改,是否保存修改结果?”,若点击保存,即可保存到本地磁盘,但是问题保存的是编辑前的页面,我要保存编辑后的页面,怎么实现?或者干脆不让弹出网页保存对话框,这样我可直接保存InnerHtml

 回复 引用 查看   
#32楼 2008-04-25 11:06 知秋      
我说呢楼主忽悠我,吓我一跳,我还以为是在线HTML编辑器呢!
 回复 引用   
#33楼 2008-08-28 17:18 yoling[未注册用户]
《C# Webbrowser控件 查看HTML源码-解说!》
http://cnbody.com.cn/bbs/showtopic-111.aspx

 回复 引用 查看   
#34楼 2010-10-27 23:29 鬼神      
写得很不错.MARK.