熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

如何導出WinForm 控件界面的矢量圖

2013-11-13 10:22:46  來源: .NET編程 

  調用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等) 可以無限放大不失真 還能夠編輯裡面的文本哦!


From:http://tw.wingwit.com/Article/program/net/201311/13427.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.