创意网站推荐,企业培训师资格证报考2022,常用网站搜索引擎,企业天眼查询信息官网一、起因
关于winform窗体无边框的问题很简单#xff0c;只需要设置winform的窗体属性即可#xff1a;
FormBorderStyle FormBorderStyle.None;
但是这中无边框窗口实现的效果和背景完全没有层次的感觉#xff0c;所以能加上阴影#xff0c;突出窗口显示的感觉。
二、…一、起因
关于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);}
}
四、最终方案的效果和源码
源码下载