天天看点

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,如需转载请自行联系原作者

继续阅读