程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 如何導出WinForm 控件界面的矢量圖

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

編輯:關於.NET

調用Control.DrawToBitmap(Bitmap) 方法是很容易得到控件的圖形的。 但是bitmap是柵格化圖形。 柵格化圖形有很多缺點,比如文件體積比較大、 放大後失真、 不易編輯等等。 這裡教你如何導出一個 控件的矢量圖。

I. Windows MetaFile.

windows MetaFile 是windows 下面的一種矢量圖形格式。 事實上WMF 只是記錄下來的一串GDI 命令 ,重新調用一次這一串GDI命令就可以重建之前記錄下來的圖像。而大部分windows應用程序的界面都是用 GDI繪制的,所以理論上都可以導出他們界面的矢量圖。 詳細去看: http://en.wikipedia.org/wiki/Windows_Metafile

II. 繪圖表面 ( drawing surfaces )

用GDI+繪圖的時候,基本上你會把圖形繪制到 屏幕上的窗體、傳到打印機的打印文檔、內存裡的圖像 文件等等。 這些叫做繪圖表面。

首先我們來創建一個新的EMF文件:

            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);

調用WinApi把控件打印到此Graphics 對象上面(這個Graphics對象會作為參數傳遞給下面一級一級的 子控件的OnPaint()函數):

        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);

        }

到這裡已經得到了這個控件的矢量圖了。下面附加一段代碼把這個EMF復制到剪切板上面去:

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved