C# (转载)webbrowser专题(参考资料:https://www.cnblogs.com/blogpro/p/11458390.html)

C# .Net 2.0实例学习:WebBrowser页面与WinForm交互技巧 2javascript

Study Case 4:高亮显示 

上一个例子中咱们学会了查找文本——究跟到底,对Web页面仍是只读不写。那么,若是说要把全部的搜索结果高亮显示呢?咱们很快会想到把全部匹配的文字颜色、背景改一下就能够了。首先想到的多是直接修改HTML文本吧……可是,与SourceCode的高亮显示不一样,咱们须要而且只须要高亮页面中的文本部分。HTML标签、脚本代码等等是绝对不该该去改动的。所以咱们不能把整个页面的Source Code读进来而后replace,那样有破坏HTML文件结构的可能;咱们只能在可以分离出文本与其余内容(标签,脚本……)的前提下进行。

具体方法有不少,下面提供两个比较简单的方法。
方法一:使用TextRange(IHTMLTxtRange) 
有了上一个Case的基础,相信你们马上会想到使用TextRange。没错,TextRange除了提供查找方法以外,还提供了一个pasteHTML方法,以指定的HTML文本替换当前TextRange中的内容。代码片段以下:
    public partial class HilightDemo : Form
     {
        // 定义高亮显示效果的标签。
        string tagBefore = "<span style='background-color:yellow;color:black'>";
        string tagAfter = "</span>";

        // ……

        private void btnHilight_Click(object sender, EventArgs e)
         {
             HtmlDocument htmlDoc = webBrowser.Document;
            string keyword = txtKeyword.Text.Trim();
            if (keyword == "")
                return;

            object oTextRange = htmlDoc.Body.InvokeMember("createTextRange");

             mshtml.IHTMLTxtRange txtrange = oTextRange as mshtml.IHTMLTxtRange;

            while (txtrange.findText(keyword, 1, 4))
             {
                try 
                 {
                     txtrange.pasteHTML(tagBefore + keyword + tagAfter);
                 }
                catch { }
                 txtrange.collapse(false);
             }
         }
     }

※这段代码里获取IHTMLTxtRange的方式和上面的例子稍稍不一样,其实所谓条条大路通罗马,本质是同样的。

方法二:使用DOM(文档对象模型)
将HTML文档解析为DOM,而后遍历每一个节点,在其中搜索关键字并进行相应替换处理便可。
    public partial class HilightDemo : Form
     {
        //……

        private void btnHilight_Click(object sender, EventArgs e)
         {
             HTMLDocument document = (HTMLDocument)webBrowser.Document.DomDocument;
             IHTMLDOMNode bodyNode = (IHTMLDOMNode)webBrowser.Document.Body.DomElement;
            string keyword = txtKeyword.Text.Trim();
            if (keyword == "")
                return;

             HilightText(document, bodyNode, keyword);
         }

        private void HilightText(HTMLDocument document, IHTMLDOMNode node, string keyword)
         {
            // nodeType = 3:text节点
            if (node.nodeType == 3)
             {
                string nodeText = node.nodeValue.ToString();
                // 若是找到了关键字
                if (nodeText.Contains(keyword))
                 {
                     IHTMLDOMNode parentNode = node.parentNode;
                    // 将关键字做为分隔符,将文本分离,并逐个添加到原text节点的父节点
                    string[] result = nodeText.Split(new string[] { keyword }, StringSplitOptions.None);
                    for (int i = 0; i < result.Length - 1; i++)
                     {
                        if (result[i] != "")
                         {
                             IHTMLDOMNode txtNode = document.createTextNode(result[i]);
                             parentNode.insertBefore(txtNode, node);
                         }
                         IHTMLDOMNode orgNode = document.createTextNode(keyword);
                         IHTMLDOMNode hilightedNode = (IHTMLDOMNode)document.createElement("SPAN");
                         IHTMLStyle style = ((IHTMLElement)hilightedNode).style;
                         style.color = "black";
                         style.backgroundColor = "yellow";
                         hilightedNode.appendChild(orgNode);

                         parentNode.insertBefore(hilightedNode, node);
                     }
                    if (result[result.Length - 1] != "")
                     {
                             IHTMLDOMNode postNode = document.createTextNode(result[result.Length - 1]);
                             parentNode.insertBefore(postNode, node);
                     }
                     parentNode.removeChild(node);
                 } // End of nodeText.Contains(keyword)
             }
            else 
             {
                // 若是不是text节点,则递归搜索其子节点
                 IHTMLDOMChildrenCollection childNodes = node.childNodes as IHTMLDOMChildrenCollection;
                foreach (IHTMLDOMNode n in childNodes)
                 {
                     HilightText(document, n, keyword);
                 }
             }
         }
     }
上面的两段代码都是为了清晰易懂而精简得不能再简的,有不少地方很不完善。好比,没考虑到如何从高亮显示状态复原;也没有大小写匹配等等。固然,掌握了原理以后相信这些都不会太难。

这两种方法各有优缺点:
使用TextRange较轻量迅速,并且有一个特长,就是能够把跨标签(Tag)的关键字挑出来。例如,有这么一段HTML:
<b>Hel</b>lo World!
先无论做者出于什么目的让Hel三个字母成为粗体,总之显示在页面上的是一句“Hello World!”。在咱们但愿高亮页面中的“Hello”这个关键字时,若是用DOM分析的话,会得出含有“Hel”的<b>节点和文本节点“lo World!”两个节点,所以没法将其挑出来。而TextRange则能正确识别,将其设置为高亮。所以也能够说TextRange是只和文本有关,和HTML语法结构无关的对象。

可是,TextRange也有其致命缺点,加亮容易,反向的话就很难。换句话说,去除高亮显示的时候不能再用TextRange,而须要采用其余方法。

而DOM方法则正好相反, 因为DOM的树状结构特性,虽然不能(或者很难)跨越Tag搜索关键字,可是去除高亮显示并不繁琐。

Study Case 5:与脚本的互操做 

在Case 1当中,咱们已经看到,Web页面的HTML元素的事件,能够由Windows Form端来响应,能够在某种程度上看做是Web页面调用WinForm;那么反过来,WinForm除了能够直接访问Web页面的HTML元素以外,可否调用Web页面里的各类Script呢?

首先是调用Web页面的脚本中已经定义好的函数。假设HTML中有以下Javascript:
function DoAdd(a, b) {
    return a + b;
}
那么,咱们要在WinForm调用它,只需以下代码便可:
object oSum = webBrowser.Document.InvokeScript("DoAdd", new object[] { 1, 2 });
int sum = Convert.ToInt32(oSum);
其次,若是咱们想执行一段Web页面中本来没有的脚本,该怎么作呢?此次.Net的类没有提供,看来还要依靠COM了。IHTMLWindow2能够将任意的字符串做为脚本代码来执行。
string scriptline01 = @"function ShowPageInfo() {";
string scriptline02 = @"      var numLinks = document.links.length; ";
string scriptline03 = @"      var numForms = document.forms.length; ";
string scriptline04 = @"      var numImages = document.images.length; ";
string scriptline05 = @"      var numScripts = document.scripts.length; ";
string scriptline06 = @"      alert('网页的统计结果:\r\n连接数:' + numLinks + ";
string scriptline07 = @"         '\r\n表单数:' + numForms + ";
string scriptline08 = @"         '\r\n图像数:' + numImages + ";
string scriptline09 = @"         '\r\n脚本数:' + numScripts);}";
string scriptline10 = @"ShowPageInfo();";

string strScript = scriptline01 + scriptline02 + scriptline03 + scriptline04 + scriptline05 +
                    scriptline06 + scriptline07 + scriptline08 + scriptline09 + scriptline10;

IHTMLWindow2 win = (IHTMLWindow2)webBrowser.Document.Window.DomWindow;
win.execScript(strScript, "Javascript");
OK,今天就写到这里吧,再想起什么来再补充吧。欢迎你们多多指正,欢迎讨论。
View Code

C# WebBrowser制做的HTML文本编辑器php

