天天看點

C# 導出一個控件的矢量圖一、兩個概念二、導出的基本過程

  調用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,如需轉載請自行聯系原作者

繼續閱讀