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

转帖|其它|编辑:郝浩|2009-02-26 10:43:12.000|阅读 956 次

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

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

调用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文件:


            System.Dra wing.Imaging.Metafile mf;
         &nb sp;  Graphics g1 
= control.CreateGraphics ();
            IntPtr  hdc 
= g1.GetHdc ();
            mf = new Metafile(hdc, new Rectangle(00, 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);
        }

 

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


        const int WM_PRINT = 0x0317;

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

 

 到这里已经得到了这个控件的矢量图了。下面附加一段代码把这个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);
      &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等 )。 可以无限放大不失真, 还能够编辑里面的文本哦!


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:博客园

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP