教你如何导出WinForm控件界面的矢量图

作者:控件中国网   出处:控件中国网   2014-09-17 15:17:22   阅读:3

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

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

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

首先我们来创建一个新的EMF文件: 

Code 
            System.Dra wing.Imaging.Metafile mf; 
         &nb sp;  Graphics g1 = control.CreateGraphics (); 
            IntPtr  hdc = g1.GetHdc (); 
            mf = new Metafile(hdc, new Rectangle(0, 0, control.Width, control.Height), MetafileFrameUnit.Pixel, Emf Type.EmfOnly);
            g 1.ReleaseHdc (hdc); 
            g1.Dispos e(); 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)  
              &nb sp; control.CreateControl (); 

            IntPtr&n bsp;hDc = g.GetHdc (); 
            SendMessage (new HandleRef(control, control.Handle), WM_PRINT,  (int) hDc, 
               ;  (int)(PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT)); 
         &n bsp;  g.ReleaseHdc(hDc); 
        }  
  


Graphics g2 = Graphics.FromImage(mf); 

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

Code 
        const int WM_PRINT = 0x0317; 

        const int PRF_CHECKVISIBLE = 0x00000001, 
        PRF_NONCLIENT = 0x00000002, 
        PRF_CLIENT = 0x00000004, 
        PRF_ERASEBKGND = 
  

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

Code 
        [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); 
      &nbs p; [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; 
            IntPt r 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&nb sp;hRes = SetClipboardData(14 /*CF_ENHMETAFILE*/, hEMF2); 
                     bResult = hRes.Equals (hEMF2); 
                     Cl oseClipboard (); 
                         }  
                 }  
               } DeleteEnhMetaFile (hEMF); 
            }  return bResult; 
        }  
运行这段代码以后, 就可以吧控件的矢量图粘贴到图像编辑软件上面了(CorelDraw, Word, Excel等 )。 可以无限放大不失真, 还能够编辑里面的文本哦! 

Copyright© 2006-2015 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 渝ICP备12000264号 法律顾问:元炳律师事务所
客服软件
live chat