[转载]使用WebBrowser的记录 - 无风嗜血 - 博客园

mikel阅读(1205)

[转载]使用WebBrowser的记录 – 无风嗜血 – 博客园.

第一:新建一个类,用了获取WebBrowser元素的类

//需要引用 Interop.SHDocVw 和 Microsoft.mshtml
public class Element
    {
        //根据Name获取元素
        public HtmlElement GetElement_Name(WebBrowser wb,string Name)
        {
            HtmlElement e = wb.Document.All[Name];
            return e;
        }

        //根据Id获取元素
        public HtmlElement GetElement_Id(WebBrowser wb, string id)
        {
            HtmlElement e = wb.Document.GetElementById(id);
            return e;
        }

        //根据Index获取元素
        public HtmlElement GetElement_Index(WebBrowser wb,int index)
        {
            HtmlElement e = wb.Document.All[index];
            return e;           
        }

        //获取form表单名name,返回表单
        public HtmlElement GetElement_Form(WebBrowser wb,string form_name)
        {
            HtmlElement e = wb.Document.Forms[form_name];
            return e;
        }

        public bool CheckExistElement_Form(WebBrowser wb, string form_name)
        {
            HtmlElement e = wb.Document.Forms[form_name];
            if (e == null)
                return false;
            else
                return true;
        }

        //设置元素value属性的值
        public void Write_value(HtmlElement e,string value)
        {
            e.SetAttribute("value", value);
        }
        
        //执行元素的方法,如:click,submit(需Form表单名)等
        public void Btn_click(HtmlElement e,string s)
        {
            e.InvokeMember(s); 
        }
    }

Element el = new Element();
el.Write_value(el.GetElement_Id(IDRWebBrowser, "patient_name"), dt.Rows[0]["Patient_Name"].ToString());
//IDRWebBrowser  浏览器控件 下同

SHDocVw.WebBrowser wb = (SHDocVw.WebBrowser)IDRWebBrowser.ActiveXInstance;
                IHTMLDocument2 doc2 = (IHTMLDocument2)wb.Document;
                IHTMLElementCollection input = (IHTMLElementCollection)doc2.all.tags("input");//获取input元素
                IHTMLElementCollection select = (IHTMLElementCollection)doc2.all.tags("select");//获取select元素

//性别 input元素
                IHTMLElement elementsex = (IHTMLElement)input.item("sex", 0);
                IHTMLInputElement InputElementsex = (IHTMLInputElement)elementsex;
                if (dt.Rows[0]["Sex"].ToString() == "男")
                {
                    InputElementsex.value = "1";
                    InputElementsex.@checked = true;
                }
                else
                {
                    InputElementsex.value = "2";
                    InputElementsex.@checked = true;
                }
//select元素
IHTMLElement elementgroup_id = (IHTMLElement)select.item("group_id", 0);
                IHTMLSelectElement SelectElementgroup_id = (IHTMLSelectElement)elementgroup_id;
                //SelectElementgroup_id.value = dt.Rows[0]["Profession"].ToString();
                SelectElementgroup_id.value = zy.ToString();
                IDRWebBrowser.Document.All["group_id"].RaiseEvent("onchange");

//获取Iframe元素
IHTMLDocument2 doc11 = (IHTMLDocument2)IDRWebBrowser.Document.Window.Frames["addriframe"].Document.DomDocument;
doc11.url="自己定义它的src";

//如果需要执行元素的事件,比如onchange事件,onclick事件,onblur事件 可以用以下两种方式
WebBrowser执行dom里面的js,以下是两种方式:
1.IDRWebBrowser.Document.All["b_year"].RaiseEvent("onblur");//执行元素name='b_year'的onblur事件,如果是onclick事件改一下就行了
2.IDRWebBrowser.Document.InvokeScript("changeDiseaseid1", new object[] { InputElementselDisease_1 });//执行changeDiseaseid1这个方法,后面是带参数的,这个网上的解释比较多,我建议用第一种,第一种好用。

[转载]使用web api开发微信公众号,调用图灵机器人接口(一) - 烽火情怀 - 博客园

mikel阅读(1167)

[转载]使用web api开发微信公众号,调用图灵机器人接口(一) – 烽火情怀 – 博客园.

此文将分两篇讲解,主要分为以下几步

  1. 签名校验;
  2. 首次提交验证申请;
  3. 接收消息;
  4. 被动响应消息(返回XML);
  5. 映射图灵消息及微信消息;

其实图灵机器人搭载微信公众号很简单,只需要把图灵的地址配到公众后台就可以了。
不过这样做之后也就没有任何扩展的可能了,因此自己实现一套!

一、签名校验

在开发者首次提交验证申请时,微信服务器将发送GET请求到填写的URL上,并且带上四个参数(signature、timestamp、nonce、echostr),开发者通过对签名(即signature)的效验,来判断此条消息的真实性。

此后,每次开发者接收用户消息的时候,微信也都会带上前面三个参数(signature、timestamp、nonce)访问开发者设置的URL,开发者依然通过对签名的效验判断此条消息的真实性。效验方式与首次提交验证申请一致。

根据微信开发者平台中的描述,我们在首次提交验证申请及接收用户消息时,都需要校验签名以确保消息来源真实。

参与签名的参数为timestampnoncetoken(即开发者中心中配置的Token令牌)

加密/校验流程如下:

  1. 将token、timestamp、nonce三个参数进行字典序排序(此处注意:是三个参数的值,而不是按参数名排序)
  2. 将三个参数字符串拼接成一个字符串进行sha1加密
  3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

由于这个东西在接收消息时是通用的,我们可以使用授权过滤器AuthorizeAttribute来实现。

using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Linq;
using System.Web.Http.Controllers;

using Efh.Core.Security;

namespace Efh.Blog.Web.Areas.WeiXin.Filter
{
    public class WXAuthorizeAttribute : AuthorizeAttribute
    {
        /// <summary>
        /// 签名Key
        /// </summary>
        private string _wxToken = ConfigurationManager.AppSettings["WXToken"];

        /// <summary>
        /// 是否通过授权
        /// </summary>
        /// <param name="actionContext">上下文</param>
        /// <returns>是否成功</returns>
        protected override bool IsAuthorized(HttpActionContext actionContext)
        {
            var requestQueryPairs = actionContext.Request.GetQueryNameValuePairs().ToDictionary(k => k.Key, v => v.Value);
            if (requestQueryPairs.Count == 0
                || !requestQueryPairs.ContainsKey("timestamp")
                || !requestQueryPairs.ContainsKey("signature")
                || !requestQueryPairs.ContainsKey("nonce"))
            {
                return false;
            }

            string[] waitEncryptParamsArray = new[] { _wxToken, requestQueryPairs["timestamp"], requestQueryPairs["nonce"] };

            string waitEncryptParamStr = string.Join("", waitEncryptParamsArray.OrderBy(m => m));

            string encryptStr = HashAlgorithm.SHA1(waitEncryptParamStr);

            return encryptStr.ToLower().Equals(requestQueryPairs["signature"].ToLower());
        }

