調用Control.DrawToBitmap(Bitmap) 方法是很容易得到控件的圖形的。 但是bitmap是栅格化圖形。栅格化圖形有很多缺點,比如檔案體積比較大、 放大後失真、 不易編輯等等。 這裡将給出導出一個控件的矢量圖的過程。
Windows MetaFile
繪圖表面 ( drawing surfaces )
用GDI+繪圖的時候,基本上你會把圖形繪制到 螢幕上的窗體、傳到列印機的列印文檔、記憶體裡的圖像檔案等等。 這些叫做繪圖表面。
1
2
3
4
5
6
<code>System.Drawing.Imaging.Metafile mf;</code>
<code>Graphics g1 = control.CreateGraphics();</code>
<code>IntPtr hdc = g1.GetHdc();</code>
<code>mf = </code><code>new</code> <code>Metafile(hdc, </code><code>new</code> <code>Rectangle(0, 0, control.Width, control.Height), MetafileFrameUnit.Pixel, EmfType.EmfOnly);</code>
<code>g1.ReleaseHdc(hdc);</code>
<code>g1.Dispose();</code>
調用WinApi把控件列印到此Graphics 對象上面。這個Graphics對象會作為參數傳遞給下面一級一級的子控件的OnPaint()函數中。
7
8
9
10
11
12
13
14
15
16
17
18
19
<code>const</code> <code>int</code> <code>WM_PRINT = 0x0317;</code>
<code>const</code> <code>int</code> <code>PRF_CHECKVISIBLE = 0x00000001,</code>
<code>PRF_NONCLIENT = 0x00000002,</code>
<code>PRF_CLIENT = 0x00000004,</code>
<code>PRF_ERASEBKGND = 0x00000008,</code>
<code>PRF_CHILDREN = 0x00000010;</code>
<code>[DllImport(</code><code>"user32.dll"</code><code>, CharSet = CharSet.Auto)]</code>
<code>private</code> <code>static</code> <code>extern</code> <code>IntPtr SendMessage(HandleRef hWnd, </code><code>int</code> <code>msg, </code><code>int</code> <code>wParam, </code><code>int</code> <code>lParam);</code>
<code>public</code> <code>static</code> <code>void</code> <code>DrawControl(Control control, Graphics g)</code>
<code>{</code>
<code> </code><code>if</code> <code>(!control.Created)</code>
<code> </code><code>control.CreateControl();</code>
<code> </code><code>IntPtr hDc = g.GetHdc();</code>
<code> </code><code>SendMessage(</code><code>new</code> <code>HandleRef(control, control.Handle), WM_PRINT, (</code><code>int</code><code>)hDc,(</code><code>int</code><code>)(PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT));</code>
<code> </code><code>g.ReleaseHdc(hDc);</code>
<code>}</code>
到這裡已經得到了這個控件的矢量圖了。下面附加一段代碼把這個EMF複制到剪切闆上面去.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<code>[DllImport(</code><code>"user32.dll"</code><code>)]</code>
<code>static</code> <code>extern</code> <code>bool</code> <code>OpenClipboard(IntPtr hWndNewOwner);</code>
<code>static</code> <code>extern</code> <code>bool</code> <code>EmptyClipboard();</code>
<code>static</code> <code>extern</code> <code>IntPtr SetClipboardData(</code><code>uint</code> <code>uFormat, IntPtr hMem);</code>
<code>static</code> <code>extern</code> <code>bool</code> <code>CloseClipboard();</code>
<code>[DllImport(</code><code>"gdi32.dll"</code><code>)]</code>
<code>static</code> <code>extern</code> <code>IntPtr CopyEnhMetaFile(IntPtr hemfSrc, IntPtr hNULL);</code>
<code>static</code> <code>extern</code> <code>bool</code> <code>DeleteEnhMetaFile(IntPtr hemf);</code>
<code>static</code> <code>public</code> <code>bool</code> <code>PutEnhMetafileOnClipboard(IntPtr hWnd, Metafile mf)</code>
<code> </code><code>bool</code> <code>bResult = </code><code>false</code><code>;</code>
<code> </code><code>IntPtr hEMF, hEMF2;</code>
<code> </code><code>hEMF = mf.GetHenhmetafile(); </code><code>// invalidates mf</code>
<code> </code><code>if</code> <code>(!hEMF.Equals(</code><code>new</code> <code>IntPtr(0)))</code>
<code> </code><code>{</code>
<code> </code><code>hEMF2 = CopyEnhMetaFile(hEMF, </code><code>new</code> <code>IntPtr(0));</code>
<code> </code><code>if</code> <code>(!hEMF2.Equals(</code><code>new</code> <code>IntPtr(0)))</code>
<code> </code><code>{</code>
<code> </code><code>if</code> <code>(OpenClipboard(hWnd))</code>
<code> </code><code>{</code>
<code> </code><code>if</code> <code>(EmptyClipboard())</code>
<code> </code><code>{</code>
<code> </code><code>IntPtr hRes = SetClipboardData(14 </code><code>/*CF_ENHMETAFILE*/</code><code>, hEMF2);</code>
<code> </code><code>bResult = hRes.Equals(hEMF2);</code>
<code> </code><code>CloseClipboard();</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code> </code><code>} DeleteEnhMetaFile(hEMF);</code>
<code> </code><code>} </code><code>return</code> <code>bResult;</code>
參考文章
沒有整理與歸納的知識,一文不值!高度概括與梳理的知識,才是自己真正的知識與技能。 永遠不要讓自己的自由、好奇、充滿創造力的想法被現實的架構所束縛,讓創造力自由成長吧! 多花時間,關心他(她)人,正如别人所關心你的。理想的騰飛與實作,沒有别人的支援與幫助,是萬萬不能的。
本文轉自wenglabs部落格園部落格,原文連結:http://www.cnblogs.com/arxive/p/5845889.html,如需轉載請自行聯系原作者