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事件再读写
  
 

None.gif UCOMIStream stream  =   null ;
None.gif  
None.gif CreateStreamOnHGlobal(Marshal.StringToHGlobalUni(value), 
true out  stream);
None.gif   
None.gif
None.gif
None.gif
None.gif 
if (stream  !=   null )
None.gif  
ExpandedBlockStart.gifContractedBlock.gif 
dot.gif {
InBlock.gif   IPersistStreamInit persistentStreamInit 
=
InBlock.gif     (IPersistStreamInit)WebBrowser.Document;
InBlock.gif  
InBlock.gif   persistentStreamInit.InitNew();
InBlock.gif   persistentStreamInit.Load(stream);
InBlock.gif   persistentStreamInit 
= null;
ExpandedBlockEnd.gif }

None.gif


  
 UCOMIStream是COM中IStream的CLR版本
 CreateStreamOnHGlobal函数从一个字符串的地址
 创建一个IStream供使用
  

None.gif  [DllImport( " ole32.dll " , PreserveSig = false )]
None.gif 
static   extern   void  CreateStreamOnHGlobal(IntPtr hGlobal,
None.gif   Boolean fDeleteOnRelease, [Out] 
out  UCOMIStream pStream);


  
 然后就是通过IPersistStreamInit接口初始化并载入HTML源码,
 IPersistStreamInit接口CLR缺省没有导入,定义如下
  

None.gif  [ComVisible( true ), ComImport(), Guid( " 7FD52380-4E07-101B-AE2D-08002B2EC713 " ),
None.gif  InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
None.gif 
public   interface  IPersistStreamInit
ExpandedBlockStart.gifContractedBlock.gif 
dot.gif {
InBlock.gif   
void GetClassID([In, Out] ref Guid pClassID);
InBlock.gif  
InBlock.gif   [
return: MarshalAs(UnmanagedType.I4)] [PreserveSig]
InBlock.gif   
int IsDirty();
InBlock.gif  
InBlock.gif   
void Load([In, MarshalAs(UnmanagedType.Interface)] UCOMIStream pstm);
InBlock.gif   
void Save([In, MarshalAs(UnmanagedType.Interface)] UCOMIStream pstm,
InBlock.gif             [In, MarshalAs(UnmanagedType.I4)] 
int fClearDirty);
InBlock.gif   
void GetSizeMax([Out, MarshalAs(UnmanagedType.LPArray)] long pcbSize);
InBlock.gif   
void InitNew();
ExpandedBlockEnd.gif }


  
 读取HTML也是类似思路,将HTML源码写到一个IStream中
 然后转换成字符串供C#代码使用,不过实现方式比较麻烦
  
 比较简单的方法还是使用ole32.dll提供的函数
 重建流,但这需要预先设定流的长度,如
  

None.gif UCOMIStream stream  =   null ;
None.gif  
None.gif CreateStreamOnHGlobal(Marshal.AllocHGlobal(
4096 ),  true out  stream);
None.gif  
None.gif IPersistStreamInit persistentStreamInit 
=
None.gif   (IPersistStreamInit)WebBrowser.Document;
None.gif  
None.gif persistentStreamInit.Save(stream, 
0 );
None.gif persistentStreamInit 
=   null ;
None.gif  
None.gif IntPtr pStr;
None.gif  
None.gif GetHGlobalFromStream(stream, 
out  pStr);
None.gif  
None.gif 
return  Marshal.PtrToStringAnsi(pStr);


  
 然后使用GetHGlobalFromStream函数和
 Marshal.PtrToStringAnsi将流转换为字符串
 另外一种方法是自行实现一个支持IStream接口的类
 通过流的方式灵活完成读取操作,我比较喜欢这种 

None.gif   using (MemoryStream stream  =   new  MemoryStream())
None.gif
None.gif
ExpandedBlockStart.gifContractedBlock.gif 
dot.gif {
InBlock.gif   ComStreamAdapter adapter 
= new ComStreamAdapter(stream);
InBlock.gif  
InBlock.gif   IPersistStreamInit persistentStreamInit 
=
InBlock.gif     (IPersistStreamInit)WebBrowser.Document;
InBlock.gif  
InBlock.gif   persistentStreamInit.Save(adapter, 
0);
InBlock.gif  
InBlock.gif   stream.Seek(
0, SeekOrigin.Begin);
InBlock.gif  
InBlock.gif   
using(StreamReader reader = new StreamReader(stream))
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif     
return reader.ReadToEnd();
ExpandedSubBlockEnd.gif   }

ExpandedBlockEnd.gif }

None.gif


  
 这里的ComStreamAdapter是一个使用了adapter模式的类
 将普通的System.IO.Stream转换为IStream支持的类
  
   

None.gif    public   class  ComStreamAdapter : UCOMIStream
ExpandedBlockStart.gifContractedBlock.gif     
dot.gif {
InBlock.gif       
private Stream _stream;
InBlock.gif
InBlock.gif
InBlock.gif  
InBlock.gif       
public ComStreamAdapter(Stream stream)
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif         _stream 
= stream;
ExpandedSubBlockEnd.gif       }

InBlock.gif  
ContractedSubBlock.gifExpandedSubBlockStart.gif       
UCOMIStream Members#region UCOMIStream Members
InBlock.gif  
InBlock.gif       
public void Commit(int grfCommitFlags)
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
ExpandedSubBlockEnd.gif       }

InBlock.gif  
InBlock.gif       
public void Clone(out UCOMIStream ppstm)
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif         ppstm 
= null;
ExpandedSubBlockEnd.gif       }

InBlock.gif  
InBlock.gif       
public void CopyTo(UCOMIStream pstm, long cb, System.IntPtr pcbRead, Syste
InBlock.gif m.IntPtr pcbWritten)
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
ExpandedSubBlockEnd.gif       }

InBlock.gif  
InBlock.gif
InBlock.gif
InBlock.gif       
public void Revert()
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
ExpandedSubBlockEnd.gif       }

InBlock.gif  
InBlock.gif       
public void LockRegion(long libOffset, long cb, int dwLockType)
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
ExpandedSubBlockEnd.gif       }

InBlock.gif  
InBlock.gif       
public void UnlockRegion(long libOffset, long cb, int dwLockType)
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
ExpandedSubBlockEnd.gif       }

InBlock.gif  
InBlock.gif       
public void Seek(long dlibMove, int dwOrigin, System.IntPtr plibNewPositio
InBlock.gif n)
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif         _stream.Seek(dlibMove, (SeekOrigin)dwOrigin);
InBlock.gif  
InBlock.gif         
if(plibNewPosition != IntPtr.Zero)
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif           Marshal.WriteInt32(plibNewPosition, (
int)_stream.Position);
ExpandedSubBlockEnd.gif         }

ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif
InBlock.gif  
InBlock.gif       
public void Read(byte[] pv, int cb, System.IntPtr pcbRead)
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif         
int size = _stream.Read(pv, (int)_stream.Position, cb);
InBlock.gif  
InBlock.gif         
if(pcbRead != IntPtr.Zero)
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif           Marshal.WriteInt32(pcbRead, size);
ExpandedSubBlockEnd.gif         }

ExpandedSubBlockEnd.gif       }

InBlock.gif  
InBlock.gif       
public void Write(byte[] pv, int cb, System.IntPtr pcbWritten)
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif         _stream.Write(pv, 
0, cb);
InBlock.gif  
InBlock.gif         
if(pcbWritten != IntPtr.Zero)
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif           Marshal.WriteInt32(pcbWritten, cb);
ExpandedSubBlockEnd.gif         }

ExpandedSubBlockEnd.gif       }

InBlock.gif  
InBlock.gif       
public void SetSize(long libNewSize)
InBlock.gif
InBlock.gif
InBlock.gif         _stream.SetLength(libNewSize);
ExpandedBlockEnd.gif       }

None.gif  
None.gif       
public   void  Stat( out  STATSTG pstatstg,  int  grfStatFlag)
ExpandedBlockStart.gifContractedBlock.gif       
dot.gif {
InBlock.gif         pstatstg 
= new STATSTG ();
ExpandedBlockEnd.gif       }

None.gif  
None.gif       
#endregion
None.gif     }
None.gif
None.gif
None.gif
None.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值