        /// <summary>
        /// 处理未授权请求
        /// </summary>
        /// <param name="actionContext">上下文</param>
        protected sealed override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            actionContext.Response = actionContext.Request.CreateResponse(
                HttpStatusCode.Unauthorized, new { status = "sign_error" });
        }
    }
}

将该特性声明在我们的微信Controller或者Action上,我们的签名校验便完成了。

二、首次提交验证申请

首次提交验证申请,微信服务器来调的时候是Get请求,而且要求我们将echostr原样返回。
注意,是原样返回。不是XML,也不是Json,<string>echostr</string>和”echostr”都是不行的!

囊中羞涩,本人使用的是虚拟主机搭载在原有的项目中,故新建微信区域(WeiXin)来实现。WeiXinAreaRegistration.cs文件如下:

public class WeiXinAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "WeiXin";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.Routes.MapHttpRoute(
            "WeiXinProcessor",
            "WeiXin/{controller}",
            new { controller = "Processor" }
        );
    }
}

新建Processor控制器,实现如下:

[WXAuthorize]
public class ProcessorController : ApiController
{
	public HttpResponseMessage Get()
	{
	    var requestQueryPairs = Request.GetQueryNameValuePairs().ToDictionary(k => k.Key, v => v.Value);
	
	    return new HttpResponseMessage(HttpStatusCode.OK)
	    {
	        Content = new StringContent(requestQueryPairs["echostr"]),
	    };
	}
}

上述我们便实现了首次微信的验证。

三、接收消息

微信将请求的消息分为六种:文本消息、图片消息、语音消息、视频消息、地理位置消息、链接消息,其实我们还可以将事件推送也理解为其中一种。

将响应的消息分为六种:
1. 回复文本消息
2. 回复图片消息
3. 回复语音消息
4. 回复视频消息
5. 回复音乐消息
6. 回复图文消息
。我们在这儿主要使用文本消息和图文消息。

分析后我们发现,ToUserNameFromUserNameCreateTimeMsgType是所有消息共有的参数。同时也是我们响应时必需的参数。

我们创建消息基类和消息类型枚举如下

public class BaseMsg
{
    public string ToUserName { get; set; }

    public string FromUserName { get; set; }

    public long CreateTime { get; set; }

    public MsgType MsgType { get; set; }
}

public enum MsgType
{
    [XmlEnum("event")]
    Event,
    [XmlEnum("text")]
    Text,
    [XmlEnum("image")]
    Image,
    [XmlEnum("voice")]
    Voice,
    [XmlEnum("video")]
    Video,
    [XmlEnum("music")]
    Music,
    [XmlEnum("news")]
    News
}

此处枚举字段标注的XmlEnum稍候解释。

而后按照各消息类型的非共有的参数,分别创建对应消息的实体类

文本消息:

[XmlRoot("xml")]
public class TextMsg : BaseMsg
{
    public string Content { get; set; }
}

图文消息:

[XmlRoot("xml")]
public class NewsMsg : BaseMsg
{
    public int ArticleCount { get; set; }

    [XmlArray("Articles")]
    [XmlArrayItem("item")]
    public List<NewsInfo> Articles { get; set; }
}

public class NewsInfo
{
    public string Title { get; set; }

    public string Description { get; set; }

    public string PicUrl { get; set; }

    public string Url { get; set; }
}

等等。

刚才下班,朋友喊了,勿勿忙忙就提交了。。。现在继续!

接下来我们就可以开始接收微信的消息了

微信是通过Post,从正文中以XML的格式将参数传递过来的

var requestContent = Request.Content.ReadAsStreamAsync().Result;

将正文参数读取出来后,转为Xml

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(requestContent);	

这样,我们便可以读取到我们需要的内容了

string msgTypeStr = xmlDoc.SelectSingleNode("xml/MsgType").InnerText;//消息类型
string userName = xmlDoc.SelectSingleNode("xml/FromUserName").InnerText;//来源用户标识
string efhName = xmlDoc.SelectSingleNode("xml/ToUserName").InnerText;//我们的用户标识

而后,我们根据消息类型,进行进一步的处理。

静候片刻,第二篇马上奉上…

[转载]Webbrowser控件史上最强技巧全集 - 莫问奴归处 - 博客园

mikel阅读(1066)

[转载]Webbrowser控件史上最强技巧全集 – 莫问奴归处 – 博客园.

VB调用webbrowser技巧集
1、获得浏览器信息:
Private Sub Command1_Click()
WebBrowser1.Navigate “http://www.applevb.com”
End Sub
Private Sub Command2_Click()
Dim oWindow
Dim oNav
Set oWindow = WebBrowser1.Document.parentWindow
Set oNav = oWindow.navigator
Debug.Print oNav.userAgent
Set oWindow = Nothing
Set oNav = Nothing
End Sub
点击Command1浏览网页,点击Command2在立即窗口中输出浏览器信息。

2、弹出Webbrowser消息窗口

Dim oWindow
Set oWindow = WebBrowser1.Document.parentWindow
oWindow.confirm “abcd”

VB调用webbrowser技巧集2

向Webbrowser中写入HTML内容的几种方法

首先在Form_Load中加入

WebBrowser1.Navigate “about:blank”

确保Webbrowser1可用

方法1:

Dim s As String
Dim stream As IStream

s = “”
s = s + “”
s = s + “”
s = s + ”

hello world


s = s + “”
s = s + ”
WebBrowser1.Document.Write s

方法2:

Dim o

Set o = WebBrowser1.Document.selection.createrange
Debug.Print o
If (Not o Is Nothing) Then
o.pasteHTML “哈哈”
Set o = Nothing
End If

方法3:

‘插入文本框
Dim o

Set o = WebBrowser1.Document.selection.createrange

o.execCommand “InsertTextArea”, False, “xxx”

vb调用Webbrowser技巧集3
1、页面滚动:

Private Sub Command2_Click()
WebBrowser1.Document.parentwindow.scrollby 0, 30
End Sub

Private Sub Form_Load()
WebBrowser1.Navigate “http://www.applevb.com”
End Sub

点击Command2就可以使当前页面向下滚动30像素

2、判断页面是否可以前进后退

Private Sub Command1_Click()
WebBrowser1.GoForward
End Sub

Private Sub Command2_Click()
WebBrowser1.GoBack
End Sub

Private Sub Form_Load()
WebBrowser1.Navigate “http://www.applevb.com”
End Sub

Private Sub WebBrowser1_CommandStateChange(ByVal Command As Long, ByVal Enable As Boolean)
If (Command = CSC_NAVIGATEBACK) Then
Command2.Enabled = Enable
End If
If (Command = CSC_NAVIGATEFORWARD) Then
Command1.Enabled = Enable
End If
End Sub

VB调用webbrowser技巧集4

1、如何使网页不出现滚动条:

Private Sub mnuScroll1_Click()
@#注意:必须在网页完全显示之后才可以运行
WebBrowser1.Document.body.Scroll = “no” @#不显示滚动条的办法
End Sub
Private Sub mnuScroll2_Click()
@#注意:必须在网页完全显示之后才可以运行
WebBrowser1.Document.body.Scroll = “Auto” @#显示滚动条的办法
End Sub

