zoukankan      html  css  js  c++  java
  • 通过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;
                }

    红色加粗位置.

  • 相关阅读:
    C#磁吸屏幕窗体类库
    准备
    我写的诗
    How to turn off a laptop keyboard
    How to tell which commit a tag points to in Git?
    Why should I care about lightweight vs. annotated tags?
    How to get rid of “would clobber existing tag”
    Facebook, Google and Twitter threaten to leave Hong Kong over privacy law changes
    The need for legislative reform on secrecy orders
    Can a foreign key be NULL and/or duplicate?
  • 原文地址:https://www.cnblogs.com/Chinasf/p/603294.html
Copyright © 2011-2022 走看看