通过IViewObject接口,取浏览器的图象,实现SNAP
今天又见到snap实现的文章,看来对此感兴趣的人挺多的.实现这个功能确实很'眩',我也来做一个把玩一下.
我的做法不是 Control.DrawToBitmap ,而是直接QueryInterface 浏览器Com对象的 IViewObject 接口,用它实现的Draw方法,画到图象上.
首先定义IViewObject的接口声名,如下:
IVewObject接口声明
该接口.net 自己带了,只是internal形式,所以只有想办法用Reflector 将它弄出来,相关的还有几个类,分别是tagLOGPALETTE,COMRECT,tagDVTARGETDEVICE.
定义如下:
相关定义
现在可以通过 Marshal.QueryInterface 将浏览器COM实例的IViewObject接口取出:
//获取接口
object hret = Marshal.QueryInterface(Marshal.GetIUnknownForObject(pUnknown),ref UnsafeNativeMethods.IID_IViewObject, out pViewObject);
pUnknown为 com对象实例.
将IViewObject 指针对象 pViewObject 转化为接口对象.
ViewObject = Marshal.GetTypedObjectForIUnknown(pViewObject, typeof(SnapLibrary.UnsafeNativeMethods.IViewObject)) as SnapLibrary.UnsafeNativeMethods.IViewObject;
调用draw方法,绘制到图象上,以下是TakeSnapshot方法的完整代码:
Snapshot类
到此既完成了对Com对象的图象抓取.那么现在给它提供一个浏览器的实例,让它实现对 web page 的快照吧.
.net 2.0提供了webbrowser对象,它是对activex对象的包装,它的使用很简单,这里就不详细说明.
WebBrowser 对象的实例的属性ActiveXInstance就是它的原生COM对象,获取它的IVewObject接口,即可调用它实现的Draw方法把网页绘制到指定的DC上.
以下是对webbrowser对象的包装类,结合Snapshot 类的类代码:
web 页面快照类
这里提供一个测试用的代码:
class Program
{
/// <summary>
/// 测试
/// </summary>
/// <param name="args"></param>
[STAThread]
static void Main(string[] args)
{
//web 页面快照
WebPageSnapshot wps = new WebPageSnapshot();
![]()
if (args != null && args.Length > 1)
wps.Url = args[0];
else
wps.Url = "http://www.cnblogs.com";
![]()
try
{
//保存到文件
wps.TakeSnapshot().Save("1.bmp");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
wps.Dispose();
}
![]()
![]()
}
工程原始代码下载:
/Files/Chinasf/SnapLibrary.rar
当然,这样做可能太复杂了,因为.net 为我们简化了所有的工作,简单到任意的contrl对象都支持DrawToBitmap 方法.不过想要了解机制的朋友们,可以研究一下.
2006年12月26日 8:55:14 修正:请到Snapshot类中增加一句释放引用接口的代码.
Snapshot..
try
{
//ViewObject = Marshal.GetObjectForIUnknown(pViewObject) as SnapLibrary.UnsafeNativeMethods.IViewObject;
ViewObject = Marshal.GetTypedObjectForIUnknown(pViewObject, typeof(SnapLibrary.UnsafeNativeMethods.IViewObject)) as SnapLibrary.UnsafeNativeMethods.IViewObject;
//调用Draw方法
ViewObject.Draw((int)DVASPECT.DVASPECT_CONTENT,
-1,
IntPtr.Zero,
null,
IntPtr.Zero,
hDrawDC.GetHdc(),
new NativeMethods.COMRECT(bmpRect),
null,
IntPtr.Zero,
0);
Marshal.Release(pViewObject);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw ex;
}
红色加粗位置.
我的做法不是 Control.DrawToBitmap ,而是直接QueryInterface 浏览器Com对象的 IViewObject 接口,用它实现的Draw方法,画到图象上.
首先定义IViewObject的接口声名,如下:
该接口.net 自己带了,只是internal形式,所以只有想办法用Reflector 将它弄出来,相关的还有几个类,分别是tagLOGPALETTE,COMRECT,tagDVTARGETDEVICE.
定义如下:
现在可以通过 Marshal.QueryInterface 将浏览器COM实例的IViewObject接口取出:
//获取接口
object hret = Marshal.QueryInterface(Marshal.GetIUnknownForObject(pUnknown),ref UnsafeNativeMethods.IID_IViewObject, out pViewObject);将IViewObject 指针对象 pViewObject 转化为接口对象.
ViewObject = Marshal.GetTypedObjectForIUnknown(pViewObject, typeof(SnapLibrary.UnsafeNativeMethods.IViewObject)) as SnapLibrary.UnsafeNativeMethods.IViewObject;调用draw方法,绘制到图象上,以下是TakeSnapshot方法的完整代码:
到此既完成了对Com对象的图象抓取.那么现在给它提供一个浏览器的实例,让它实现对 web page 的快照吧.
.net 2.0提供了webbrowser对象,它是对activex对象的包装,它的使用很简单,这里就不详细说明.
WebBrowser 对象的实例的属性ActiveXInstance就是它的原生COM对象,获取它的IVewObject接口,即可调用它实现的Draw方法把网页绘制到指定的DC上.
以下是对webbrowser对象的包装类,结合Snapshot 类的类代码:
这里提供一个测试用的代码:
class Program
{
/// <summary>
/// 测试
/// </summary>
/// <param name="args"></param>
[STAThread]
static void Main(string[] args)
{
//web 页面快照
WebPageSnapshot wps = new WebPageSnapshot();
if (args != null && args.Length > 1)
wps.Url = args[0];
else
wps.Url = "http://www.cnblogs.com";
try
{
//保存到文件
wps.TakeSnapshot().Save("1.bmp");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
wps.Dispose();
}

}工程原始代码下载:
/Files/Chinasf/SnapLibrary.rar
当然,这样做可能太复杂了,因为.net 为我们简化了所有的工作,简单到任意的contrl对象都支持DrawToBitmap 方法.不过想要了解机制的朋友们,可以研究一下.
2006年12月26日 8:55:14 修正:请到Snapshot类中增加一句释放引用接口的代码.
Snapshot..
try
{
//ViewObject = Marshal.GetObjectForIUnknown(pViewObject) as SnapLibrary.UnsafeNativeMethods.IViewObject;
ViewObject = Marshal.GetTypedObjectForIUnknown(pViewObject, typeof(SnapLibrary.UnsafeNativeMethods.IViewObject)) as SnapLibrary.UnsafeNativeMethods.IViewObject;
//调用Draw方法
ViewObject.Draw((int)DVASPECT.DVASPECT_CONTENT,
-1,
IntPtr.Zero,
null,
IntPtr.Zero,
hDrawDC.GetHdc(),
new NativeMethods.COMRECT(bmpRect),
null,
IntPtr.Zero,
0);
Marshal.Release(pViewObject);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw ex;
}红色加粗位置.



浙公网安备 33010602011771号