1. 程式人生 > >C#繪畫圓角矩形的兩種方式

C#繪畫圓角矩形的兩種方式

最近在用C#進行程式設計,重寫CheckBox,需要繪畫圓角矩形,在網上查找了許多資料,用C#FillPath的方式繪畫總感覺太麻煩,需要算座標,不如直接呼叫C++的方法繪畫圓角矩形。
宣告:本程式碼借鑑網上程式碼,在此僅做整理出來供大家參考使用
        [DllImport("user32.dll")]
        public static extern int SetWindowRgn(IntPtr hWnd,
            IntPtr hRgn, bool bRedraw);
        [DllImport("gdi32.dll")]
        public
static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int cx, int cy); [DllImport("gdi32.dll")] public static extern bool RoundRect(IntPtr hDC, int x1, int y1, int x2, int y2, int x3, int y3); [DllImport("user32")] public
static extern IntPtr GetDC(IntPtr hwnd); [DllImport("gdi32.dll")] public static extern IntPtr CreatePen( int fnPenStyle, // pen style int nWidth, // pen width int crColor // pen color ); [DllImport("gdi32.dll")] public
static extern IntPtr CreateSolidBrush(int crColor); [DllImport("gdi32.dll")] public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); [DllImport("gdi32.dll")] public static extern bool DeleteObject(IntPtr hObject); [DllImport("gdi32.dll")] public static extern IntPtr GetStockObject(int fnObject); [DllImport("gdi32.dll")] public static extern IntPtr CreateCompatibleDC(IntPtr hDC); [DllImport("gdi32.dll")] public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); [DllImport("gdi32.dll")] public static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, UInt32 dwRop); /// <summary> /// 繪畫矩形(利用C++API繪畫圓角矩形) /// </summary> public static bool DrawRoundRectC(Graphics e, Pen pen, SolidBrush Br, int X1, int Y1, int X2, int Y2, int X3, int Y3) { IntPtr hPen, oldpen; IntPtr hBr, oldBr; IntPtr hMemDc; IntPtr hBitmap, hOldBitmap; hPen = CreatePen((int)pen.DashStyle, (int)pen.Width, ColorTranslator.ToWin32(pen.Color) ); //hPen = GetStockObject(8);//空畫筆 hBr = CreateSolidBrush(ColorTranslator.ToWin32(Br.Color)); //hbrush = GetStockObject(5);//空畫刷 IntPtr hDC = e.GetHdc(); //建立相容DC /////////////////////////////////////////////////////////////// int iWidth = X2 - X1; int iHeight = Y2 - Y1; hMemDc = CreateCompatibleDC(hDC); hBitmap = CreateCompatibleBitmap(hDC, iWidth, iHeight); hOldBitmap = SelectObject(hMemDc, hBitmap); BitBlt(hMemDc, 0, 0, iWidth, iHeight, hDC, 0, 0, (UInt32)0xcc0020); ///////////////////////////////////////////////////////////// //選入畫刷和畫筆 oldBr = SelectObject(hMemDc, hBr); oldpen = SelectObject(hMemDc, hPen); bool bRet = RoundRect(hMemDc, X1, Y1, X2, Y2, X3, Y3); BitBlt(hDC, 0, 0, iWidth, iHeight, hMemDc, 0, 0, (UInt32)0xcc0020); //資源釋放 SelectObject(hMemDc, oldpen); SelectObject(hMemDc, oldBr); SelectObject(hMemDc, hOldBitmap); DeleteObject(hBitmap); DeleteObject(hMemDc); DeleteObject(hBr); DeleteObject(hPen); e.ReleaseHdc(hDC); return bRet; }

還有一種方法是網上利用C#的另一種方法

        /// <summary>
        /// 填充圓角矩形
        /// </summary>
        private void FillRound(Rectangle rectangle,
            Graphics g, Brush br, int _radius)
        {
            g.FillPath(br, DrawRoundRect(rectangle.X,
                rectangle.Y, rectangle.Width - 2,
                rectangle.Height - 1, _radius));
        }
        /// <summary>
        /// 生成圓角矩形路徑
        /// </summary>
        public static GraphicsPath DrawRoundRect(int x, int y, int width, int height, int radius)
        {
            GraphicsPath gp = new GraphicsPath();
            gp.AddArc(x, y, radius, radius, 180, 90);
            gp.AddArc(width - radius, y, radius, radius, 270, 90);
            gp.AddArc(width - radius, height - radius, radius, radius, 0, 90);
            gp.AddArc(x, height - radius, radius, radius, 90, 90);
            gp.CloseAllFigures();
            return gp;
        }

在編寫過程中,若擔心pen,brush資源釋放問題,可以使用

using(Pen p = new Pen(Color.Red))
{
}

這種方式資源會自動釋放。

本人編寫了重繪了CheckBox,使其為一種可滑動的安妞形狀,類似手機的滑動按鈕方式