2、如何获得网页中被选中部分的HTML:

Private Sub Command1_Click()
Dim objSelection
Dim objTxtRange

Set objSelection = WebBrowser1.Document.selection
If Not (objSelection Is Nothing) Then
Set objTxtRange = objSelection.createRange
If Not (objTxtRange Is Nothing) Then
Debug.Print objTxtRange.htmlText

Set objTxtRange = Nothing
End If
Set objSelection = Nothing
End If
End Sub

Private Sub Form_Load()
WebBrowser1.Navigate “http://www.applevb.com”
End Sub

Navigate 方 法 的 语 法 格 式 为:

WebBrowser 控 件 名.Navigate URL
[Flags,][TargetFrameName,][PostData,][Headers]

—- WebBrowser 控 件 支 持 的 主 要 方 法 有:

GoBack — — — 回 退 到 上 一 屏。
GoForward — — — 进 入 到 下 一 屏。
GoHome — — — 回 家。 即 回 到 主 页。
Stop — — — 停 止 导 航。
Refresh — — — 刷 新。
Navigate — — — 导 航。

—- WebBrowser 控 件 所 响 应 的 事 件:

—- BeforeNavigate 事 件 — — — 在 开 始 导 航 前 发 生。 一 般 在 此 获 取 完 整 的URL 字 符 串。

—- WebBrowser 控 件 最 主 要 的 参 数:

—- URL — — — 获 得 导 航 用 的 标 准URL 字 符 串。 例 如: 它 能 将”www.MicroSoft.Com” 自 动 翻 译 为”http://www.MicroSoft.Com”.URL 是Uniform Resource Locator 的 缩 写, 是 在Internet 的WWW 服 务 程 序 上 用 于 指 定 信 息 位 置 的 表 示 方 法。

使用WebBrowser的Navigator或者Navigator2方法打开一个asp文档并且传递

参数进去,但是asp文档无法获得参数,请教是什么原因?

vb源码:
Private Sub cmdSubmit_Click()
Dim strURL As String, strFormData As String
Dim strData As String
strURL = Trim$(txtURL.Text)
strFormData = “name=” & Trim$(txtName.Text) &

“&password=” & Trim$(txtPassword.Text)
Call WBTest.Navigate2(strURL, 64, “_blank”, strFormData,

“hello”)
End Sub

asp源码:

<%@ Language=VBScript %>
<%
dim strName
dim strPassword
strName=Trim(Request.Form(“name”))
strPassword=Trim(Request.Form(“password”))
Response.Write(strName)
Response.Write(strPassword)
if strName=”KingZhang” and strPassword=”123456″ then
Response.Write(“登陆成功“)
else
Response.Write(“非法登陆用户!”)
end if

%>

*********************************************************************

Option Explicit

Private Sub Command1_Click()
Dim szValue As String
WebBrowser1.Document.body.innerHTML = ”

method=post action=http://地址/xxx.php>


WebBrowser1.Document.Forms(“post”).submit
End Sub

Private Sub Form_Load()
WebBrowser1.Navigate2 “about:blank”
End Sub
Top

********************************************************************

请问:在WebBrwoser控件里提供的Navigate或者Navigate2方法中提供了传递数据

的参数,调用方式为:WebBrowser1.Navigate2(URL,[Flags],

[TargetFrameName],[PostData],[Headers])
其中PostData参数就是一个提交参数字符串,例如”name=aaa&password=123″,

但问题是为什么这个方法并不是有效的,服务器端不能取得数据?
如果这个方法是有效的话就不需要用一段html代码模拟这种调用了。

下面代码能检测出程序post出去的消息

Private Sub WebBrowser1_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
MsgBox PostData
End Sub

WebBrowser的8个方法和13个属性

WebBrowser的8个方法和13个属性,以及它们的功能:

方法 说明
GoBack 相当于IE的“后退”按钮,使你在当前历史列表中后退一项

GoForward 相当于IE的“前进”按钮,使你在当前历史列表中前进一项
GoHome 相当于IE的“主页”按钮,连接用户默认的主页
GoSearch 相当于IE的“搜索”按钮,连接用户默认的搜索页面
Navigate 连接到指定的URL
Refresh 刷新当前页面
Refresh2 同上,只是可以指定刷新级别,所指定的刷新级别的值来自RefreshConstants枚举表,
该表定义在ExDisp.h中,可以指定的不同值如下:
REFRESH_NORMAL 执行简单的刷新,不将HTTP pragma: no-cache头发送给服务器
REFRESH_IFEXPIRED 只有在网页过期后才进行简单的刷新
REFRESH_CONTINUE 仅作内部使用。在MSDN里写着DO NOT USE! 请勿使用
REFRESH_COMPLETELY 将包含pragma: no-cache头的请求发送到服务器

Stop 相当于IE的“停止”按钮,停止当前页面及其内容的载入
属性 说明
Application 如果该对象有效,则返回掌管WebBrowser控件的应用程序实现的自动化对象(IDispatch)。如果在宿主对象中自动化对象无效,这个程序将返回WebBrowser
控件的自动化对象
Parent 返回WebBrowser控件的父自动化对象,通常是一个容器,例如是宿主或IE窗口
Container 返回WebBrowser控件容器的自动化对象。通常该值与Parent属性返回的值相同
Document 为活动的文档返回自动化对象。如果HTML当前正被显示在WebBrowser中,则
Document属性提供对DHTML Object Model的访问途径
TopLevelContainer 返回一个Boolean值,表明IE是否是WebBrowser控件顶层容器,是就返回true

Type 返回已被WebBrowser控件加载的对象的类型。例如:如果加载.doc文件,就会返
回Microsoft Word Document
Left 返回或设置WebBrowser控件窗口的内部左边与容器窗口左边的距离
Top 返回或设置WebBrowser控件窗口的内部左边与容器窗口顶边的距离
Width 返回或设置WebBrowser窗口的宽度,以像素为单位
Height 返回或设置WebBrowser窗口的高度,以像素为单位
LocationName 返回一个字符串,该字符串包含着WebBrowser当前显示的资源的名称,如果资源
是网页就是网页的标题;如果是文件或文件夹,就是文件或文件夹的名称
LocationURL 返回WebBrowser当前正在显示的资源的URL
Busy 返回一个Boolean值,说明WebBrowser当前是否正在加载URL,如果返回true
就可以使用stop方法来撤销正在执行的访问操作

如何利用 WebBrowser 控件,显示 .GIF 动画?

要有一定的网页知识(HTML、JavaScript、CSS)
注意细节:
没有”滚动条”和”鼠标右键弹出的 IE 上下文菜单”,”.HTM 源文件” …
我写了一个,效果还真不错!

‘Objects: Form1、Command1、CommonDialog1、WebBrowser1
Option Explicit
Private Sub Command1_Click()
CommonDialog1.ShowOpen
If VBA.Len(VBA.Trim(CommonDialog1.FileName)) > 0 Then
Dim p As stdole.StdPicture
Dim sPath As String
sPath = VBA.Trim(VBA.Trim(CommonDialog1.FileName))
Set p = VB.LoadPicture(sPath)
WebBrowser1.Width = p.Width * 16 / 26
WebBrowser1.Height = p.Height * 16 / 26
‘ WebBrowser1.Navigate “about:blank”
WebBrowser1.Document.open
WebBrowser1.Document.writeln “”
WebBrowser1.Document.writeln “”
WebBrowser1.Document.writeln “”
WebBrowser1.Document.writeln “”
WebBrowser1.Document.writeln “WebBrowser1.Document.writeln ”