C# WebBrowser制做的HTML文本编辑器
· 下载源文件(http: //www.codeproject.com/cs/miscctrl/editor_in_windows_forms/editor2_src.zip) - 42.3 Kb
· 下载演示项目(http: //www.codeproject.com/cs/miscctrl/editor_in_windows_forms/editor2_demo.zip) - 19.7 Kb
· 原文:A Windows Forms based text editor with HTML output
· 相似的控件:HTMLTextBox
 简介
刚才,我在编写一个聊天应用程序,其中一个聊天客户端是基于 web 的并以 ASP.NET 2.0 编写,另外一个聊天客户端是 C# 编写的基于 Windows 窗体的 .NET 应用。对于此Windows 窗体客户端,我须要一个能够输出 HTML 的富文本编辑器(a rich text editor) ,以便于 ASP.NET 的客户端能够显示 Windows 窗体客户端的聊天内容。这样,就排除了使用 RTF 文本框的可能。
我设计出的解决方案是在 Windows 窗体客户端,以编辑模式使用一个 WebBrowser 控件。对于 WebBrowser  控件中选定的文本,同时在 WebBrowser 控件的上方放置包含格式按钮的工具栏,以便设置文本格式。
本文说明了这个方案中,使用 WebBrowser 控件创建一个编辑器时的主要难点问题。由于源代码不难理解,我就不深刻介绍了。 可是,我会介绍一些必要的实现技巧。
WebBrowser 控件设计模式设置
当使用此组件时,会自动应用设计模式,并为文档创建一个编辑模板。可是,做为参考,下面简单说明这是如何实现的。
应用设计模式须要使用 COM 接口,添加一个 MSHTML 的 "Microsoft HTML Object Library" 的引用,并添加一个对 'MSHTML''using'。
在把改变写入到 DOM 文档以前,有必要添加一个 body 到控件。要这样作,你能够简单地设置一些文本到 WebBrowser 控件的 DocumentText 属性中。
webBrowser1.DocumentText = "<html><body></body></html>"
下面的代码能够取得新的 DomDocument COM 接口的引用,并设置设计模式为 "On"。
IHTMLDocument2 doc =
webBrowser1.Document.DomDocument as IHTMLDocument2;
doc.designMode = "On";
最后,我把 WebBrowser 控件的上下文菜单替换掉,这样 IE 浏览器的默认上下文菜单就不会显示出来。
webBrowser1.Document.ContextMenuShowing +=
new HtmlElementEventHandler(Document_ContextMenuShowing);
浏览器如今处于设计模式中,使用一个自定义方法来显示指定的上下文菜单。
格式化文本
使用 browser.Document 中的 ExecCommand 方法,你能够把格式和编辑功能应用到设计模式下的浏览器控件。
下面是一些例子:
public void Cut()
{
 webBrowser1.Document.ExecCommand("Cut", false, null);
}
public void Paste()
{
 webBrowser1.Document.ExecCommand("Paste", false, null);
}
public void Copy()
{
 webBrowser1.Document.ExecCommand("Copy", false, null);
}
某些命令用于绑定(显示)当前选区的格式。
public void Bold()
{
 webBrowser1.Document.ExecCommand("Bold", false, null);
}

public void Italic()
{
 webBrowser1.Document.ExecCommand("Italic", false, null);
}
同步刷新选定文本的格式按钮
下面介绍一些比发出格式化命令到浏览器更有用的技巧。每 200 毫秒,我逐一查询浏览器编辑选区的状态,并据此设置工具栏格式按钮的状态。
private void timer_Tick(object sender, EventArgs e)
{
 SetupKeyListener();
 boldButton.Checked = IsBold();
 italicButton.Checked = IsItalic();
 underlineButton.Checked = IsUnderline();
 orderedListButton.Checked = IsOrderedList();
 unorderedListButton.Checked = IsUnorderedList();
 linkButton.Enabled = SelectionType == SelectionType.Text;

 UpdateFontComboBox();
 UpdateFontSizeComboBox();
 if (Tick != null) Tick();
}
你可能已经注意到这儿使用了一个 Tick 计时器事件。外部的组件能够订阅此事件来更新 GUI 的状态。举例来讲,它们将基于编辑器控件的状态,刷新“剪切/复制/粘贴/撤销/重复”(操做)的 Enabled 状态。
我经过使用从 WebBrowser 控件返回的 COM 文档接口,来完成此任务,先使用:
IHTMLDocument2 doc = webBrowser1.Document.DomDocument as IHTMLDocument2;
而后,使用 queryCommandState  方法来肯定当前选区的状态:
public bool IsBold()
{
 return doc.queryCommandState("Bold");
}

public bool IsItalic()
{
 return doc.queryCommandState("Italic");
}

public bool IsUnderline()
{
 return doc.queryCommandState("Underline");
}
链接按钮和字体控件以一种简单的方式管理,但我将会保留以代码检测的方法。
取得焦点
让控件取得焦点不必定是简单的。 WebBrowser 控件自己不接受焦点。 WebBrowser 控件的文档也不接受焦点。可是,body 会取得焦点,能够假定有一个 body 元素在控件中。
private void SuperFocus()
{
 if (webBrowser1.Document != null &&
 webBrowser1.Document.Body != null)
 webBrowser1.Document.Body.Focus();
}
固然,你决不须要直接调用此方法。在控件上调用 Focus 方法,会把焦点放置到包含了 WebBrowser 控件的编辑器控件上。当接收到 GotFocus  事件时,编辑器控件会自动把焦点转到 WebBrowser 控件文档的 body 上。
取得文本或 HTML
分别使用 BodyHtml 和 BodyText 方法,能够返回 HTML 和文本。
链接到组件程序集
在 Visual Studio 2005 中,你能够链接到一个程序集 (添加一个引用),即便程序集是可执行的(文件)。此编辑器是做为内嵌在窗体的组件来编写的,所以你能够把这个组件添加到控件面板上,并把它拖放到你的应用程序中。此控件的名称为 Editor,在命名空间 Design 中。
结束语
.NET 2.0 中的 WebBrowser 控件能够做为一个有效的文本编辑器来使用。当你须要一个 HTML 编辑器控件时,它颇有用。可是在某些范围内,不能彻底直接地使用 WebBrowser 控件来实现。本文试图展现一些让它工做的必要技巧。
View Code

C# webBrowser js 交互 调用css

前面我也有转载过相关文章,当时没有测试,今天测试 ,结果不能用,之前都没注意。
今天整理了一下 。代码以下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Security.Permissions;

namespace test10
{
 [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
 [System.Runtime.InteropServices.ComVisibleAttribute(true)]
 public partial class MainForm : Form
 {
  
  public MainForm()
  {
   InitializeComponent();
   webBrowser1.ObjectForScripting = this;
  }
  
  void MainFormLoad(object sender, EventArgs e)
  {
   string s="";
   s+="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">";
   s+="<HTML>";
   s+=" <HEAD>";
   s+="  <TITLE> New Document </TITLE>";
   s+="  <META NAME=\"Generator\" CONTENT=\"EditPlus\">";
   s+="  <META NAME=\"Author\" CONTENT=\"\">";
   s+="  <META NAME=\"Keywords\" CONTENT=\"\">";
   s+="  <META NAME=\"Description\" CONTENT=\"\">";
   s+="  <script>";
   s+=" function ShopXG(inf)";
   s+=" {";
   s+="  alert(inf);";
   s+=" }";
   s+=" var as = 'as';";
   s+="  </script>";
   s+="";
   s+="";
   s+=" </HEAD>";
   s+="";
   s+=" <BODY>";
   s+="  <input type=\"button\" value=\"调用 js 方法\" onClick=\"ShopXG('123123123')\" />";
   s+="  <input type=\"button\" value=\"调用 C# 方法\" onclick=\"window.external.te('我调用到了 C# 方法');\"/>";//调用 C# 的te 方法
   s+="  <input id=\"btnId\" type=\"button\" value=\"C#添加事件\"/>";
   s+=" </BODY>";
   s+="</HTML>";
   webBrowser1.DocumentText =s;
  }
  
  void Button1Click(object sender, EventArgs e)
  {
   HtmlElement el = webBrowser1.Document.GetElementById("btnId");
   el.Click+= new HtmlElementEventHandler(BtnClick);//为 web 按钮添加事件
  }
  
  void Button2Click(object sender, EventArgs e)
  {
   webBrowser1.Document.InvokeScript("ShopXG", new string[] {"我调用到了 js 方法"});//调用 web ShopXG方法
  }

  void BtnClick(object sender, EventArgs e){
   MessageBox.Show("C# 添加事件到 js");
  }
  
  public void te(string s)
  {
   MessageBox.Show(s);
  }
 }
}
View Code

C#经过webbrowser控件与javascript交互html

C#经过webbrowser控件与javascript交互
1.C#里调用控件里面网页的js函数
// 调用JavaScript的messageBox方法,并传入参数
object[] objects = new object[1];
objects[0] = “C#访问JavaScript脚本”;
this.webBrowser1.Document.InvokeScript(“messageBox”, objects);
//object就是传入的参数,而messageBox则是网页中预约义好的js函数。
经过这种方式C#里面就能够执行Javascript函数,能够把上面的代码放到一个button的click事件里面。
2.C#windows窗体应用webbrowser控件里网页js调用C#窗体的函数
首先须要在代码里面加上
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public partial class Form1 : Form
{
…..//
}
这样使得C#的com对象是对网页里的javascript可见的。
而后在嵌入网页里面经过“window.external.MyMessageBox(‘javascript访问C#代码’)” ,即经过window.external捕获调用c#定义好的函数。
具体Form.cs代码以下(经过vs2008建立的c#window窗体应用,拖拽上一个webbrowser控件和button控件。):
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
System.IO.FileInfo file = new System.IO.FileInfo(“test.html”);
// WebBrowser控件显示的网页路径
this.webBrowser1.Url = new Uri(file.FullName);
// 将当前类设置为可由脚本访问
this.webBrowser1.ObjectForScripting =this;
}
private void button1_Click(object sender, EventArgs e)
{
}
// 提供给JavaScript调用的方法
public void MyMessageBox(string message)
{
MessageBox.Show(message);
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
private void button1_Click_1(object sender, EventArgs e)
{
// 调用JavaScript的messageBox方法,并传入参数
object[] objects = new object[1];
objects[0] = “C#访问JavaScript脚本”;
this.webBrowser1.Document.InvokeScript(“messageBox”, objects);
}
}
test.html内容比较简单:
<html>
<head>
<meta http-equiv=”Content-Language” content=”zh-cn”>
<script language=”javascript” type=”text/javascript”>
<!– 提供给C#程序调用的方法 –>
function messageBox(message)
{
alert(message);
}
</script>
</head>
<body>
<!– 调用C#方法 –>
<button onclick=”window.external.MyMessageBox(‘javascript访问C#代码’)” >
javascript访问C#代码</button>
</body>
</html>
配置运行成功的话,能够看到相互调用的效果,但愿对须要的童鞋有用!
补充一个js调用C#函数的方法:
1,设置脚本对象:

wb.ObjectForScripting = this; // wb为Webbrowser对象
2,公开方法
public void Alert()
{
MessageBox.Show("dkkfdkf");
}
3,而后页面上用javascript能够调用这个方法
external.Alert();
 看了高人的博客,再补充几个,哈:
Winform WebBrowser控件对访问页面执行、改写、添加Javascript代码
 
你们有兴趣能够加我QQ群交流:14792063 广州软件开发团队使用Winform WebBrowser控件对访问页面执行、改写、添加Javascript代码,能够解决许多问题,实现你想要的效果。能够经过引用Microsoft.mshtml,实现对Javascript的操做,代码以下:代码mshtml.IHTMLDocument2 doc = webBrowser1.Document.DomDocument as mshtml.IHTMLDocument2;mshtml.IHTMLWindow2 win = doc.parentWindow as mshtml.IHTMLWindow2;win.execScript(@"alert('hello webbrowser')", "javascript"); 其实还有一种更好的、无需引用Microsoft.mshtml的实现方式:代码HtmlElement ele = webBrowser1.Document.CreateElement("script");ele.SetAttribute("type", "text/javascript");ele.SetAttribute("text", "alert('hello webbrowser')");webBrowser1.Document.Body.AppendChild(ele); 这种使用.Net框架自己所提供的对象,相比引用框架外的COM,好处是显而易见的,这将更方便于安装部署至客户机上。 执行上述两段代码的效果是同样的,都将弹出网页对话框“hello webbrowser”。若是仅是执行Javascript方法,那么,有更简单的且可得到方法返回值的方式,首先假如页面上有以下Javascript方法:function sayHello(to) { alert('hello ' + to); return 'hi, i am javascript';} 在Winform中执行如下代码,首先会弹出网页对话框“hello webbrowser”,而后是Winform的MessageBox对话框“hi, i am javascript” MessageBox.Show(webBrowser1.Document.InvokeScript("sayHello",new object[]{"webbrowser"}).ToString());Winform WebBrowser控件是一个好东西,它不但能够导航网页,还可使用它获取一些在客户端浏览器HTML源代码中没法获取的数据。如使用了AJAX获取数据的页面,经过客户端浏览器查看源代码的方式,将没法获取到这部分的数据;又如使用了Javascript对内容进行加密以防止采集的页面,即便让你得到HTML源代码,也难以解密获得你想要的结果。但WebBrowser使得这一切变得简单!有兴趣的朋友欢迎继续阅读本博的另外一篇文章《》,讲述如何经过WebBrowser访问加密页面,改写其中的Javascirpt方法获取加密的结果。
View Code

Web Browser Express 概述java

Web Browser Express 概述
Visual Studio 2005
8(共 8)对本文的评价是有帮助 - 评价此主题
发布日期 : 8/26/2004 | 更新日期 : 8/26/2004
John Kennedy
Microsoft Corporation
摘要:创建您本身的、支持选项卡的 Web 浏览器,以及链接到搜索引擎的集成连接。
下载 WebBrowserExpress.msi 示例文件。
本页内容

 简介 

 利用他人成果的好处 

 设计 Web 浏览器 

 工做原理 

 有意思的几点 

 扩展建议 

 小结 
简介
Web 浏览器的一个功能是在同一浏览器窗口内打开不一样选项卡或子页,这个功能正在变得更加普及。当浏览多个站点时,使用选项卡来分开多个页会保持桌面的整齐。有若干种第三方 Web 浏览器在 Windows 和其余平台上提供这一功能,若是您跟我同样,您将发现这是一种让人上瘾的浏览方法。不少浏览器,不管是默认设置仍是经过插件,也提供一种快速方法,无须直接使用搜索引擎就能够执行 Web 搜索。可以编写本身的浏览器,并使其可以完成全部这些工做,还能把它微调并调整到彻底适合您的须要,那不是很棒吗?

图 1:用 Visual C# Express 设计并实现本身的 Web 浏览器
将这些对功能的渴望变为一种全新的产品看起来好像须要大量的工做。毕竟,开发 Internet Explorer 用了多少时间?(答:很长时间。)我如何可以只用一夜的时间,单枪匹马,就能复制出 Internet Explorer 的强大 HTML 呈现功能并添加我本身的新功能列表?那是由于我使用 Visual C# Express。

 返回页首 
利用他人成果的好处
在一个晚上编写 Web 浏览器的秘密在于使用其余人的成果。在本例中,秘密是使用了 C# Express WebBrowser 控件。若是您安装了 C# Express 而且打开了帮助,您可能已经看到了一个叫作¡°如何:用 C# Express建立 Windows 应用程序¡±的主题。这一简短的项目将指导您完成建立 Windows 窗体应用程序所涉及的各个步骤。若是您尚未看完,并且您对 C# 不熟悉,我建议您阅读它。
关键之处是,经过使用与 C# Express 配套的控件,建立多个应用程序(包括完整的 Web 浏览器)都是很容易的。一旦 WebBrowser 控件确实已在 Windows 窗体上了,您只需告诉它哪些 URL 是要获取并显示的,以及是否须要返回、向前、刷新或中止。链接到 Internet、获取数据、格式化 HTML、显示图形等全部困难的工做都由该控件处理。
这个项目与帮助项目相近,除了一点,该项目建立多个 WebBrowser 控件并将其添加到 TabControl 中的网页上,而不是只添加一个WebBrowser 控件到 Windows 窗体上。是的,我甚至无须编写代码来建立 TabControl。这是从工具箱到 Windows 窗体拖放的另外一个示例。
那么,虽然我知道这看似一个巨大而复杂的应用程序,仿佛须要数月的工做来完成,但事实上我只是连结了现有控件间的点,就在一个晚上完成了全部工做。这就是个人编程方式!

 返回页首 
设计 Web 浏览器

图 2:从工具箱拖动控件是编写这一应用程序的关键
如下描述了我如何着手建立 Web Browser Express 项目。在从 C# Express 新项目对话框建立一个Windows 应用程序以后,我将下列控件拖到 Windows 窗体:
TabControl:这个控件存储全部子页,每一个子页能控制一个 WebBrowser 控件。一旦它已经建立,向其添加其余页就会很容易。为了肯定它填充了整个 Windows 窗体,Dock 属性被设定为 Fill。这使得该控件保持与 Windows 窗体一样大小,即使是调整大小以后。
MenuStrip:尽管这个应用程序中没有菜单,仍是存在 MenuStrip 来提供一个屏幕顶端的区域,按钮和文本框能够添加到这个区域。另外,若是您决定添加一些菜单选项,您能够在这里添加。我将 MenuStrip 拖出以使其变得稍大。
Buttons:须要有一些用于 Web 浏览的简单控件。按钮被拖动到 MenuStrip 中,并调整大小,有一个图像应用于这些按钮。我唯一须要作的一件事就是从新绘制图像背景,使其为浅蓝色,以便看起来像 MenuStrip。
Textboxes 和 ComboBoxes :除了按钮,我还须要一个用于 URL 和搜索字符串的文本框。实际上,URL 是一个 ComboBoxes,容许用户输入一个 Web 地址,并从一个下拉列表中选择项目。这个列表是在设计器中填充的,但若是您但愿的话能够以编程方式添加新项。
PictureBox:最右边的 PictureBox 控件是为了装饰用的。Web 浏览器在下载内容时会显示一些动画。
timer:timer 对象用于一秒钟数次发出一个消息。这个消息被一个叫作 timer1_tick() 的方法捕获,并用于更改在 PictureBox 中显示的图像。结果是动画。这并不算是第一流的解决方案,可是它奏效。

 返回页首 
工做原理
当该程序启动后,它所作的第一件事是调用 Create_a_new_tab()。此方法建立一个新选项卡页,将其添加到 TabControl,而后在其上建立一个 WebBrowser 控件。WebBrowser URL 被设定为“主页”,不管它在您的系统上多是什么。下面是建立新选项卡的代码:
// Create a new Tab Page
TabPage newpage = new TabPage("Loading...");
tabControl1.TabPages.Add(newpage);
 
这是建立新 WebBrowser 控件的代码:
// Create a new WebBrowser control.
WebBrowser webpage = new WebBrowser();       
webpage.Parent = newpage;
webpage.Dock = DockStyle.Fill;
webpage.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webpage_DocumentCompleted);
webpage.GoHome();                              
            
 
此代码肯定 WebBrowser 的父级是 Tab 页。它还用设置为 Fill 的 Dock 来肯定它也保持在窗口的实际大小。咱们还添加了一个事件处理程序:控件经过将消息发送到您的程序来工做。您能够选择您所聆听的消息,以及经过将事件处理程序连接到消息所调用的方法。在本例中,该消息告诉咱们 WebControl 已经完成了站点的加载和显示,当完成任务时,它将调用名为 webpage_DocumentComplete() 的方法。这容许咱们定义当网页加载完毕时执行的代码。例如,中止动画。
Create_a_new_tab() 方法中的最后一行启用计时器:
timer1.Enabled = true;      
 
计时器轻松地将小段消息发送到 timer1_tick(),它改变在 PictureBox 控件中显示的图像,以下所示:
private void timer1_Tick(object sender, EventArgs e)
        {
            // This method is called by the timer, and we use it to update the
            // image displayed by the PictureBox control to create a simple
            // animation.
 
            image_animation++;
            if (image_animation > 10) image_animation = 0;
 
            switch (image_animation)
            {
                case 0: pictureBox_busy.Image = wbe.Properties.Resources.anim0; break;
                case 1: pictureBox_busy.Image = wbe.Properties.Resources.anim1; break;
                case 2: pictureBox_busy.Image = wbe.Properties.Resources.anim2; break;
...
                case 7: pictureBox_busy.Image = wbe.Properties.Resources.anim7; break;
                case 8: pictureBox_busy.Image = wbe.Properties.Resources.anim8; break;
                case 9: pictureBox_busy.Image = wbe.Properties.Resources.anim9; break;
            }
        }
 
您能够看到,计时器每次激发时,在 PictureBox 中就会显示一个不一样的图像。使用您将一个图像分配到按钮或 PictureBox 控件时显示的对话框,从磁盘加载图像。
程序的其他部分由事件驱动 — 当用户单击按钮或者输入一个 Web 地址或搜索字符串时调用特定方法。
例如,Web 导航按钮都调用当前 WebBrowser 控件。例如,若是您单击 Back 按钮,会调用如下方法:
private void button_back_Click(object sender, EventArgs e)
        {
            // Go Back - if the web control can go back, do it.
            WebBrowser thiswebpage = GetCurrentWebBrowser();
            if (thiswebpage.CanGoBack)
                thiswebpage.GoBack();
        }
 
当在 Address 组合框中输入一个 URL 时,咱们使用 Web 控件的 navigate 方法来获取并显示该页。下面的代码使用了当前显示在组合框中的文本并将其传递到 navigate 方法:
WebBrowser thiswebpage = GetCurrentWebBrowser();                
thiswebpage.Navigate(comboBoxurl.Text);
timer1.Enabled = true;  
 

 返回页首 
有意思的几点
在编写这个项目时,我想到了几个小窍门。不过,可能它们实际上并不能说是窍门,而是一些技术,当您编写本身的代码时可能发现它们是有用的。
使文本和组合框响应 Return 键。
Address ComboBoxes 和 Search TextBox 容许用户输入文本,而后在单击 Go 按钮时使用这个文本。使用 Text 属性从控件提取文本是很容易的。不过,若是按键盘上的“return”键就能够执行与单击一个按钮一样的操做,这样也很好。我经过从两个文本框检查 KeyUp 消息来使其奏效。当 KeyUp 消息到达时,我检查它是不是 Return 键。若是它是,就触发了与单击按钮相同的操做。
ComboBox 而非TextBox
Web Browser Express 的第一个版本将一个 TextBox用于地址 URL 和 Search 框。这很奏效,可是在实践中每次都要手工输入 URL 十分麻烦。我删除了 ComboBox 并添加了一个 TextBox,用一些 URL 填充这一组合框来使用户开始。您能够从 ComboBox 属性资源管理器添加您本身的 URL。
集成搜索
全部流行的 Web 浏览器都有一个能够输入搜索词汇的文本框,结果会返回到 Web 页中,而不须要首先浏览到搜索引擎。因为 MSN 搜索目前有了更新,这看起来是将此功能内置到我本身的 Web 浏览器中的最佳理由。
这很是简单。只需查看 Internet Explorer 中 MSN 搜索上的历史记录,看一下搜索字符串须要使用的格式。而后 Search 方法将搜索文本追加到 URL 并定位到该连接,结果做为一个标准 Web 页返回。
动画
从图形化 Web 浏览器的早期以来,从 Web 请求内容就是有迹可寻的,这样用户就不会觉得它们的计算机出了问题,或者觉得全部东西都被锁定了。总的来讲,让用户知道有些事在发生而且他们须要有耐心老是个好主意。
这是要实现的项目中我最喜欢的部分之一,若是您在艺术上有几分天赋,那么在建立可以想象到的最酷的徽标时,您能够获得很多乐趣。在本例中,我在一个动画程序中建立了一系列大约 12 个帧,并将其做为 BMP 图像导出,加载到 C# Express 中。

图 3:添加图形十分简单。为一个按钮或 PictureBox 选择图像属性,您能够直接从磁盘导入图像。在开始前肯定图像的大小正确。

 返回页首 
扩展建议
若是您已经尝试过了 Web Browser Express,而且但愿添加本身的功能,那么我这篇文章就作得不错。为了让您保持忙碌,下面还有几个主意,让您能够相对较快地取得进步。
历史记录:保留全部曾访问过的 Web 站点的记录,这样再访问它们时会比较容易。
自动完成:检查 Return 键的方法也可以检查之前输入过的 URL,并自动将其完成。与 Internet Explorer 相比,您能够更改这一自动完成的方式,好比能够只有在按 Tab 键时才自动完成。
收藏:ComboBox 由 6 个 Web 站点填充,您能够从 Properties 资源管理器很容易地更改这些站点。然而,将一个新按钮添加到MenuStrip 取得当前正在显示的 Web 站点并将其添加到 ComboBox 列表怎么样呢?用这种方法用户能够构建起其收藏站点的列表。当程序退出并从新启动时,您须要一些方法来保存并从新加载这个列表。
集成的 RSS 阅读器:保持比竞争对手领先一步,尽可能将 RSS 阅读器内置到您的 Web 浏览器中。

 返回页首 
小结
用 C# Express 建立应用程序的秘密在于:知道哪些控件是可用的,以及用这些控件能够作什么。在本例中,只用了几个控件就构造了一个全功能的 Web 浏览器。祝您本身编程时好运。
John Kennedy 是 C# 用户教育团队的程序员/做者。您能够经过阅读他的网络日记,在联机帮助编写中了解他的成就,网络日记网址为:http://blogs.msdn.com/johnkenn
转到原英文页面

 返回页首
View Code

WebBrowser控件的高级用法,c#和Javascript交互及光标位置恢复node

蛙蛙推荐:WebBrowser控件的高级用法,c#和Javascript交互及光标位置恢复
摘要:在作Winform应用的时候,有些效果不太好作,不像网页,用CSS和HTML能作出灰常漂亮的界面来,其实用WebBrowser可让你的程序拥有二者的优点。这里介绍一个winform内嵌WebBrowser作的一个RSS浏览器及内嵌在Winform里的html编辑器的光标恢复问题。
  不知道你们有没有用过FeedDemon,它是一个不错的RSS订阅工具,左边的导航树是Winform的,右边的主区域是用WebBrowser来呈现的,并且在主区域点击某条RSS条目后左边的树节点相应的未读数目就会变化,点击左边的树选择“设置全部项目未已读”,右边主区域的RSS列表就会变为已读图标,这是一个典型的Winform和WebBrowser相结合的例子,既发挥了Winform能利用本地CPU计算能力,响应快的特色,又发挥了HTML编程容易,界面华丽的优点,要用winform写一个右边主区域效果的控件,估计得费很多力。
  咱们先来看下这个RSS阅读器的核心功能,首先是利用http请求去获取rss内容,RSS是XML格式的,显示的话,就能够用XSLT来显示,这样能够作到内容和显示相分离,显示部分用WebBrowser来显示,而后呢WebBrowser里的javascript要能够调用Winform方法,Winform也要能调用Webbrowser控件里的javascript方法。
 RSS的XML格式你们都很熟悉了,随便找一段示例以下
 


<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:slash="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <channel>
    <title>老农专一数据库编程</title>
    <link>http://www.5do8.com/</link>
    <description>老农如是想如是为</description>
    <copyright>copyright by 5do8</copyright>
    <item read="true">
      <title>我军步兵营所属炮连的98式120火箭筒

..</title>
      <description>我军步兵营所属炮连的98式120火箭筒

..</description>
      <link>/tableforum/App/view.php?bbsid=4&subid=1&fid=65544&tbid=8075</link>
      <author></author>
      <pubDate>
        Wed, 30 Jan 2008 22:03:01 GMT
      </pubDate>
    </item>

    <item read="true">
      <title>温今早看望广州火车站80万滞留旅客:&quot;大..</title>
      <description>温今早看望广州火车站80万滞留旅客:&quot;大..</description>
      <link>/tableforum/App/view.php?bbsid=4&subid=2&fid=65638&tbid=2819</link>
      <author></author>
      <pubDate>
        Wed, 30 Jan 2008 22:03:01 GMT
      </pubDate>
    </item>

    <item read="true">
      <title>温今早看望广州火车站80万滞留旅客:&quot;大..</title>
      <description>温今早看望广州火车站80万滞留旅客:&quot;大..</description>
      <link>/tableforum/App/view.php?bbsid=4&subid=3&fid=65639&tbid=6065</link>
      <author></author>
      <pubDate>
        Wed, 30 Jan 2008 22:03:01 GMT
      </pubDate>
    </item>

    <item>
      <title>07最惹火十部国产片</title>
      <description>07最惹火十部国产片</description>
      <link>http://sh.sohu.com/7/1103/22/column216152269.shtml</link>
      <author></author>
      <pubDate>
        Wed, 30 Jan 2008 22:02:55 GMT
      </pubDate>
    </item>

    <item>
      <title>赚大钱取之有道火爆</title>
      <description>赚大钱取之有道火爆</description>
      <link>http://doc.go.sohu.com/200712/df66a3feef3110edd839666dcb3fc1de.php?url=http://vip.78.cn/zs/gbook_admin/getgo.php?id=452</link>
      <author></author>
      <pubDate>
        Wed, 30 Jan 2008 22:02:55 GMT
      </pubDate>
    </item>

    <item>
      <title>火!等一分钟</title>
      <description>火!等一分钟</description>
      <link>http://61.135.132.134/goto.php?aid=27&amp;pid=1153</link>
      <author></author>
      <pubDate>
        Wed, 30 Jan 2008 22:02:55 GMT
      </pubDate>
    </item>

    <item>
      <title>火车票预售期</title>
      <description>火车票预售期</description>
      <link>http://news.sogou.com/news?query=火车票预售??pid=01003102&p=01010302</link>
      <author></author>
      <pubDate>
        Wed, 30 Jan 2008 22:02:55 GMT
      </pubDate>
    </item>

    <item>
      <title>春运火车票</title>
      <description>春运火车票</description>
      <link>http://news.sogou.com/news?query=春运火车票&pid=01003102&p=01010302</link>
      <author></author>
      <pubDate>
        Wed, 30 Jan 2008 22:02:55 GMT
      </pubDate>
    </item>

    <item>
      <title>轻松购买火车票!</title>
      <description>轻松购买火车票!</description>
      <link>http://61.135.132.134/goto.php?aid=26&amp;pid=1175</link>
      <author></author>
      <pubDate>
        Wed, 30 Jan 2008 22:02:55 GMT
      </pubDate>
    </item>

    <item>
      <title>one-mall·火热招商</title>
      <description>one-mall·火热招商</description>
      <link>http://shop.focus.cn/shopview/450228.html</link>
      <author></author>
      <pubDate>
        Wed, 30 Jan 2008 22:02:55 GMT
      </pubDate>
    </item>

    <item>
      <title>六佰本火热招商进行中</title>
      <description>六佰本火热招商进行中</description>
      <link>http://shop.focus.cn/shopview/450319.html</link>
      <author></author>
      <pubDate>
        Wed, 30 Jan 2008 22:02:55 GMT
      </pubDate>
    </item>

  </channel>
</rss>

  咱们还要再写个RSS来呈现这个RSS,就以列表的方式呈现就好了,而后咱们设置简单的CSS,让已读的RSS条目显示为蓝色,未读的默认显示为黑色,而后点击每一个条目的时候要把颜色改成已读的颜色,而且同时Winform。从上面的RSS定义能够看到我把前三个item元素加了一个read="true"的属性(为了演示目的我手工加的),咱们用xslt的if语句来读取这个属性来动态设置RSS条目的样式。最后xslt还要定义一个让winform调用的javascript方法以供后面的演示。最终的XSLT以下,不太熟悉XSLT语法的能够参考我之前贴过的帖子。


<?xml version="1.0" encoding="utf-8" ?>

<xsl:stylesheet

     version="1.0"

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="html" />

  <xsl:template match="rss/channel">

    <html>

      <head>

        <title>

          <xsl:value-of select="title" />

        </title>

        <SCRIPT LANGUAGE="JavaScript">

          function invokeWin(obj)

          {

          obj.childNodes[0].style.color='blue';

          window.external.winFunction(obj.childNodes[0].href);

          }

          function scriptFunc(str)

          {

          alert(str);

          }

        </SCRIPT>

        <style media="all" lang="en" type="text/css">

          body

          {

          background-color:#ccc;

          }

          .ChannelTitle

          {

          font-family:  Verdana;

          font-size:  11pt;

          font-weight:  bold;

          width:  500px;

          text-align:  center;

          }

          .PostDate

          {

          font-family:  Verdana;

          font-size:  7pt;

          padding-left:  15px;

          }

          A,A:visited

          {

          text-decoration:  none;

          color: #000

          }

          A:link

          {

          text-decoration:  none;

          }

          A:hover

          {

          text-decoration:  underline;

          }

        </style>

      </head>

      <body>

        <xsl:apply-templates select="title" />

        <ol>

          <xsl:apply-templates select="item" />

        </ol>

        <div align="center">© 2008WawaSoft 2008</div>

      </body>

    </html>

  </xsl:template>

  <xsl:template match="title">

    <div class="ChannelTitle">

      <xsl:value-of select="text()" />

    </div>

    <br />

  </xsl:template>

  <xsl:template match="item">

    <li>

      <span onclick="invokeWin(this)">

        <a TARGET="_blank" href="{link}">

          <xsl:if test="@read='true'">

            <xsl:attribute name="style">color:blue;</xsl:attribute>

          </xsl:if>

          <xsl:value-of select="title" />

        </a>

      </span>

      <span class="PostDate">

        <xsl:value-of select="pubDate" />

      </span>

    </li>

  </xsl:template>

</xsl:stylesheet>


程序里面呢,咱们得让WebBrowser来显示这个RSS,代码以下
 

private void FWBTest_Load(object sender, EventArgs e)
{
    wb1.AllowWebBrowserDrop = false;
    //wb1.IsWebBrowserContextMenuEnabled = false;
    wb1.WebBrowserShortcutsEnabled = false;
    wb1.ObjectForScripting = this;
    wb1.ScriptErrorsSuppressed = true;

    try
    {
        XslCompiledTransform xslt = new XslCompiledTransform();
        xslt.Load("rss.xslt");
        string HTMLoutput;
        using (StringWriter writer = new StringWriter())
        {
            xslt.Transform("rss.xml", null, writer);
            HTMLoutput = writer.ToString();
        }
        wb1.DocumentText = HTMLoutput;
    }
    catch (XsltException xsle)
    {
        Console.WriteLine("样式表中有错。");
    }
    catch (XmlException xmle)
    {
        Console.WriteLine("加载样式表时出现分析错误。");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}

 
都是WebBrowser和.net的Xml对象的基本用法。
和javascript交互也很简单,如下分别是让javascript调用的方法和用c#调用javascript方法的代码。

public void winFunction(string str)
{
    toolStripStatusLabel1.Text = string.Format("脚本执行方法:{0}", str);
}

private void toolStripButton1_Click(object sender, EventArgs e)
{
    wb1.Document.InvokeScript("scriptFunc",
    new String[] { "这是winform调用脚本方法" });

}


关键点就是javascript代码的下面这句
window.external.winFunction(obj.childNodes[0].href);
以及c#代码下面这句
wb1.Document.InvokeScript("scriptFunc",new String[] { "这是winform调用脚本方法" });
RSS这部分演示完毕了。
winform下的富文本编辑器控件不太多,通常有两种途径,一种是扩展RichTextBox,要去研究rtf格式,mime协议等,一种是用WebBrowser控件,并把designMode设置为on,而后就是和网页的html编辑器同样,调用一些ExecCommand方法来编辑格式等,这里介绍后者,由于后者实现简单,并且html格式能够直接按原格式贴到互联网上,通用性比较好,这里不具体说一些编辑命令如何实现,这些能够参考文后的参考连接,这里只讨论如何让你的HTML文档关闭后再加载恢复上次编辑的光标位置的功能。
这里须要用一些mshtml对象,因此要在项目里引用Microsoft.mshtml,引用位置默认应该是C:\Program Files\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll,我不知道这个组件是否是新安装的windows xp,2003都有,若是没有的话能够把这个dll放到你项目的bin目录下一块儿发布。
大体原理是这样的,在关闭当前编辑文档的时候获取当前光标的位置,也就是当前选择的元素(虽然doc.selection有多是个图片,而不是TextRange,但咱们只考虑textRange的状况,你们能够写代码过滤掉其它状况,若是当前编辑点不是文本类型,就不考虑恢复光标位置了,呵呵。)。而后给当前选择元素后面插入一个小的span元素,做为一个标识符,最后再把文档的Body的InnerHTML保存到数据库里。下次从数据库里读取保存的html文本,先设置到当前WebBrowser的Body的innerHTML属性,而后经过getElementById方法找上次插入的标识符span,找到这个span就至关于找到了上次的光标位置,最后用body元素createTextRange后调用其moveToElementText方法把光标编辑位置移动到找到的位置。
相应代码以下
 


private void NewDoc()

{

    wb1.Navigate("about:blank");

    IHTMLDocument2 doc = wb1.Document.DomDocument as IHTMLDocument2;

    doc.designMode = "On";

}



private void SaveDoc()

{

    if (wb1.Document != null)

    {

        IHTMLDocument2 doc = wb1.Document.DomDocument as IHTMLDocument2;

        HTMLDocumentClass documentClass = wb1.Document.DomDocument as HTMLDocumentClass;

        IHTMLDOMNode caret_pos = (IHTMLDOMNode)documentClass.getElementById("caret_pos");

        if (caret_pos != null) caret_pos.removeNode(true);

        IHTMLTxtRange range = doc.selection.createRange() as IHTMLTxtRange;

        range.pasteHTML(caretHtml);

        range.collapse(true);

        _text = doc.body.innerHTML;

        doc.body.innerHTML = "";

    }

}



private void LoadDoc()

{

    if (!string.IsNullOrEmpty(_text))

    {

        IHTMLDocument2 doc = wb1.Document.DomDocument as IHTMLDocument2;

        doc.body.innerHTML = _text;

        IHTMLBodyElement bodyElement = doc.body as IHTMLBodyElement;

        if (bodyElement != null)

        {

            IHTMLTxtRange range = bodyElement.createTextRange();

            HTMLDocumentClass documentClass = wb1.Document.DomDocument as HTMLDocumentClass;

            IHTMLElement caret_pos = documentClass.getElementById("caret_pos");

            if (caret_pos != null)

            {

                range.moveToElementText(caret_pos);

                range.select();

            }

        }

        _text = "";

    }

}




注:代码写的不严谨,只用于演示目的,请勿用于生产环境。

关于Winform html编辑器的参考连接
http://windowsclient.net/articles/htmleditor.aspx
http://www.codeproject.com/cs/miscctrl/editor_in_windows_forms.asp
http://www.codeproject.com/KB/IP/WYSIWYG_netHTML2.aspx
关于恢复光标位置的参考连接
设置光标位置的问题:SetDocumentHTML(html) 以后, SetCaretPos(curpos) 为什么失效?
http://topic.csdn.net/t/20050729/22/4177529.html
HTML可视化编辑器中IE丢失光标位置的问题。
http://hi.baidu.com/jindw/blog/item/8c3e928ba1f04dd0fc1f10d2.html
用土办法记忆可编辑div 内的光标位置- 极湖- by OU(连接不可用,请从google缓存里查看)
http://my.opera.com/jlake/blog/2008/05/05/div
How to RemoveChild from HtmlElement from C#
http://bytes.com/forum/thread453742.html
本文源码下载地址以下
 WebBrowserDemo.zip
View Code

WebBrowser 设置代理彻底解决方案程序员

微软webbrowser控件也就是IE插件,他的全部功能就像IE相似,固然设置也是同样的,下面介绍下webbrowser如何设置代理,可不要用这个对抗广告联盟哦

You can change the proxy with InternetSetOption method from the wininet.dll, here is a example to set the proxy:

using System.Runtime.InteropServices;

Public struct Struct_INTERNET_PROXY_INFO 
{ 
public int dwAccessType; 
public IntPtr proxy; 
public IntPtr proxyBypass; 
}; 
[DllImport("wininet.dll", SetLastError = true)] 
private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength);

private void RefreshIESettings(string strProxy) 
{ 
const int INTERNET_OPTION_PROXY = 38; 
const int INTERNET_OPEN_TYPE_PROXY = 3; 

Struct_INTERNET_PROXY_INFO struct_IPI; 

// Filling in structure 
struct_IPI.dwAccessType = INTERNET_OPEN_TYPE_PROXY; 
struct_IPI.proxy = Marshal.StringToHGlobalAnsi(strProxy); 
struct_IPI.proxyBypass = Marshal.StringToHGlobalAnsi("local"); 

// Allocating memory 
IntPtr intptrStruct = Marshal.AllocCoTaskMem(Marshal.SizeOf(struct_IPI)); 

// Converting structure to IntPtr 
Marshal.StructureToPtr(struct_IPI, intptrStruct, true); 

bool iReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY, intptrStruct, Marshal.SizeOf(struct_IPI)); 
} 

private void SomeFunc() 
{ 
RefreshIESettings("192.168.1.200:1010"); 

System.Object nullObject = 0; 
string strTemp = String.Empty; 
System.Object nullObjStr = strTemp;
axWebBrowser1.Navigate("http://willstay.tripod.com", ref nullObject, ref nullObjStr, ref nullObjStr, ref nullObjStr); 
}

-------------------------------------------------------------------------------------------------------------------------------------

昨 天作的投票机遇到个新问题,昨天开始那个投票开始如今ip地址,每一个地址只能投5票/天。若是每次更改ie的链接为代理服务器,那也麻烦死了,如 果改用webclient,那昨天的2个多小时就白费了,上网一通狂收还真找到了办法,这下好办了,建了一个proxy.txt文档,里面放上从网上收到 的代理服务器,而后程序读到一个listbox里面,每次须要更换ip的时候只要单击一次,就能够还一个地址从新投票了。
附上proxy.cs

using System.Runtime.InteropServices;//须要添加这个引用
public struct Struct_INTERNET_PROXY_INFO
{
public int dwAccessType;
public IntPtr proxy;
public IntPtr proxyBypass;
};
[DllImport("wininet.dll", SetLastError = true)]
private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength);
public void RefreshIESettings(string strProxy)
{
const int INTERNET_OPTION_PROXY = 38;
const int INTERNET_OPEN_TYPE_PROXY = 3;
Struct_INTERNET_PROXY_INFO struct_IPI;
// Filling in structure
struct_IPI.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
struct_IPI.proxy = Marshal.StringToHGlobalAnsi(strProxy);
struct_IPI.proxyBypass = Marshal.StringToHGlobalAnsi(”local”);
// Allocating memory
IntPtr intptrStruct = Marshal.AllocCoTaskMem(Marshal.SizeOf(struct_IPI));
// Converting structure to IntPtr
Marshal.StructureToPtr(struct_IPI, intptrStruct, true);
bool iReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY, intptrStruct, Marshal.SizeOf(struct_IPI));
}

使用的时候,调用RefreshIESettings
py.proxy py1 = new proxy();
py1.RefreshIESettings(”221.4.155.51:3128″);
System.Object nullObject = 0;
string strTemp = String.Empty;
System.Object nullObjStr = strTemp;
webBrowser1.Navigate(”http://www.hfxsy.cn”, null, null, null);
View Code

WebBrowser控件读html流并显示web

C# WebBrowser控件读html流并显示
2008-04-22 08:52 677人阅读 评论(2) 收藏 举报
//环境VS2005,WinXPSP2

  //test.txt 为html源代码

         private void Form1_Load(object sender, EventArgs e)

         {

             string str = null;

            StreamReader sr = new StreamReader("D:/test.txt", Encoding.Default);

             webBrowser1.Navigate("about:blank");

            webBrowser1.Document.OpenNew(true);

             str = sr.ReadToEnd();

          webBrowser1.Document.Write(str);

       }
View Code

webBrowser 加载网页时实现进度显示数据库

private void Fmain_Load(object sender, EventArgs e)
        {
            Uri uri= new Uri("http://www.baidu.com");
            webBrowser1.Url = uri;
            webBrowser1.ProgressChanged += new WebBrowserProgressChangedEventHandler(webBrowser1_ProgressChanged);
        }
        private void webBrowser1_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e)
        {
            progressBar1.Visible = true;
            if ((e.CurrentProgress > 0) && (e.MaximumProgress > 0))
            {
                progressBar1.Maximum = Convert.ToInt32(e.MaximumProgress);//设置正在加载的文档总字节数
                progressBar1.Step = Convert.ToInt32(e.CurrentProgress);////获取已下载文档的字节数
                progressBar1.PerformStep();
            }
            else if (webBrowser1.ReadyState == WebBrowserReadyState.Complete)//加载完成后隐藏进度条
            {
                progressBar1.Value = 0;
                progressBar1.Visible = false;
            }
        }
View Code

webbrowser 代理编程

百度,google加本身理解后,将所得方法总结一下:

    方法1:修改注册表Software//Microsoft//Windows//CurrentVersion//Internet Settings下 ProxyEnable和ProxyServer。这种方法适用于局域网用户,拨号用户无效。
public partial class Form1 : Form
   {       
 4        //用于刷新注册表
       [DllImport(@"wininet",
       SetLastError = true,
       CharSet = CharSet.Auto,
       EntryPoint = "InternetSetOption",
       CallingConvention = CallingConvention.StdCall)]
11
       public static extern bool InternetSetOption
       (
       int hInternet,
       int dmOption,
       IntPtr lpBuffer,
       int dwBufferLength
       );
20         private void btnStart_Click(object sender, EventArgs e)
       {
           RegistryKey pregkey;
               pregkey = Registry.CurrentUser.OpenSubKey("Software//Microsoft//Windows//CurrentVersion//Internet Settings", true);
               if (pregkey == null)
               {
                   Console.WriteLine("键值不存在");
               }
               else
               {
                   pregkey.SetValue("ProxyEnable", 1);
                   pregkey.SetValue("ProxyServer", "代理地址");
                   //激活代理设置
                   InternetSetOption(0, 39, IntPtr.Zero, 0);
                   InternetSetOption(0, 37, IntPtr.Zero, 0);
                   webBrowser1.Navigate(txtweb.Text, false);
                   // System.Threading.Thread.Sleep(10000);
               }
       }
39}

方法2: 修改注册表Software//Microsoft//Windows//CurrentVersion//Internet Settings//Connections下以你拨号链接名为键的值,该键为二进制。这种方法适用于拨号用户。

    
public partial class FrmMain : Form
    {

[DllImport(@"wininet",
        SetLastError = true,
        CharSet = CharSet.Auto,
        EntryPoint = "InternetSetOption",
        CallingConvention = CallingConvention.StdCall)]


        public static extern bool InternetSetOption
        (
        int hInternet,
        int dmOption,
        IntPtr lpBuffer,
        int dwBufferLength
        );

//将值转换为注册表中的二进制值
public byte ChangeTobyte(char i)
        {
            byte key = 0;
            switch (i)
            {
                case '0': key = 48; break;
                case '1': key = 49; break;
                case '2': key = 50; break;
                case '3': key = 51; break;
                case '4': key = 52; break;
                case '5': key = 53; break;
                case '6': key = 54; break;
                case '7': key = 55; break;
                case '8': key = 56; break;
                case '9': key = 57; break;
                case '.': key = 46; break;
                case ':': key = 58; break;
                
            }
            return key;
        }

private void btnStart_Click(object sender, EventArgs e)
        {
             int i = ("代理地址").Length;
                byte[] key = new byte[50];
                char[] source = ("代理地址").ToCharArray();
                key[0] = 60;
                key[4] = 3;
                key[8] = 3;
                key[12] = (byte)i;
                for (int ii = 0; ii < source.Length; ii++)
                {
                    key[16 + ii] = ChangeTobyte(source[ii]);
                }
                string sDirectX = "";
                for (int k = 0; k < key.Length; k++)
                {
                    if (key[k] != 0)
                    {
                        sDirectX += key[k] + " ";
                    }
                }
                //MessageBox.Show(sDirectX);
                RegistryKey pregkey;
                pregkey = Registry.CurrentUser.OpenSubKey("Software//Microsoft//Windows//CurrentVersion//Internet Settings//Connections", true);
                if (pregkey == null)
                {
                    Console.WriteLine("键值不存在");
                }
                else
                {
                    pregkey.SetValue("拨号名字对应键值", key, RegistryValueKind.Binary);
                    //激活代理设置
                    InternetSetOption(0, 39, IntPtr.Zero, 0);
                    InternetSetOption(0, 37, IntPtr.Zero, 0);
                    webBrowser1.Navigate(txtweb.Text, false);
                    webBrowser1.Refresh();
                    
                }

        }
}

方法3: 使用c#自带的webproxy类,使用这种方法能够得到目标网站的响应,但我不会把这种响应用IE反馈出来,有高手帮个忙么?
网上的代码说是MSDN的:
    HttpWebRequest myWebRequest=(HttpWebRequest)WebRequest.Create("http://www.microsoft.com"/); 
    WebProxy myProxy=new WebProxy(); 
    // Obtain the 'Proxy' of the  Default browser.   
    myProxy=(WebProxy)myWebRequest.Proxy; 这行我编译不经过
    // Print the Proxy Url to the console. 
    Console.WriteLine("/nThe actual default Proxy settings are {0}",myProxy.Address); 
    try 
    { 
    Console.WriteLine("/nPlease enter the new Proxy Address that is to be set:"); 
    Console.WriteLine("(Example:http://myproxy.example.com:port/)"); 
    string proxyAddress; 
    proxyAddress =Console.ReadLine(); 
    if(proxyAddress.Length>0) 

    { 
    Console.WriteLine("/nPlease enter the Credentials "); 
    Console.WriteLine("Username:"); 
    string username; 
    username =Console.ReadLine(); 
    Console.WriteLine("/nPassword:"); 
    string password; 
    password =Console.ReadLine(); 
    // Create a new Uri object. 
    Uri newUri=new Uri(proxyAddress); 
    // Associate the newUri object to 'myProxy' object so that new myProxy settings can be set. 
    myProxy.Address=newUri; 
    // Create a NetworkCredential object and associate it with the Proxy property of request object. 
    myProxy.Credentials=new NetworkCredential(username,password); 
    myWebRequest.Proxy=myProxy; 
    } 
    Console.WriteLine("/nThe Address of the  new Proxy settings are {0}",myProxy.Address); 
    HttpWebResponse myWebResponse=(HttpWebResponse)myWebRequest.GetResponse(); 

我改了下:
    
            HttpWebRequest myWebRequest = (HttpWebRequest)WebRequest.Create("http://www.123cha.com");
            WebProxy myProxy = new WebProxy("代理地址", true);
            try
            {
                
                Console.WriteLine("/nThe Address of the  new Proxy settings are {0}", myProxy.Address);
                HttpWebResponse myWebResponse = (HttpWebResponse)myWebRequest.GetResponse();
               
                webBrowser1.DocumentStream = myWebResponse.GetResponseStream();
             

            }
            catch { }
View Code

设置IE浏览器的代理

思路:主要是经过修改注册表实现的。
 
代码以下:
using System.Runtime.InteropServices;
using Microsoft.Win32;
 
 //You can change the proxy with InternetSetOption method from the wininet.dll, here is a example to set the proxy
[DllImport("wininet.dll", SetLastError = true)]
private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength);
 
/// <summary>
/// 设置IE代理
/// </summary>
/// <param name="isNeedProxy">是否须要代理</param>
 private static void SettingsIEBrowserProxy(bool isNeedProxy)
{
           const string INTERNETSETTINGSKEYPATH = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
            RegistryKey settings = null;
            try
            {
                settings = Registry.CurrentUser.OpenSubKey(INTERNETSETTINGSKEYPATH, true);
                //更改健值,设置代理,  
                if (settings != null)
                {
                    if (isNeedProxy)
                    {
                        settings.SetValue("ProxyEnable", 1);
                        //ip.port 就是代理服务器的ip,port就是端口
                        settings.SetValue("ProxyServer", ip +":" + port);
                    }
                    else
                    {
                        //取消代理
                        settings.SetValue("ProxyEnable", 0);
                    }
                }
                //激活代理设置
                InternetSetOption(IntPtr.Zero, 39, IntPtr.Zero, 0);
                InternetSetOption(IntPtr.Zero, 37, IntPtr.Zero, 0);
            }
            catch (Exception ex)
            {
                 throw ex;
            }
            finally
            {
                if (settings != null)
                {
                    settings.Close();
                }
            }
 }
 
这样就能够实现IE经过代理,来打开网页。
View Code

 经过http代理服务器,实现代理登陆

C# 经过http代理服务器,实现代理登陆
今天接到一个需求,须要经过http代理服务器,实现代理登陆。 
思路很简单:
实例化一个代理对象;
把上面的代理对象实例赋给HttpWebRequest、WebService服务对象的Proxy属性,就实现了代理登陆。
    
看下面的代码:
//第一步:实例化代理对象,proxyServerAddress表示代理服务器地址,false表示,若代理服务器是本地地址,则跳过http代理服务器。http代理服务器地址通常形式:http://ip:端口
Web代理 proxy = new Web代理("代理服务器地址",false); 
 
//第二步:给代理对象加上验证属性,要看你的http代理服务器是否须要身份验证;proxyname代理用户名,proxypassword代理密码,domainname域名
proxy.Credentials = new NetworkCredential(proxyname,proxypassword,domainname);
 
因为项目上使用的登陆是用webservice实现的,这样形成也能够用http代理服务器实现代理登陆;
//第三步:实例化登陆服务
 ProxyInterfaceService loginService=new ProxyInterfaceService();
 
//第四步:给登陆服务对象的代理属性赋值为第一步实例化的代理对象
loginService.Proxy = proxy;
loginService.login("登陆用户名","登陆密码",null); 
  
如果用http实现的登陆也是同样的,只要修改上面的第3、四步的代码就好了。代码以下:
 
HttpWebRequest request = WebRequest.Create("真正登陆的服务器地址")  as  HttpWebRequest;
request.Proxy=proxy;
就这样实现了http代理登陆,很简单吧。
View Code

为WebBrowser设置代理,打开网页

WebBrowser控件是基于IE浏览器的,因此它的内核功能是依赖于IE的,相信作.NET的人都知道。
       今天的主题,和上一篇文章应该是差很少的,都是经过代理来实现功能的。
        请看下面的代码:
        //1.定义代理信息的结构体
        public struct Struct_INTERNET_PROXY_INFO 
        { 
            public int dwAccessType; 
            public IntPtr proxy; 
            public IntPtr proxyBypass; 
        };
 
        //You can change the proxy with InternetSetOption method from the wininet.dll, here is a example to set the proxy
       //这个就是设置一个Internet 选项,其实就是能够设置一个代理
        [DllImport("wininet.dll", SetLastError = true)] 
        private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength);
 
       //设置代理的方法
        //strProxy为代理IP:端口
        private void InternetSetOption(string strProxy) 
        {
           //设置代理选项
            const int INTERNET_OPTION_PROXY = 38;
           //设置代理类型
            const int INTERNET_OPEN_TYPE_PROXY = 3;
           //设置代理类型,直接访问,不须要经过代理服务器了
            const int INTERNET_OPEN_TYPE_DIRECT = 1;

            Struct_INTERNET_PROXY_INFO struct_IPI;
            // Filling in structure 
            struct_IPI.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
            //把代理地址设置到非托管内存地址中 
            struct_IPI.proxy = Marshal.StringToHGlobalAnsi(strProxy);
            //代理经过本地链接到代理服务器上
            struct_IPI.proxyBypass = Marshal.StringToHGlobalAnsi("local");
            // Allocating memory 
           //关联到内存
            IntPtr intptrStruct = Marshal.AllocCoTaskMem(Marshal.SizeOf(struct_IPI));
            if (string.IsNullOrEmpty(strProxy) || strProxy.Trim().Length == 0)
            {
                strProxy = string.Empty;
                struct_IPI.dwAccessType = INTERNET_OPEN_TYPE_DIRECT;
            }
            // Converting structure to IntPtr 
           //把结构体转换到句柄
            Marshal.StructureToPtr(struct_IPI, intptrStruct, true);
            bool iReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY, intptrStruct, Marshal.SizeOf(struct_IPI));
        } 
 
        private void button1_Click(object sender, EventArgs e)
        {
                InternetSetOption("192.168.6.218:3128");
                webBrowser1.Navigate("http://www.baidu.com", null, null, null);
        }
       
       上面是代码是设置代理,要是取消代理怎么实现?
       很简单,把调用InternetSetOption(string strProxy) 函数中的strProxy参数设置为空就好了。
       例如:
       private void button2_Click(object sender, EventArgs e)
        {
                InternetSetOption(string.Empty);
                webBrowser1.Navigate("http://www.baidu.com", null, null, null);
        }
View Code
相关文章
相关标签/搜索