中国IT实验室LOGO 首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式 | 存储世界服务器 | 华为 | 网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 北大青鸟 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 活动沙龙 | 论坛
中国IT实验室Dotnet频道
首页 ASP.NET  C#  XML/WebService ADO.NET VC.NET VB.NET .NET 资讯动态 专题 RSS订阅 讨论 下载
您现在的位置: 中国IT实验室 >> Dotnet >> ASP.NET >> 正文

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

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

  I.  Windows MetaFile.

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

  II. 绘图表面 ( drawing surfaces )

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

  首先我们来创建一个新的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();

  Graphics g2 = Graphics.FromImage(mf);

  调用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);

  }

  到这里已经得到了这个控件的矢量图了。下面附加一段代码把这个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;

  }

  运行这段代码以后, 就可以吧控件的矢量图粘贴到图像编辑软件上面了(CorelDraw, Word, Excel等)。 可以无限放大不失真, 还能够编辑里面的文本哦!

【责编:coco】

相关产品和培训
文章评论
 友情推荐链接
 认证培训
 专题推荐

 ·Java EE 6规范中文版
 ·Oracle 10g OCP考证秘笈
 ·算法分析与设计之五大常用算法
 ·开发必备 漫谈Java加密保护
 ·嵌入式开发--ARM技术专题
 ·C/C++指针,认真了解,灵活运用
 ·.NET开发:C#实用基础教程
 ·软件测试工具QTP学习专题
 ·嵌入式开发单片机解决方案专题
 ·Java开发环境 Greenfoot 程序员手册
 今日更新
 社区讨论
 博客论点
 频道精选
 Dotnet频道相关导航