轉(zhuǎn)帖|其它|編輯:郝浩|2010-08-18 11:46:56.000|閱讀 771 次
概述:調(diào)用Control.DrawToBitmap(Bitmap) 方法是很容易得到控件的圖形, 但是bitmap是柵格化圖形。柵格化圖形有很多缺點,比如文件體積比較大、 放大后失真、 不易編輯等等。 這里教你如何導出一個控件的矢量圖。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
調(diào)用Control.DrawToBitmap(Bitmap) 方法是很容易得到控件的圖形, 但是bitmap是柵格化圖形。柵格化圖形有很多缺點,比如文件體積比較大、 放大后失真、 不易編輯等等。 這里教你如何導出一個控件的矢量圖。
I. Windows MetaFile.
windows MetaFile 是windows 下面的一種矢量圖形格式。 事實上WMF 只是記錄下來的一串GDI 命令,重新調(diào)用一次這一串GDI命令就可以重建之前記錄下來的圖像。而大部分windows應用程序的界面都是用GDI繪制的,所以理論上都可以導出他們界面的矢量圖。 詳細去看:Windows_Metafile">//en.wikipedia.org/wiki/Windows_Metafile
II. 繪圖表面 ( drawing surfaces )
用GDI+繪圖的時候,基本上你會把圖形繪制到 屏幕上的窗體、傳到打印機的打印文檔、內(nèi)存里的圖像文件等等。 這些叫做繪圖表面。
首先我們來創(chuàng)建一個新的EMF文件:
Code
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);
調(diào)用WinApi把控件打印到此Graphics 對象上面(這個Graphics對象會作為參數(shù)傳遞給
下面一級一級的子控件的OnPaint()函數(shù)):
Code
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);
}
到這里已經(jīng)得到了這個控件的矢量圖了。下面附加一段代碼把這個EMF復制到剪切板上面去:
Code
[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等)。 可以無限放大不失真, 還能夠編輯里面的文本哦!
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務必注明出處、不得修改原文相關鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:網(wǎng)絡轉(zhuǎn)載