C#中实现WebBrowser控件的HTML源代码读写
原文:C#中实现WebBrowser控件的HTML源代码读写
C#中实现WebBrowser控件的HTML源代码读写
http://www.blogcn.com/user8/flier_lu/index.html?id=1125200&run=.0D9CAA6
趁周末想折腾一下嵌入ASP.NET的WinForm程序
需要用到WebBrowser控件的HTML源码读写
就把以前的一些代码片断移值到C#下
顺便发个帖子备忘,呵呵
思路其实很简单,直接通过document.documentElement.outerHTML
或者使用IPersistStreamInit接口直接对流进行处理
前者我就不废话了,后者实现方法如下
首先是写入HTML到已初始化的WebBrowser控件
初始化可以通过Navigate("about:blank")完成
必须确保WebBrowser.Document != null
否则应该推迟到DocumentComplete事件再读写
UCOMIStream stream = null;
CreateStreamOnHGlobal(Marshal.StringToHGlobalUni(value), true, out stream);



if(stream != null)

{
IPersistStreamInit persistentStreamInit =
(IPersistStreamInit)WebBrowser.Document;
persistentStreamInit.InitNew();
persistentStreamInit.Load(stream);
persistentStreamInit = null;
}
UCOMIStream是COM中IStream的CLR版本
CreateStreamOnHGlobal函数从一个字符串的地址
创建一个IStream供使用
[DllImport("ole32.dll", PreserveSig=false)]
static extern void CreateStreamOnHGlobal(IntPtr hGlobal,
Boolean fDeleteOnRelease, [Out] out UCOMIStream pStream);然后就是通过IPersistStreamInit接口初始化并载入HTML源码,
IPersistStreamInit接口CLR缺省没有导入,定义如下
[ComVisible(true), ComImport(), Guid("7FD52380-4E07-101B-AE2D-08002B2EC713"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersistStreamInit
{
void GetClassID([In, Out] ref Guid pClassID);
[return: MarshalAs(UnmanagedType.I4)] [PreserveSig]
int IsDirty();
void Load([In, MarshalAs(UnmanagedType.Interface)] UCOMIStream pstm);
void Save([In, MarshalAs(UnmanagedType.Interface)] UCOMIStream pstm,
[In, MarshalAs(UnmanagedType.I4)] int fClearDirty);
void GetSizeMax([Out, MarshalAs(UnmanagedType.LPArray)] long pcbSize);
void InitNew();
}读取HTML也是类似思路,将HTML源码写到一个IStream中
然后转换成字符串供C#代码使用,不过实现方式比较麻烦
比较简单的方法还是使用ole32.dll提供的函数
重建流,但这需要预先设定流的长度,如
UCOMIStream stream = null;
CreateStreamOnHGlobal(Marshal.AllocHGlobal(4096), true, out stream);
IPersistStreamInit persistentStreamInit =
(IPersistStreamInit)WebBrowser.Document;
persistentStreamInit.Save(stream, 0);
persistentStreamInit = null;
IntPtr pStr;
GetHGlobalFromStream(stream, out pStr);
return Marshal.PtrToStringAnsi(pStr);然后使用GetHGlobalFromStream函数和
Marshal.PtrToStringAnsi将流转换为字符串
另外一种方法是自行实现一个支持IStream接口的类
通过流的方式灵活完成读取操作,我比较喜欢这种
using(MemoryStream stream = new MemoryStream())


{
ComStreamAdapter adapter = new ComStreamAdapter(stream);
IPersistStreamInit persistentStreamInit =
(IPersistStreamInit)WebBrowser.Document;
persistentStreamInit.Save(adapter, 0);
stream.Seek(0, SeekOrigin.Begin);
using(StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
这里的ComStreamAdapter是一个使用了adapter模式的类
将普通的System.IO.Stream转换为IStream支持的类
public class ComStreamAdapter : UCOMIStream
{
private Stream _stream;

public ComStreamAdapter(Stream stream)
{
_stream = stream;
}

UCOMIStream Members#region UCOMIStream Members
public void Commit(int grfCommitFlags)
{
}
public void Clone(out UCOMIStream ppstm)
{
ppstm = null;
}
public void CopyTo(UCOMIStream pstm, long cb, System.IntPtr pcbRead, Syste
m.IntPtr pcbWritten)
{
}


public void Revert()
{
}
public void LockRegion(long libOffset, long cb, int dwLockType)
{
}
public void UnlockRegion(long libOffset, long cb, int dwLockType)
{
}
public void Seek(long dlibMove, int dwOrigin, System.IntPtr plibNewPositio
n)
{
_stream.Seek(dlibMove, (SeekOrigin)dwOrigin);
if(plibNewPosition != IntPtr.Zero)
{
Marshal.WriteInt32(plibNewPosition, (int)_stream.Position);
}
}

public void Read(byte[] pv, int cb, System.IntPtr pcbRead)
{
int size = _stream.Read(pv, (int)_stream.Position, cb);
if(pcbRead != IntPtr.Zero)
{
Marshal.WriteInt32(pcbRead, size);
}
}
public void Write(byte[] pv, int cb, System.IntPtr pcbWritten)
{
_stream.Write(pv, 0, cb);
if(pcbWritten != IntPtr.Zero)
{
Marshal.WriteInt32(pcbWritten, cb);
}
}
public void SetSize(long libNewSize)

_stream.SetLength(libNewSize);
}
public void Stat(out STATSTG pstatstg, int grfStatFlag)
{
pstatstg = new STATSTG ();
}
#endregion
}



C#中实现WebBrowser控件的HTML源代码读写的更多相关文章
- Winform中修改WebBrowser控件User-Agent的方法(已经测试成功)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...
- vs2005中的WebBrowser控件的简单应用
原文:vs2005中的WebBrowser控件的简单应用 这个控件被封装了一下,和以前的调用方式稍有不同.事件还是那几个,变化不大.方法变了不少.从网上能查到的资料不多,贴出一些代码来作参考.看看这段 ...
- WPF中嵌入WinForm中的webbrowser控件
原文:WPF中嵌入WinForm中的webbrowser控件 使用VS2008创建WPF应用程序,需使用webbrowser.从工具箱中添加WPF组件中的webbrowser发现其中有很多属性事件不能 ...
- 在VC中使用WebBrowser控件的两方法
ClassWizard方式: 1.创建包装类:View->ClassWizard->Add Class->Form a Type Library->C:/winnt/syste ...
- C#中的WebBrowser控件的使用
0.常用方法 Navigate(string urlString):浏览urlString表示的网址 Navigate(System.Uri url):浏览url表示的网址 Navigate(st ...
- 009. C#中的WebBrowser控件的属性、方法及操作演示代码(转)
本文转自 http://www.open-open.com/code/view/1430559996802 0.常用方法 Navigate(string urlString):浏览urlString表 ...
- WPF中禁止WebBrowser控件打开新窗口
一.针对纯WPF的WebBrowser控件: <summary> Suppress Script Errors In WPF WebBrowser </summary> pub ...
- C#中的WebBrowser控件加载ActiveX插件
C#中WebBrowser控件,将项目输入更改为x86输出,在页面打开时即可自动加载ActiveX控件
- C#中利用WebBrowser控件,获得HTML源码
最近获得网页的几个老程序都不能用了. 我原来用 如下代码获得网页html 源码: <pre name="code" class="csharp"> ...
随机推荐
- Connect2015 简要整理
2015 简要整理 去年 Connect(); 2014 Visual Studio Contact(); 直播笔记 对于我个人来说,今年 Connect(); 的三个重要发布: ASP.NET 5 ...
- Makefile 中:= ?= += =的差别 和条件运行
一:在Makefile中常常看到obj-m := scull.o和KERNELDIR ?= /lib/modules/等不同的赋值方式,如今总结他们的差别: = 是最主要的赋值 := 是覆盖之前 ...
- 为大型数据文件每行只能产生id
为大型数据文件每行只能产生id 4个主要思路: 1 单线程处理 2 普通多线程 3 hive 4 Hadoop 搜到一些參考资料 <Hadoop实战>的笔记-2.Hadoop输入与输出 h ...
- ASP.NET 5 Beta8 发布
ASP.NET 5 Beta8 发布 ASP.NET 5 的路线图(详见 ASP.NET 5 Schedule and Roadmap : https://github.com/aspnet/home ...
- 大数据量传输时配置WCF的注意事项
原文:大数据量传输时配置WCF的注意事项 WCF传输数据量的能力受到许多因素的制约,如果程序中出现因需要传输的数据量较大而导致调用WCF服务失败的问题,应注意以下配置: 1.MaxReceivedMe ...
- Git常用操作汇总(转)
如果一个文件被删除了,可以使用切换版本号进行恢复.恢复方法: 先确定需要恢复的文件要恢复成哪一个历史版本(commit),假设那个版本号是: commit_id,那么 git checkout com ...
- eclipse 中 Android sdk 无法更新的问题
诶,真是麻烦,想下个东西都下不了. 我也好久没折腾过这个了,在家的电脑是早就下载好了的,然后如今又须要下载一份.下不到.网上搜到了资料,记录下来: 第一种方法: sdk manager - ...
- C#版的抓包软件
C#版的抓包软件 [创建时间:2015-09-10 22:37:04] NetAnalyzer下载地址 不好意思啊,NetAnalyzer停更有点长了,今天继续填坑^&^ NetAnaly ...
- 单机部署redis主从备份
redis为了避免单点故障,也支持主从备份.个人在做主从备份的实验时,因为机器数量有限,一般非常少有多台机器做支撑. 本文就将叙述怎样在一台电脑上实现redis的主从备份. 同一台机器上部署多个red ...
- Duanxx的C++学习 : 数字转换String
下面是这两个数字转换String道路.件:sstream string num2str1(unsigned int num) { stringstream ss; ss<<num; ret ...