作者: 乔克斯
查看: 120480|回复: 271
打印 上一主题 下一主题

【四边阴影】教你实现Winform窗体的四边阴影效果

  [复制链接]
跳转到指定楼层
楼主
查看: 120480|回复: 271
说明:
1.首先我们得有这样一张阴影图片。


2.然后分别有两个窗体去实现这个阴影效果。

  • SkinForm - 用于实现阴影的绘制,特性:鼠标可穿透,无法点击,跟随窗体。
  • SkinMain - 主窗体,也是承载控件的容器窗体, 特性:与普通窗体无一区别,移动和拉伸,阴影窗体都会跟随。

3.SkinMain主窗体的OnVisibleChanged事件中new出阴影窗体

  • //绘制层
  • private SkinForm skin;
  • skin = new SkinForm(this);
  • skin.Show(this);
4.阴影窗体中绘制不规则透明图片的代码:
[C#] 纯文本查看 复制代码
public void SetBits() {
    //绘制绘图层背景
    Bitmap bitmap = new Bitmap(Main.Width + 10, Main.Height + 10);
    Rectangle _BacklightLTRB = new Rectangle(20, 20, 20, 20);//窗体光泽重绘边界
    Graphics g = Graphics.FromImage(bitmap);
    g.SmoothingMode = SmoothingMode.HighQuality; //高质量
    g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量
    ImageDrawRect.DrawRect(g, Properties.Resources.main_light_bkg_top123, ClientRectangle, Rectangle.FromLTRB(_BacklightLTRB.X, _BacklightLTRB.Y, _BacklightLTRB.Width, _BacklightLTRB.Height), 1, 1);
 
    if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat))
        throw new ApplicationException("图片必须是32位带Alhpa通道的图片。");
    IntPtr oldBits = IntPtr.Zero;
    IntPtr screenDC = Win32.GetDC(IntPtr.Zero);
    IntPtr hBitmap = IntPtr.Zero;
    IntPtr memDc = Win32.CreateCompatibleDC(screenDC);
 
    try {
        Win32.Point topLoc = new Win32.Point(Left, Top);
        Win32.Size bitMapSize = new Win32.Size(Width, Height);
        Win32.BLENDFUNCTION blendFunc = new Win32.BLENDFUNCTION();
        Win32.Point srcLoc = new Win32.Point(0, 0);
 
        hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));
        oldBits = Win32.SelectObject(memDc, hBitmap);
 
        blendFunc.BlendOp = Win32.AC_SRC_OVER;
        blendFunc.SourceConstantAlpha = Byte.Parse("255");
        blendFunc.AlphaFormat = Win32.AC_SRC_ALPHA;
        blendFunc.BlendFlags = 0;
 
        Win32.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, Win32.ULW_ALPHA);
    } finally {
        if (hBitmap != IntPtr.Zero) {
            Win32.SelectObject(memDc, oldBits);
            Win32.DeleteObject(hBitmap);
        }
        Win32.ReleaseDC(IntPtr.Zero, screenDC);
        Win32.DeleteDC(memDc);
    }
}


效果图:


案例源码下载:

评分

参与人数 7威望 +1 金钱 +12 贡献 +1 收起 理由
AZAZA + 1
落叶的忧伤 + 1 赞一个!
Xiao_M + 1 感谢LZ对论坛做出的贡献~
liqinglin + 1 感谢分享,LZ辛苦了~
上下求索 + 1 感谢分享,LZ辛苦了~
cskin + 2 感谢分享,LZ辛苦了~
xiaobo + 1 + 5 + 1 感谢LZ对论坛做出的贡献~

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏10 转播转播
回复 论坛版权

使用道具 举报

沙发
 楼主| 乔克斯 发表于 2014-9-20 13:38:15 | 显示全部楼层
Shaozhuyong 发表于 2014-9-20 08:54
哪呢?说好的资源呢?

回复后,重新再看隐藏区域。
板凳
 楼主| 乔克斯 发表于 2014-11-19 21:36:46 | 显示全部楼层
mrtong 发表于 2014-11-19 18:17
能否禁止调整大小?

可以,吧拉伸代码去掉就行了。
地板
 楼主| 乔克斯 发表于 2014-11-20 11:11:19 | 显示全部楼层
mrtong 发表于 2014-11-20 09:08
看代码里面已经设置了FormBorderStyle = FormBorderStyle.None;啊?

我写了代码重新实现了拖动和拉伸,把那串代码干掉就行。
5#
 楼主| 乔克斯 发表于 2015-1-7 14:48:27 | 显示全部楼层
jaqleung 发表于 2015-1-7 10:40
这个方法试试,不知windows是不是有底层的方法来实现

底层有实现,左下,和右边的阴影。但是没有四边阴影的。。除非你在win7系统调用 玻璃模糊 api可以实现四边。但是其他系统没效果。
6#
 楼主| 乔克斯 发表于 2015-2-6 23:21:12 | 显示全部楼层
pingyuanyk 发表于 2015-2-6 14:21
这个图片去哪里下载,可不可以把SkinForm做成父窗体或这把SkinMain做成父窗体

案例源码里面有这个图片。做成父窗体- -。。可以啊。直接设置mdi就是了。
7#
 楼主| 乔克斯 发表于 2015-4-5 02:17:20 | 显示全部楼层
whyyanjj 发表于 2015-4-3 20:43
楼主太牛了  想看到源码

下载,就有源码了。
8#
 楼主| 乔克斯 发表于 2015-5-10 13:32:45 | 显示全部楼层
poetice 发表于 2015-5-10 06:22
用两个窗体来实现吗?是不是太浪费系统资源了?

还好吧。不会占用多少。VS都是这样实现的阴影。
9#
 楼主| 乔克斯 发表于 2015-5-22 15:04:27 | 显示全部楼层
Tom 发表于 2015-5-22 13:42
弄一个可以改阴影大小和颜色的教程吧乔

cskin里面的就有。=-=就是把固定图片阴影换成自己用GDI+画阴影。就能控制大小和颜色了。
10#
 楼主| 乔克斯 发表于 2015-10-30 14:26:05 | 显示全部楼层
O.O 发表于 2015-10-30 11:30
灰常强大,但是还有个问题问一下,在这个主窗体show一个子窗体后,显示隐藏这个主窗体就会在右边和下边出 ...

用CSkin。
您需要登录后才可以回帖 登录 | 加入CSkin博客

本版积分规则

QQ|申请友链|小黑屋|手机版|Archiver|CSkin ( 粤ICP备13070794号

Powered by Discuz! X3.2  © 2001-2013 Comsenz Inc.  Designed by ARTERY.cn
GMT+8, 2024-5-2 14:47, Processed in 0.603143 second(s), 33 queries , Gzip On.

快速回复 返回顶部 返回列表