WebBrowser1.Document.writeln “WebBrowser1.Document.writeln “


WebBrowser1.Document.writeln “”
WebBrowser1.Document.writeln “”
End If
End Sub
Private Sub Form_Load()
Command1.Caption = “&Open”
WebBrowser1.Navigate “about:blank”
WebBrowser1.Document.open
WebBrowser1.Document.writeln “”
WebBrowser1.Document.writeln “”
WebBrowser1.Document.writeln “”
WebBrowser1.Document.writeln “”
WebBrowser1.Document.writeln “WebBrowser1.Document.writeln “”
WebBrowser1.Document.writeln “”
WebBrowser1.Document.Close
End Sub

WebBrowser控件说明
方法 说明
GoBack 相当于IE的“后退”按钮,使你在当前历史列表中后退一项

GoForward 相当于IE的“前进”按钮,使你在当前历史列表中前进一项
GoHome 相当于IE的“主页”按钮,连接用户默认的主页
GoSearch 相当于IE的“搜索”按钮,连接用户默认的搜索页面
Navigate 连接到指定的URL
Refresh 刷新当前页面
Refresh2 同上,只是可以指定刷新级别,所指定的刷新级别的值来自RefreshConstants枚举表,
该表定义在ExDisp.h中,可以指定的不同值如下:
REFRESH_NORMAL 执行简单的刷新,不将HTTP pragma: no-cache头发送给服务器
REFRESH_IFEXPIRED 只有在网页过期后才进行简单的刷新
REFRESH_CONTINUE 仅作内部使用。在MSDN里写着DO NOT USE! 请勿使用
REFRESH_COMPLETELY 将包含pragma: no-cache头的请求发送到服务器

Stop 相当于IE的“停止”按钮,停止当前页面及其内容的载入

属性 说明
Application 如果该对象有效,则返回掌管WebBrowser控件的应用程序实现的自动化对象(IDispatch)。如果在宿主对象中自动化对象无效,这个程序将返回WebBrowser
控件的自动化对象
Parent 返回WebBrowser控件的父自动化对象,通常是一个容器,例如是宿主或IE窗口
Container 返回WebBrowser控件容器的自动化对象。通常该值与Parent属性返回的值相同
Document 为活动的文档返回自动化对象。如果HTML当前正被显示在WebBrowser中,则
Document属性提供对DHTML Object Model的访问途径
TopLevelContainer 返回一个Boolean值,表明IE是否是WebBrowser控件顶层容器,是就返回true

Type 返回已被WebBrowser控件加载的对象的类型。例如:如果加载.doc文件,就会返
回Microsoft Word Document
Left 返回或设置WebBrowser控件窗口的内部左边与容器窗口左边的距离
Top 返回或设置WebBrowser控件窗口的内部左边与容器窗口顶边的距离
Width 返回或设置WebBrowser窗口的宽度,以像素为单位
Height 返回或设置WebBrowser窗口的高度,以像素为单位
LocationName 返回一个字符串,该字符串包含着WebBrowser当前显示的资源的名称,如果资源
是网页就是网页的标题;如果是文件或文件夹,就是文件或文件夹的名称
LocationURL 返回WebBrowser当前正在显示的资源的URL
Busy 返回一个Boolean值,说明WebBrowser当前是否正在加载URL,如果返回true
就可以使用stop方法来撤销正在执行的访问操作

WebBrowser 的事件
Private Events Description
BeforeNavigate2 导航发生前激发,刷新时不激发
CommandStateChange 当命令的激活状态改变时激发。它表明何时激活或关闭Back和Forward
菜单项或按钮
DocumentComplete 当整个文档完成是激发,刷新页面不激发
DownloadBegin 当某项下载操作已经开始后激发,刷新也可激发此事件
DownloadComplete 当某项下载操作已经完成后激发,刷新也可激发此事件
NavigateComplete2 导航完成后激发,刷新时不激发
NewWindow2 在创建新窗口以前激发
OnFullScreen 当FullScreen属性改变时激发。该事件采用VARIENT_BOOL的一个输
入参数来指示IE是全屏显示方式(VARIENT_TRUE)还是普通显示方式(VARIENT_FALSE)
OnMenuBar 改变MenuBar的属性时激发,标示参数是VARIENT_BOOL类型的。
VARIANT_TRUE是可见,VARIANT_ FALSE是隐藏
OnQuit 无论是用户关闭浏览器还是开发者调用Quit方法,当IE退出时就会激发
OnStatusBar 与OnMenuBar调用方法相同,标示状态栏是否可见。
OnToolBar 调用方法同上,标示工具栏是否可见。
OnVisible 控制窗口的可见或隐藏,也使用一个VARIENT_BOOL类型的参数
StatusTextChange 如果要改变状态栏中的文字,这个事件就会被激发,但它并不理会程序是否有状态栏
TitleChange Title有效或改变时激发
WEBBROWSER 技巧(收藏)

看到很多关于WebBrowser控件禁止右键的提问,回复的方法很多,其中有提到使用微软提供的Webbrowser扩展COM服务器对象 (WBCustomizer.dll),但是该方法在我们想使用Webbrowser编辑网页 (Webbrowser1.Document.execCommand editMode)的时候有很多弊端,比如不能显示选中的文本等。另有些方法也就不用一一列举了。

这儿我想提到的是关于MSHTML.HTMLDocument

引用Microsoft HTML OBject Library

Rem #窗体代码#

Dim WithEvents M_Dom As MSHTML.HTMLDocument
Private Function M_Dom_oncontextmenu() As Boolean
M_Dom_oncontextmenu = False
End Function

Private Sub Webbrowser1_DownloadComplete()
Set M_Dom = Webbrowser1.Document
End Sub

Rem 好了,右键菜单没有了

=======================================================================

控件调用和获得收藏夹里面

基本上用 specialfolder(6 ) 就可以得到收藏夹的路径, 然后你可以用dir去循环读入每个目录,然后dir里面的file, file的名字就是你要的收藏的名字, 路径可以自己根据从上面得到的路径去得到.
如果你不用dir也可以用vb的dir控件.
Private Type SHITEMID
cb As Long
abID As Byte
End Type

Public Type ITEMIDLIST
mkid As SHITEMID
End Type
Public Function SpecialFolder(ByRef CSIDL As Long) As String
locate the favorites folder
Dim R As Long
Dim sPath As String
Dim IDL As ITEMIDLIST
Const NOERROR = 0
Const MAX_LENGTH = 260
R = SHGetSpecialFolderLocation(MDIMain.hwnd, CSIDL, IDL)
If R = NOERROR Then
sPath = Space$(MAX_LENGTH)
R = SHGetPathFromIDList(ByVal IDL.mkid.cb, ByVal sPath)
If R Then
SpecialFolder = Left$(sPath, InStr(sPath, vbNullChar) – 1)
End If
End If
End Function
================================================================

