C# WinForm窗体四周阴影效果
生活随笔
收集整理的這篇文章主要介紹了
C# WinForm窗体四周阴影效果
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、起因
關于winform窗體無邊框的問題很簡單,只需要設置winform的窗體屬性即可:
FormBorderStyle = FormBorderStyle.None;但是這中無邊框窗口實現的效果和背景完全沒有層次的感覺,所以能加上陰影,突出窗口顯示的感覺。
二、網上搜索的解決方案
方法 1
首先,發現了使用 user32.dll 中方法實現的方案:
C# WinForm無邊框窗體設置陰影效果
缺點:這種方法只能實現右邊和下邊的陰影效果,效果不是很好。
效果如圖:
方法 2
然后發現了使用雙層窗體,底層窗體貼陰影的PNG來實現的方式:
教你實現Winform窗體的四邊陰影效果
缺點:PNG格式特點是,支持alpha通道半透明,但是放大會失真
效果如圖:
三、最終解決方案
我使用的方法是繪制陰影到bitmap上,然后使用雙層窗體的原理把bitmap繪制到背景層上去。
其中比較重要的是:
1、繪制圓角矩形
public static void DrawRoundRectangle(Graphics g, Pen pen, Rectangle rect, int cornerRadius) {using (GraphicsPath path = CreateRoundedRectanglePath(rect, cornerRadius)){g.DrawPath(pen, path);} } public static void FillRoundRectangle(Graphics g, Brush brush, Rectangle rect, int cornerRadius) {using (GraphicsPath path = CreateRoundedRectanglePath(rect, cornerRadius)){g.FillPath(brush, path);} } internal static GraphicsPath CreateRoundedRectanglePath(Rectangle rect, int cornerRadius) {GraphicsPath roundedRect = new GraphicsPath();roundedRect.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);roundedRect.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius * 2, rect.Y);roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);roundedRect.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height - cornerRadius * 2);roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);roundedRect.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.X + cornerRadius * 2, rect.Bottom);roundedRect.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);roundedRect.AddLine(rect.X, rect.Bottom - cornerRadius * 2, rect.X, rect.Y + cornerRadius * 2);roundedRect.CloseFigure();return roundedRect; }2、繪制陰影
internal void DrawShadow() {Bitmap bitmap = null;Graphics g = null;try{bitmap = new Bitmap(Width, Height);g = Graphics.FromImage(bitmap);g.SmoothingMode = SmoothingMode.AntiAlias;Color c = Color.FromArgb(0, 0, 0, 0);Pen p = new Pen(c, 3);for (int i = 0; i < Main.ShadowWidth; i++){p.Color = Color.FromArgb((255 / 10 / Main.ShadowWidth) * i, c);DrawRoundRectangle(g, p, new Rectangle(i, i, Width - (2 * i) - 1, Height - (2 * i) - 1), Main.ShadowWidth - i);}SetBits(bitmap);}catch { }finally{g?.Dispose();bitmap?.Dispose();} }3、繪制半透明bitmap到窗口上
protected override CreateParams CreateParams {get{CreateParams cParms = base.CreateParams;cParms.ExStyle |= 0x00080000; // WS_EX_LAYEREDreturn cParms;} } public void SetBits(Bitmap bitmap) {if (!Image.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Image.IsAlphaPixelFormat(bitmap.PixelFormat))throw new ApplicationException("圖片必須是32位帶Alhpa通道的圖片。");IntPtr oldBits = IntPtr.Zero;IntPtr screenDC = FormStyleAPI.GetDC(IntPtr.Zero);IntPtr hBitmap = IntPtr.Zero;IntPtr memDc = FormStyleAPI.CreateCompatibleDC(screenDC);try{FormStyleAPI.Point topLoc = new FormStyleAPI.Point(Left, Top);FormStyleAPI.Size bitMapSize = new FormStyleAPI.Size(Width, Height);FormStyleAPI.BLENDFUNCTION blendFunc = new FormStyleAPI.BLENDFUNCTION();FormStyleAPI.Point srcLoc = new FormStyleAPI.Point(0, 0);hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));oldBits = FormStyleAPI.SelectObject(memDc, hBitmap);blendFunc.BlendOp = FormStyleAPI.AC_SRC_OVER;blendFunc.SourceConstantAlpha = Byte.Parse(((int)(Main.Opacity * 255)).ToString());blendFunc.AlphaFormat = FormStyleAPI.AC_SRC_ALPHA;blendFunc.BlendFlags = 0;FormStyleAPI.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, FormStyleAPI.ULW_ALPHA);}finally{if (hBitmap != IntPtr.Zero){FormStyleAPI.SelectObject(memDc, oldBits);FormStyleAPI.DeleteObject(hBitmap);}FormStyleAPI.ReleaseDC(IntPtr.Zero, screenDC);FormStyleAPI.DeleteDC(memDc);} }四、最終方案的效果和源碼
源碼下載
總結
以上是生活随笔為你收集整理的C# WinForm窗体四周阴影效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常用Sql整理笔记
- 下一篇: ORA-01002 提取违反顺序