zoukankan      html  css  js  c++  java
  • C# 导出一个控件的矢量图

      调用Control.DrawToBitmap(Bitmap) 方法是很容易得到控件的图形的。 但是bitmap是栅格化图形。栅格化图形有很多缺点,比如文件体积比较大、 放大后失真、 不易编辑等等。 这里将给出导出一个控件的矢量图的过程。

    一、两个概念

    Windows MetaFile
      windows MetaFile 是windows 下面的一种矢量图形格式。 事实上WMF 只是记录下来的一串GDI 命令,重新调用一次这一串GDI命令就可以重建之前记录下来的图像。而大部分windows应用程序的界面都是用GDI绘制的,所以理论上都可以导出他们 界面的矢量图。 详细去看:http://en.wikipedia.org/wiki/Windows_Metafile

    绘图表面 ( drawing surfaces )
      用GDI+绘图的时候,基本上你会把图形绘制到 屏幕上的窗体、传到打印机的打印文档、内存里的图像文件等等。 这些叫做绘图表面。

    二、导出的基本过程

    2.1 首先创建一个新的EMF文件

    System.Drawing.Imaging.Metafile mf;
    Graphics g1 = control.CreateGraphics();
    IntPtr hdc = g1.GetHdc();
    mf = new Metafile(hdc, new Rectangle(0, 0, control.Width, control.Height), MetafileFrameUnit.Pixel, EmfType.EmfOnly);
    g1.ReleaseHdc(hdc);
    g1.Dispose();
    

     2.2 将控件上的内容打印到Graphics 对象上

    调用WinApi把控件打印到此Graphics 对象上面。这个Graphics对象会作为参数传递给下面一级一级的子控件的OnPaint()函数中。

    const int WM_PRINT = 0x0317;
    
    const int PRF_CHECKVISIBLE = 0x00000001,
    PRF_NONCLIENT = 0x00000002,
    PRF_CLIENT = 0x00000004,
    PRF_ERASEBKGND = 0x00000008,
    PRF_CHILDREN = 0x00000010;
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, int lParam);
    
    public static void DrawControl(Control control, Graphics g)
    {
        if (!control.Created)
             control.CreateControl();
    
        IntPtr hDc = g.GetHdc();
        SendMessage(new HandleRef(control, control.Handle), WM_PRINT, (int)hDc,(int)(PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT));
        g.ReleaseHdc(hDc);
    }
    

     2.3  将EMF复制到剪切板上

     到这里已经得到了这个控件的矢量图了。下面附加一段代码把这个EMF复制到剪切板上面去.

            [DllImport("user32.dll")]
            static extern bool OpenClipboard(IntPtr hWndNewOwner);
            [DllImport("user32.dll")]
            static extern bool EmptyClipboard();
            [DllImport("user32.dll")]
            static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);
            [DllImport("user32.dll")]
            static extern bool CloseClipboard();
            [DllImport("gdi32.dll")]
            static extern IntPtr CopyEnhMetaFile(IntPtr hemfSrc, IntPtr hNULL);
            [DllImport("gdi32.dll")]
            static extern bool DeleteEnhMetaFile(IntPtr hemf);
    
            static public bool PutEnhMetafileOnClipboard(IntPtr hWnd, Metafile mf)
            {
                bool bResult = false;
                IntPtr hEMF, hEMF2;
                hEMF = mf.GetHenhmetafile(); // invalidates mf 
                if (!hEMF.Equals(new IntPtr(0)))
                {
                    hEMF2 = CopyEnhMetaFile(hEMF, new IntPtr(0));
                    if (!hEMF2.Equals(new IntPtr(0)))
                    {
                        if (OpenClipboard(hWnd))
                        {
                            if (EmptyClipboard())
                            {
                                IntPtr hRes = SetClipboardData(14 /*CF_ENHMETAFILE*/, hEMF2);
                                bResult = hRes.Equals(hEMF2);
                                CloseClipboard();
                            }
                        }
                    } DeleteEnhMetaFile(hEMF);
                } return bResult;
            }
    

    参考文章

    1. 如何导出WinForm 控件界面的矢量图

  • 相关阅读:
    APP性能测试-客户端性能测试
    postman——预处理和断言
    postman——token传参
    postman——环境变量
    postman——请求与相应
    postman——下载与安装
    HP LoadRunner 11.00安装+破解+汉化
    Fiddler使用 抓取手机数据包及中文乱码解决方案
    性能测试常见面试题(Loadrunner)
    python3 selenium3 POM设计模式 【比较全的使用邮件自动发送测试报告】
  • 原文地址:https://www.cnblogs.com/arxive/p/5845889.html
Copyright © 2011-2022 走看看