是的,webbrowser本生是一个控件, 你要它全屏,就是要它所在的窗体全屏, 可以用setwindowlong取消窗体的 title, 用Call ShowWindow(FindWindow(Shell_traywnd, ), 0) 隐藏tray,就是下边那个包含开始那一行. 用Call ShowWindow(FindWindow(Shell_traywnd, ), 9) 恢复. 够详细了吧.

然后在form1.windowstate = 2 就可以了.

====================================================================
选择网页上的内容。
Private Sub Command1_Click()
请先选中一些内容
Me.WebBrowser1.ExecWB OLECMDID_COPY, OLECMDEXECOPT_DODEFAULT
MsgBox Clipboard.GetText
End Sub

=============================================================
用IE来下载文件
Private Declare Function DoFileDownload Lib shdocvw.dll (ByVal lpszFile As String) As Long

Private Sub Command1_Click()

Dim sDownload As String

sDownload = StrConv(Text1.Text, vbUnicode)
Call DoFileDownload(sDownload)

End Sub

保存webbrowser中的HTML内容
Dim oPF As IPersistFile
Set oPF = WebBrowser1.Document
oPF.Save “TheFileNameHere.htm”, False

WebBrowser1.ExecWB怎么用

下面是我测试的参数
WB.ExecWB(4,1)

4,1 保存网页
4,2 保存网页(可以重新命名)
6,1 直接打印
6,2 直接打印
7,1 打印预览
7,2 打印预览
8,1 选择参数
8,2 选择参数
10,1 查看页面属性
10,2 查看页面属性
17,1 全选
17,2 全选
22,1 重新载入当前页
22,2 重新载入当前页

webbrowser确定对话框的正确方法
webbrowser确定窗口对话框

某些网页出于各种考虑会弹出对话框要求信息确认,往往会中断我们的webbrowser过程,可以使用如下方法:
1.加入Microsoft Html Object
2.加入语句

Private Sub WebBrowser1_NavigateComplete2(ByVal pDisp As Object, URL As Variant)
Dim obj As HTMLDocument
Set obj = pDisp.Document
obj.parentWindow.execScript “function showModalDialog(){return;}” ‘对showModalDialog引起的对话框进行确定
End Sub
而confirm引发的对话确定框可用confirm替换showModalDialog即可,Alert等同理~

WebBrowser取得网页源码Private Sub Command1_Click()
WebBrowser1.Navigate “http://www.sdqx.gov.cn/sdcity.php”
End Sub

Private Sub WebBrowser1_DownloadComplete()
‘页面下载完毕
Dim doc, objhtml
Set doc = WebBrowser1.Document

Set objhtml = doc.body.createtextrange()
If Not IsNull(objhtml) Then
Text1.Text = objhtml.htmltext
End If

End Sub

我用WebBrowser取得网页源码,直接运行正常,但在编译后出错

提示:实时错误“91” Object 变量或 with 块变量没有设置
可能是没有下载完所致,

Private Sub WebBrowser1_DownloadComplete()
if webbrowser.busy=false then
Dim doc, objhtml
Set doc = WebBrowser1.Document

Set objhtml = doc.body.createtextrange()
If Not IsNull(objhtml) Then
Text1.Text = objhtml.htmltext
End If
end if
End Sub

[转载]C# WinForm开发系列 - WebBrowser - peterzb - 博客园

mikel阅读(1096)

[转载]C# WinForm开发系列 – WebBrowser – peterzb – 博客园.  介绍Vs 2005中带的WebBrowser控件使用以及一些疑难问题的解决方法, 如如何正确显示中文, 屏蔽右键菜单, 设置代理等; 收集的文章中有可能还带了一些ASP.NET开发使用微软的WebBrowser进行页面打印方面文章.

01. vs2005中的WebBrowser控件的简单应用

02. WebBrowser控件的简单应用2

03. WebBrowser控件应用:弹出新窗体和关闭窗口

04. WebBrowser控件应用:播放PPT文件

05. WebBrowser控件使用技巧分享

06. .Net 2.0实例学习:WebBrowser页面与WinForm交互技巧

07. WebBrowser脚本错误的完美解决方案

08. Winform: use the WebBrowser to display XML with xslt, xml, xslt 转 html 字符串

09. 使用Vs2005打造简单分页浏览器(1)原创

10. 利用WebBrowser彻底解决Web打印问题

11. WebBrowser

12. WebBrowser控件使用详解

13. webBrowser.execWB的完整说明

14. C#中WebBrowser的使用

15. C#中实现WebBrowser控件的HTML源代码读写

16. Webbrowser控件史上最强技巧全集

17. 利用WebBrowser实现Web打印的分析

18. 利用webBrowser获取框架内Html页面内容

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

20. [原创]C/S模式开发中如何利用WebBrowser控件制作导航窗体

21. WebBrowser!

22. 网上收集的WebBrowser的Cookie操作

23. 使用WebBrowser控件时在网页元素上绘制文本或其他自定义内容

24. WebBrowser编程简述

25. 网页抓取之WebBrowser

26. WebBrowser的一些疑惑

27. 在VB.NET中如何使在Webbrowser中实现标签页中打开新链接

28. WebBrowser 控件 内存溢出 补丁 From Microsoft

29. [原创]在权限设计中利用WebBrowser设计可变数目权限的一种设计方法

30. 利用IDocHostUIHandler接口屏蔽WebBrowser的弹出菜单

31. 学习vs2005中webbrowser控件

32. 如何用webbrowser自动点击网页中的一个按钮

33. 几个WebBrowser相关的函数–原创

34. 施昌权-博客 WebBrowser控件说明

 

35. 从WebBrowser中取得Cookie 和 WebClient设置cookie!

36. 使用Webbrowser的一点心得体会

37. 关于webbrowser控件自动登陆的问题

38. WebBrowser

39. 屏蔽webbrowser控件右键的一种方法

40. 关于WebBrowser(浏览器)控件的调用

41. .Net2.0 –Winform结合WebBrowser控件和Socket老技术来实现另类Push~

42. A WebBrowser Toy

43. Webbrowser代理支持

44. 如何清除应用程序承载 WebBrowser 控件时缓存

45. C# WebBrowser 代理的使用

46.  WinForm开发浏览器,WebBrowser获取页面内容,如何解决中文乱码

47. 关于WebBrowser.DocumentCompleted事件

作者:peterzb个人开发历程知识库 – 博客园
出处:http://peterzb.cnblogs.com/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

[转载]vs2005中的WebBrowser控件的简单应用 - 横刀立马者 - 博客园

mikel阅读(1036)

[转载]vs2005中的WebBrowser控件的简单应用 – 横刀立马者 – 博客园.这个控件被封装了一下,和以前的调用方式稍有不同。

事件还是那几个,变化不大。

方法变了不少。

从网上能查到的资料不多,贴出一些代码来作参考。

看看这段代码,可以用来分析网页上的元素的类型的。

        private void btn_Find_Click(object sender, EventArgs e)
        
