原文: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源代码读写的更多相关文章

  1. Winform中修改WebBrowser控件User-Agent的方法(已经测试成功)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

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

    原文:vs2005中的WebBrowser控件的简单应用 这个控件被封装了一下,和以前的调用方式稍有不同.事件还是那几个,变化不大.方法变了不少.从网上能查到的资料不多,贴出一些代码来作参考.看看这段 ...

  3. WPF中嵌入WinForm中的webbrowser控件

    原文:WPF中嵌入WinForm中的webbrowser控件 使用VS2008创建WPF应用程序,需使用webbrowser.从工具箱中添加WPF组件中的webbrowser发现其中有很多属性事件不能 ...

  4. 在VC中使用WebBrowser控件的两方法

    ClassWizard方式: 1.创建包装类:View->ClassWizard->Add Class->Form a Type Library->C:/winnt/syste ...

  5. C#中的WebBrowser控件的使用

    0.常用方法   Navigate(string urlString):浏览urlString表示的网址 Navigate(System.Uri url):浏览url表示的网址 Navigate(st ...

  6. 009. C#中的WebBrowser控件的属性、方法及操作演示代码(转)

    本文转自 http://www.open-open.com/code/view/1430559996802 0.常用方法 Navigate(string urlString):浏览urlString表 ...

  7. WPF中禁止WebBrowser控件打开新窗口

    一.针对纯WPF的WebBrowser控件: <summary> Suppress Script Errors In WPF WebBrowser </summary> pub ...

  8. C#中的WebBrowser控件加载ActiveX插件

    C#中WebBrowser控件,将项目输入更改为x86输出,在页面打开时即可自动加载ActiveX控件

  9. C#中利用WebBrowser控件,获得HTML源码

    最近获得网页的几个老程序都不能用了. 我原来用 如下代码获得网页html 源码: <pre name="code" class="csharp"> ...

随机推荐

  1. 【C语言探索之旅】 第三部分第一课:SDL开发游戏之安装SDL

    内容简介 1.课程大纲 2.第三部分第一课: SDL开发游戏之安装SDL 3.第三部分第二课预告: SDL开发游戏之创建窗口和画布 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会 ...

  2. 解决 U盘安装Windows Server 2012 R2 报错 Windows 无法打开所需的文件 Sources\install.wim

    报错原因: 使用UltraISO等软件刻录镜像时默认使用FAT32文件系统,该系统不支持大于4G的文件, 而Server 2012 R2的安装文件install.wim为5.12G,固安装失败. 解决 ...

  3. 高仿淘宝送货地址暴走漫画系列(附demo)

    演讲: 我是个程序员,一天我坐在路边一边喝水一边苦苦检查bug. 这时一个乞丐在我边上坐下了,開始要饭,我认为可怜.就给了他1块钱. 然后接着调试程序.他可能生意不好,就无聊的看看我在干什么.然后过了 ...

  4. UBuntu经常使用的操作(网络资源)

    http://docs.google.com/Doc? id=dqsbw4c_46d89djccr 版权声明:本文博主原创文章.博客,未经同意不得转载.

  5. 3D数学--学习笔记(五岁以下儿童):总结一些概念(避免遗忘!)

    下面是一些概念只是一个简单的解释,这里是它的一个简单的了解! 当人们谈论,我能理解有关. 1.正交投影: 投影.这意味着降维操作. 全部的点都被拉平至垂直的轴(2D)或平面(3D)上.这样的类型的投影 ...

  6. Java TCP/UDP网络通信编程

    本文转自:http://www.cnblogs.com/cdtarena/archive/2013/04/10/3012282.html 网络应用中基本上都是TCP(Transmission Cont ...

  7. table在 点击线条颜色

    效果图: <html> <head> <meta http-equiv="Content-Type" content="text/html; ...

  8. 深入了解C++中间mutablekeyword

         深入理解C++中的mutablekeyword kezunhai@gmail.com http://blog.csdn.net/kezunhai keywordmutable是C++中一个不 ...

  9. SQL Server 2008 R2 性能计数器详细列表(五)

    原文:SQL Server 2008 R2 性能计数器详细列表(五) SQL Server:SQL Statistics 对象: 监视编译和发送到 SQL Server 实例的请求类型 SQL Ser ...

  10. 一个好用的web甘特图

      前些天一直在弄web甘特图,发现网上很多web甘特图框架,但大部分是收费的.偶尔发现了向日葵甘特图 感觉不错,特此写下来一方面当做记录,另一方面也为寻找web甘特图的同学们少走一些弯路,双赢嘛~ ...