调用ControlDrawToBitmap(Bitmap) 方法是很容易得到控件的图形的 但是bitmap是栅格化图形栅格化图形有很多缺点比如文件体积比较大 放大后失真 不易编辑等等 这里教你如何导出一个控件的矢量图 I Windows MetaFile windows MetaFile 是windows 下面的一种矢量图形格式 事实上WMF 只是记录下来的一串GDI 命令重新调用一次这一串GDI命令就可以重建之前记录下来的图像而大部分windows应用程序的界面都是用GDI绘制的所以理论上都可以导出他们界面的矢量图 详细去看Windows_Metafile>_Metafile II 绘图表面 ( drawing surfaces ) 用GDI+绘图的时候基本上你会把图形绘制到 屏幕上的窗体传到打印机的打印文档内存里的图像文件等等 这些叫做绘图表面 首先我们来创建一个新的EMF文件 SystemDrawingImagingMetafile mf; Graphics g = controlCreateGraphics(); IntPtr hdc = gGetHdc(); mf = new Metafile(hdc new Rectangle( controlWidth controlHeight) MetafileFrameUnitPixel EmfTypeEmfOnly); gReleaseHdc(hdc); gDispose(); Graphics g = GraphicsFromImage(mf); 调用WinApi把控件打印到此Graphics 对象上面(这个Graphics对象会作为参数传递给下面一级一级的子控件的OnPaint()函数): const int WM_PRINT = x; const int PRF_CHECKVISIBLE = x PRF_NONCLIENT = x PRF_CLIENT = x PRF_ERASEBKGND = x PRF_CHILDREN = x; [DllImport(userdll CharSet = CharSetAuto)] private static extern IntPtr SendMessage(HandleRef hWnd int msg int wParam int lParam); public static void DrawControl(Control control Graphics g) { if (!controlCreated) controlCreateControl(); IntPtr hDc = gGetHdc(); SendMessage(new HandleRef(control controlHandle) WM_PRINT (int)hDc (int)(PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT)); gReleaseHdc(hDc); } 到这里已经得到了这个控件的矢量图了下面附加一段代码把这个EMF复制到剪切板上面去 [DllImport(userdll)] static extern bool OpenClipboard(IntPtr hWndNewOwner); [DllImport(userdll)] static extern bool EmptyClipboard(); [DllImport(userdll)] static extern IntPtr SetClipboardData(uint uFormat IntPtr hMem); [DllImport(userdll)] static extern bool CloseClipboard(); [DllImport(gdidll)] static extern IntPtr CopyEnhMetaFile(IntPtr hemfSrc IntPtr hNULL); [DllImport(gdidll)] static extern bool DeleteEnhMetaFile(IntPtr hemf); static public bool PutEnhMetafileOnClipboard(IntPtr hWnd Metafile mf) { bool bResult = false; IntPtr hEMF hEMF; hEMF = mfGetHenhmetafile(); // invalidates mf if (!hEMFEquals(new IntPtr())) { hEMF = CopyEnhMetaFile(hEMF new IntPtr()); if (!hEMFEquals(new IntPtr())) { if (OpenClipboard(hWnd)) { if (EmptyClipboard()) { IntPtr hRes = SetClipboardData( /*CF_ENHMETAFILE*/ hEMF); bResult = hResEquals(hEMF); CloseClipboard(); } } } DeleteEnhMetaFile(hEMF); } return bResult; } 运行这段代码以后 就可以吧控件的矢量图粘贴到图像编辑软件上面了(CorelDraw Word Excel等) 可以无限放大不失真 还能够编辑里面的文本哦! |