{
            
//find all the input controls on the page
            if (this.wb_Show.Document == null)
            
{
                MessageBox.Show(
请先打开一个要分析的网页);
                
return;
            }

            
string type = this.cbx_type.Text.ToLower().Trim();
            
if (type == “”)
            
{
                MessageBox.Show(
请选择一个分析对象的类型);
                
return;
            }

            
this.lb_InputList.Items.Clear();
            HtmlDocument htm 
= this.wb_Show.Document;
            HtmlElementCollection all 
= htm.All;
            
for (int i = 0; i < all.Count; i++)
            
{
                HtmlElement elem 
= all[i];
                
if (elem.TagName.ToLower() == type)
                
{
                    
this.lb_InputList.Items.Add(elem.Name);
                }

            }

            MessageBox.Show(
总共找到 + this.lb_InputList.Items.Count.ToString() + 个符合条件的结果);
        }

这一段代码是用来触发按钮事件的,注意使用的是click参数

                     if (elem.Name.ToLower() == login.Attributes[name].Value)
                     
{
                         
//elem.InvokeMember(“click”);
                         elem.InvokeMember(click);

                     }

对于form的提交,得使用submit


             
else
             
{
                 XmlNode form 
= FindNode(form);
                 htm.Forms[form.Attributes[
name].Value].InvokeMember(submit);
             }

获取值,和赋值类似

                XmlNode userName = FindNode(userName);
                
if (elem.TagName.ToLower() == input && elem.Name.ToLower() == userName.Attributes[name].Value)
                
{
                    elem.InnerText 
= userName.InnerText;
                }

可以使用这些简单的应用做一个网页自动登录之类的系统

[转载].Net 2.0实例学习:WebBrowser页面与WinForm交互技巧 - smalldust - 博客园

mikel阅读(1023)

[转载].Net 2.0实例学习:WebBrowser页面与WinForm交互技巧 – smalldust – 博客园.

最近看到博客园入门教学文章比较流行,自己最近又偷懒比较多,没啥心得,不妨写一篇没啥深度的入门文章吧。

话说有了WebBrowser类,终于不用自己手动封装SHDocVw的AxWebBrowser这个ActiveX控件了。这个类如果仅仅作为一 个和IE一模一样浏览器,那就太没意思了(还不如直接用IE呢)。那么,无论我们是想做一个“定制版IE”,还是希望利用HTML来做用户界面(指 WinApp而非WebApp。许多单机软件,包括Windows的帮助支持中心,都是HTML做的),都少不了Windows Form和包含在WebBrowser中的Web页面的交互。本文将通过几个实际的例子,初步介绍一下WinForm和WebBrowser所包含的 Web页面之间的交互。

下面的代码假设你已经建立了一个Windows Form,上面有一个WebBrowser名为“webBrowser”。

Study Case 1:用WinForm的Event Handler响应Web页面的事件

现在有这样一个Windows Application,它的界面上只有一个WebBrowser,显示一个本地的HTML文件作为界面。现在的问题是,所有逻辑都可以放在HTML文件 里,唯独“关闭”按钮遇到了困难——通常,Web页面是没有办法直接控制浏览器的,更不用说结束这个WinForm程序了。

但是,在.Net 2.0当中,“由Windows Form响应Web页面的事件”已经成为了现实。

在.Net 2.0中,整个HTML文档以及其包含的各个HTML元素,都和一个个HtmlDocument、HtmlElement之类的.Net对象对应。因此只 要找到这个“关闭”按钮对应的HtmlElement对象,为其click事件添加Event Handler即可。

假设HTML源代码如下:

<html>
<body>
<input type=”button” id=”btnClose” value=”关闭” />
</body>
</html>

那么找出该按钮并为之添加Event Handler的代码如下:

HtmlDocument htmlDoc = webBrowser.Document;
HtmlElement btnElement 
= htmlDoc.All[btnClose];
if (btnElement != null)
{
btnElement.click 
+= new HtmlElementEventHandler(HtmlBtnClose_Click);
}

其中HtmlBtnClose_Click是按下Web按钮时的Event Handler。

很简单吧?那么稍稍高级一点的——我们都知道一个HTML元素可能有很多各种各样的事件,而HtmlElement这个类只给出最常用、共通的几 个。那么,如何响应其他事件呢?这也很简单,只需要调用HtmlElement的AttachEventHandler就可以了:

btnElement.AttachEventHandler(onclicknew EventHandler(HtmlBtnClose_Click));
//这一句等价于上面的btnElement.click += new HtmlElementEventHandler(HtmlBtnClose_Click); 

对于其他事件,把”onclick”换成该事件的名字就可以了。例如:

formElement.AttachEventHandler(onsubmitnew EventHandler(HtmlForm_Submit)); 

Study Case 2:表单(form)的自动填写和提交

要使我们的WebBrowser具有自动填表、甚至自动提交的功能,并不困难。

假设有一个最简单的登录页面,输入用户名密码,点“登录”按钮即可登录。已知用户名输入框的id(或Name,下同)是username,密码输入 框的id是password,“登录”按钮的id是submitbutton,那么我们只需要在webBrowser的 DocumentCompleted事件中使用下面的代码即可:

HtmlElement btnSubmit = webBrowser.Document.All[submitbutton];
HtmlElement tbUserid 
= webBrowser.Document.All[username];
HtmlElement tbPasswd 
= webBrowser.Document.All[password];

if (tbUserid == null || tbPasswd == null || btnSubmit == null)
return;

tbUserid.SetAttribute(valuesmalldust);
tbPasswd.SetAttribute(
value12345678);

btnSubmit.InvokeMember(click);

这里我们用SetAttribute来设置文本框的“value”属性,用InvokeMember来调用了按钮的“click”方法。因为不同的 Html元素,其拥有的属性和方法也不尽相同,所以.Net 2.0提供了统一的HtmlElement来概括各种Html元素的同时,提供了这两个方法以调用元素特有的功能。关于各种Html元素的属性和方法一 览,可以查阅MSDN的DHTML Reference

※关于表单的提交,的确还有另一种方法就是获取form元素而不是button,并用form元素的submit方法:

HtmlElement formLogin = webBrowser.Document.Forms[loginForm];
//…… 
formLogin.InvokeMember(submit); 

本文之所以没有推荐这种方法,是因为现在的网页,很多都在submit按钮上添加onclick事件,以对提交的内容做最基本的验证。如果直接使用form的submit方法,这些验证代码就得不到执行,有可能会引起错误。

Study Case 3:查找并选择文本

这次我们希望实现一个和IE一模一样的查找功能,以对Web页面内的文字进行查找。

文本查找要借助于TextRange对象的findText方法。但是,.Net里并没有这个对象。这是因为,.Net 2.0提供的HtmlDocument,HtmlWindow,HtmlElement等类,只不过是对原有mshtml这个COM组件的不完整封装,只 提供了mshtml的部分功能。所以许多时候,我们仍旧要借助mshtml来实现我们需要的功能。好在这些.Net类都提供了DomDocument这个 属性,使得我们很容易把.Net对象转换为COM对象使用。下面的代码演示了如何查找Web页面的文本。
(需要添加mshtml的引用,并加上using mshtml;)

    public partial class SearchDemo : Form
{
// 建立一个查找用的TextRange(IHTMLTxtRange接口) 
        private IHTMLTxtRange searchRange = null;
public SearchDemo()
{
InitializeComponent();
}

private void btnSearch_Click(object sender, EventArgs e)
{
// Document的DomDocument属性,就是该对象内部的COM对象。 
            IHTMLDocument2 document = (IHTMLDocument2)webBrowser.Document.DomDocument;
string keyword = txtKeyword.Text.Trim();
if (keyword == “”)
return;

// IE的查找逻辑就是,如果有选区,就从当前选区开头+1字符处开始查找;没有的话就从页面最初开始查找。
// 这个逻辑其实是有点不大恰当的,我们这里不用管,和IE一致即可。 
            if (document.selection.type.ToLower() != none)
{
searchRange 
= (IHTMLTxtRange)document.selection.createRange();
searchRange.collapse(
true);
searchRange.moveStart(
character1);
}
else
{
IHTMLBodyElement body 
= (IHTMLBodyElement)document.body;
searchRange 
= (IHTMLTxtRange)body.createTextRange();
}

// 如果找到了,就选取(高亮显示)该关键字;否则弹出消息。 
            if (searchRange.findText(keyword, 10))
{
searchRange.select();
}
else
{
MessageBox.Show(
已搜索到文档结尾。);
}
}

到此为止,简单的查找就搞定了。至于替换功能,看了下一个例子,我相信你就可以触类旁通轻松搞定了。

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, 14))
{
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(DoAddnew object[] { 12 });
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,今天就写到这里吧,再想起什么来再补充吧。欢迎大家多多指正,欢迎讨论。

善待用户 善待自己的网站

mikel阅读(1531)

 

很多时候,都是在后台折腾着自己的网站,更新文章,审核信息之类的功能上的东西,很少自己去体验下网站的功能,很多人都有很多网站,尽管为了百度排名,每天都更新文章,迎合蜘蛛的口味,做排名,很多时候自己都觉得自己的网站没啥可看的,用着用着的时候也感觉这块儿很难用,可是就是懒得改进,结果越来越难用。

最近就遇到了这样的情况,自己的网站用得很不顺手,已经忍了很久了,终于忍无可忍了,痛下杀手改程序,很多时候我都觉得东西不坏就不要碰,可是真心的很不顺手啊!自己的网站自己都用得不顺手,还真的对不起那些访问的用户,最近大面积的改写程序功能,是时候善待自己的网站和用户了。

网站如此移动应用更是如此,最近移动互联网热火朝天得比过年还热闹,微信引爆了2015年的互联网媒体,更多的倒是看客,挣钱的还是闷头赚钱,不赚钱的都在那吆喝。反观操作系统,最近微软的动作不可谓不大,Windows 10横空出世,全息影像的操作让人眼前一亮,电影中的场景终于要实现了吗?!从facebook搞AR开始,眼镜真得就那么必要吗?!虚拟现实想要进一步落地,看来还有些时日,拭目以待微软的Windows 10吧!

20141110080510ce3ae

从网站谈到移动互联网,再到操作系统哪一个都是用户体验占据了主导地位,不管是微软、微信还是屌丝站长都在想办法让用户体验更好,不过首先要先善待用户吧!

 

[转载]Android性能优化典范 - Healtheon - 博客园

mikel阅读(1115)

[转载]Android性能优化典范 – Healtheon – 博客园.

  2015年伊始,Google发布了关于Android性能优化典范的专题, 一共16个短视频,每个3-5分钟,帮助开发者创建更快更优秀的Android App。课程专题不仅仅介绍了Android系统中有关性能问题的底层工作原理,同时也介绍了如何通过工具来找出性能问题以及提升性能的建议。主  要从 三个方面展开,Android的渲染机制,内存与GC,电量优化。下面是对这些问题和建议的总结梳理。

  0)Render Performance

大多数用户感知到的卡顿等性能问题的最主要根源都是因为渲染性能。从设计师的角度,他们希望App能够有更多的动画,图片等时尚元素来实现流畅 的用户体验。但是Android系统很有可能无法及时完成那些复杂的界面渲染操作。Android系统每隔16ms发出VSYNC信号,触发对UI进行渲 染,如果每次渲染都成功,这样就能够达到流畅的画面所需要的60fps,为了能够实现60fps,这意味着程序的大多数操作都必须在16ms内完成。

如果你的某个操作花费时间是24ms,系统在得到VSYNC信号的时候就无法进行正常渲染,这样就发生了丢帧现象。那么用户在32ms内看到的会是同一帧画面。

用户容易在UI执行动画或者滑动ListView的时候感知到卡顿不流畅,是因为这里的操作相对复杂,容易发生丢帧的现象,从而感觉卡顿。有很 多原因可以导致丢帧,也许是因为你的layout太过复杂,无法在16ms内完成渲染,有可能是因为你的UI上有层叠太多的绘制单元,还有可能是因为动画 执行的次数过多。这些都会导致CPU或者GPU负载过重。

我们可以通过一些工具来定位问题,比如可以使用HierarchyViewer来查找Activity中的布局是否过于复杂,也可以使用手机设 置里面的开发者选项,打开Show GPU Overdraw等选项进行观察。你还可以使用TraceView来观察CPU的执行情况,更加快捷的找到性能瓶颈。

 1)Understanding Overdraw

Overdraw(过度绘制)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结构里面,如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次。这就浪费大量的CPU以及GPU资源。

 

当设计上追求更华丽的视觉效果的时候,我们就容易陷入采用越来越多的层叠组件来实现这种视觉效果的怪圈。这很容易导致大量的性能问题,为了获得最佳的性能,我们必须尽量减少Overdraw的情况发生。

幸运的是,我们可以通过手机设置里面的开发者选项,打开Show GPU Overdraw的选项,可以观察UI上的Overdraw情况。

蓝色,淡绿,淡红,深红代表了4种不同程度的Overdraw情况,我们的目标就是尽量减少红色Overdraw,看到更多的蓝色区域。

Overdraw有时候是因为你的UI布局存在大量重叠的部分,还有的时候是因为非必须的重叠背景。例如某个Activity有一个背景,然后 里面的Layout又有自己的背景,同时子View又分别有自己的背景。仅仅是通过移除非必须的背景图片,这就能够减少大量的红色Overdraw区域, 增加蓝色区域的占比。这一措施能够显著提升程序性能。

 2)Understanding VSYNC

为了理解App是如何进行渲染的,我们必须了解手机硬件是如何工作,那么就必须理解什么是VSYNC

在讲解VSYNC之前,我们需要了解两个相关的概念:

  • Refresh Rate:代表了屏幕在一秒内刷新屏幕的次数,这取决于硬件的固定参数,例如60Hz。
  • Frame Rate:代表了GPU在一秒内绘制操作的帧数,例如30fps,60fps。

GPU会获取图形数据进行渲染,然后硬件负责把渲染后的内容呈现到屏幕上,他们两者不停的进行协作。

不幸的是,刷新频率和帧率并不是总能够保持相同的节奏。如果发生帧率与刷新频率不一致的情况,就会容易出现Tearing的现象(画面上下两部分显示内容发生断裂,来自不同的两帧数据发生重叠)。

理解图像渲染里面的双重与三重缓存机制,这个概念比较复杂,请移步查看这里:http://source.android.com/devices/graphics/index.html,还有这里http://article.yeeyan.org/view/37503/304664

通常来说,帧率超过刷新频率只是一种理想的状况,在超过60fps的情况下,GPU所产生的帧数据会因为等待VSYNC的刷新信息而被Hold住,这样能够保持每次刷新都有实际的新的数据可以显示。但是我们遇到更多的情况是帧率小于刷新频率。

在这种情况下,某些帧显示的画面内容就会与上一帧的画面相同。糟糕的事情是,帧率从超过60fps突然掉到60fps以下,这样就会发生LAGJANKHITCHING等卡顿掉帧的不顺滑的情况。这也是用户感受不好的原因所在。

  3)Tool:Profile GPU Rendering

性能问题如此的麻烦,幸好我们可以有工具来进行调试。打开手机里面的开发者选项,选择Profile GPU Rendering,选中On screen as bars的选项。

选择了这样以后,我们可以在手机画面上看到丰富的GPU绘制图形信息,分别关于StatusBar,NavBar,激活的程序Activity区域的GPU Rending信息。

随着界面的刷新,界面上会滚动显示垂直的柱状图来表示每帧画面所需要渲染的时间,柱状图越高表示花费的渲染时间越长。

中间有一根绿色的横线,代表16ms,我们需要确保每一帧花费的总时间都低于这条横线,这样才能够避免出现卡顿的问题。

每一条柱状线都包含三部分,蓝色代表测量绘制Display List的时间,红色代表OpenGL渲染Display List所需要的时间,黄色代表CPU等待GPU处理的时间。

  4)Why 60fps?

我们通常都会提到60fps与16ms,可是知道为何会是以程序是否达到60fps来作为App性能的衡量标准吗?这是因为人眼与大脑之间的协作无法感知超过60fps的画面更新。

12fps大概类似手动快速翻动书籍的帧率,这明显是可以感知到不够顺滑的。24fps使得人眼感知的是连续线性的运动,这其实是归功于运动模 糊的效果。24fps是电影胶圈通常使用的帧率,因为这个帧率已经足够支撑大部分电影画面需要表达的内容,同时能够最大的减少费用支出。

但是低于30fps是无法顺畅表现绚丽的画面内容的,此时就需要用到60fps来达到想要的效果,当然超过60fps是没有必要的。

开发app的性能目标就是保持60fps,这意味着每一帧你只有16ms=1000/60的时间来处理所有的任务。

  5)Android, UI and the GPU

了解Android是如何利用GPU进行画面渲染有助于我们更好的理解性能问题。那么一个最实际的问题是:activity的画面是如何绘制到屏幕上的?那些复杂的XML布局文件又是如何能够被识别并绘制出来的?

  Resterization栅格化是绘制那些Button,Shape,Path,String,Bitmap等组件最基础的操作。它把那些组件拆分到不同的像素上进行显示。这是一个很费时的操作,GPU的引入就是为了加快栅格化的操作。

CPU负责把UI组件计算成Polygons,Texture纹理,然后交给GPU进行栅格化渲染。

然而每次从CPU转移到GPU是一件很麻烦的事情,所幸的是OpenGL ES可以把那些需要渲染的纹理Hold在GPU Memory里面,在下次需要渲染的时候直接进行操作。所以如果你更新了GPU所hold住的纹理内容,那么之前保存的状态就丢失了。

在Android里面那些由主题所提供的资源,例如Bitmaps,Drawables都是一起打包到统一的Texture纹理当中,然后再传 递到GPU里面,这意味着每次你需要使用这些资源的时候,都是直接从纹理里面进行获取渲染的。当然随着UI组件的越来越丰富,有了更多演变的形态。例如显 示图片的时候,需要先经过CPU的计算加载到内存中,然后传递给GPU进行渲染。文字的显示更加复杂,需要先经过CPU换算成纹理,然后再交给GPU进行 渲染,回到CPU绘制单个字符的时候,再重新引用经过GPU渲染的内容。动画则是一个更加复杂的操作流程。

为了能够使得App流畅,我们需要在每一帧16ms以内处理完所有的CPU与GPU计算,绘制,渲染等等操作。

[转载]C# MD5-16位加密实例,32位加密实例(两种方法) - 亲,注意身体 - 博客园

mikel阅读(1267)

[转载]C# MD5-16位加密实例,32位加密实例(两种方法) – 亲,注意身体 – 博客园.

1.MD5 16位加密实例
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace md5
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(UserMd5("8"));
Console.WriteLine(GetMd5Str("8"));
}
///
/// MD5 16位加密 加密后密码为大写
///

//////
public static string GetMd5Str(string ConvertString)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
t2 = t2.Replace("-", "");
return t2;
}

///
/// MD5 16位加密 加密后密码为小写
///

//////
public static string GetMd5Str(string ConvertString)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
t2 = t2.Replace("-", "");

t2 = t2.ToLower();

return t2;
}

///
/// MD5 32位加密
///

//////
static string UserMd5(string str)
{
string cl = str;
string pwd = "";
MD5 md5 = MD5.Create();//实例化一个md5对像
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
for (int i = 0; i &lt; s.Length; i++)
{
// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符

pwd = pwd + s[i].ToString("X");

}
return pwd;
}
}
}

using System.Security.Cryptography;
using System.Text;

public static string StringToMD5Hash(string inputString)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] encryptedBytes = md5.ComputeHash(Encoding.ASCII.GetBytes(inputString));
StringBuilder sb = new StringBuilder();
for (int i = 0; i &lt; encryptedBytes.Length; i++)
{
sb.AppendFormat("{0:x2}", encryptedBytes[i]);
}
return sb.ToString();
}

微博终于开放打赏了

mikel阅读(1097)

微信6.1的动作,让互联网不平静的同时,也预示着微信探索盈利模式的开始,变现能力是每个产品不可避免要面临的问题,从互联网到移动互联网,大家都想着法儿让用户爽,然后掏钱消费。这不,微博终于耐不住自媒体春天的寂寞,推出了打赏功能,再也不设置什么粉丝和认证门槛了,这姗姗来迟的功能,又让多少人激动?

u=2277709199,469362917&fm=11&gp=0

不说打赏功能本身,就是这姗姗来迟就值得让人讨论半天了,可以收微博是做自媒体最早的,然而火了起来后,结果发现没人了,为啥?被玩儿坏了!生态系统彻底报废了,广告满天飞,就算是认上阿里这个干爹,也只是打通了淘宝和支付两个渠道,至今没什么亮点,依然是人们看个新闻,八卦的地方,缺乏互动,说娱乐不如微信,说新闻不如门户,说实时最近微信朋友圈比较快了,为什么才推出打赏?背后的故事不得而知,反正出来的时候QQ空间已经玩烂儿这种模式,包括长微博等也是难以为继目前混乱的现象。

互联网只给喜欢创新和适应变化的企业和人。