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文件

1
2
3
4
5
6
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()函数中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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复制到剪切板上面去.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[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 控件界面的矢量图

 

没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。






    本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/arxive/p/5845889.html,如需转载请自行联系原作者

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
21世纪什么最重要?通用!想让你的件和主流软件共享同一种编辑结果吗,那就选择我吧!国内唯一全面基于国际矢量形标准SVG的专业开发件,提供全面的矢量编辑能力,能适应组态软件和其他形软件开发需要。能够和其他主流的编辑软件如illustrator,Visio等共享最终编辑结果。使用VectorControl.Net,您可以:> 基本形状绘制,支持圆、椭圆、矩形、正方形、直线、多边形、折线的绘制> 像和文本构造,支持导入像和文本构造> 扩展形状绘制,支持星形形状和扇形的构造> 钢笔工具绘制,支持任意形状的曲线构造(贝赛尔曲线)> 二维变换,支持缩放、扭曲、平移和旋转等二维变换,并可以启用或禁用这些操作。> 形的成组和解组> 形的层次调整> 支持多个形之间的对齐> 支持多个形之间的分布功能> 调整多个形的尺寸以达到相同高度或宽度> 网格、参考线、标尺等完整视环境并支持吸附。> 支持外部自定义形状和元文件,给与用户自由扩展功能的能力,并能将当前绘内容导出为形状和元> 支持连接线,可以在对象之间保持联系> 无限制的撤销/重作> 支持SVG文件的导入> Bmp,Jpg,Gif,Tiff等多种栅格像格式的导出> SVG文件代码预览> VectorControl.Net还提供了许多Windows界面开发组件,包括弹出菜单时容器,形状和组件库选择器等> 打印支持> 两套完整的示例程序以及源代码(C#和VB.Net),全面全面展现了如何利用VectorControl.Net件实现简单的矢量应用(不需要任何手工编码实现SVG浏览器)和利用VectorControl实现一个完整的矢量编辑环境(具备所有矢量形编辑功能)的能力,您甚至可以直接将我们提供的示例程序用作您默认的矢量形的编辑器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值