• C# 自定义无边框窗体阴影效果


    工作中我们会经常遇到自定义一些窗口的样式,设置无边框然后自定义关闭、最大化等其他菜单,但是这样就失去了Winform自带的边框阴影效果,下面这个方法能让无边框增加阴影效果。代码如下:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WinfromTest.ShadowDialog
    {
        public partial class ShadowForm : Form
        {
            [DllImport("dwmapi.dll")]
            public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
    
            [DllImport("dwmapi.dll")]
            public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
    
            [DllImport("dwmapi.dll")]
            public static extern int DwmIsCompositionEnabled(ref int pfEnabled);
    
            private bool m_aeroEnabled;                     // variables for box shadow
            private const int CS_DROPSHADOW = 0x00020000;
            private const int WM_NCPAINT = 0x0085;
            private const int WM_ACTIVATEAPP = 0x001C;
    
            public struct MARGINS                           // struct for box shadow
            {
                public int leftWidth;
                public int rightWidth;
                public int topHeight;
                public int bottomHeight;
            }
    
            private const int WM_NCHITTEST = 0x84;          // variables for dragging the form
            private const int HTCLIENT = 0x1;
            private const int HTCAPTION = 0x2;
    
            protected override CreateParams CreateParams
            {
                get
                {
                    m_aeroEnabled = CheckAeroEnabled();
    
                    CreateParams cp = base.CreateParams;
                    if (!m_aeroEnabled)
                        cp.ClassStyle |= CS_DROPSHADOW;
    
                    return cp;
                }
            }
    
            private bool CheckAeroEnabled()
            {
                if (Environment.OSVersion.Version.Major >= 6)
                {
                    int enabled = 0;
                    DwmIsCompositionEnabled(ref enabled);
                    return enabled == 1 ? true : false;
                }
                return false;
            }
    
            protected override void WndProc(ref Message m)
            {
                switch (m.Msg)
                {
                    case WM_NCPAINT:                        // box shadow
                        if (m_aeroEnabled)
                        {
                            var v = 2;
                            DwmSetWindowAttribute(Handle, 2, ref v, 4);
                            MARGINS margins = new MARGINS()
                            {
                                bottomHeight = 1,
                                leftWidth = 0,
                                rightWidth = 0,
                                topHeight = 0
                            };
                            DwmExtendFrameIntoClientArea(Handle, ref margins);
    
                        }
                        break;
                    default:
                        break;
                }
                base.WndProc(ref m);
    
                if (m.Msg == WM_NCHITTEST && (int)m.Result == HTCLIENT)     // drag the form
                    m.Result = (IntPtr)HTCAPTION;
    
            }
    
            public ShadowForm()
            {
                m_aeroEnabled = false;
                FormBorderStyle = FormBorderStyle.None;
                InitializeComponent();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
    
            private void ShadowForm_Resize(object sender, EventArgs e)
            {
                pnlClient.Dock = DockStyle.Top;
                pnlClient.Height = this.Height - 1;
            }
        }
    }

     

    1.上面代码中MARGINS部分源码里设置的都是1,这样阴影效果中会有一条1像素的白边,如果都设置成0后阴影效果就没了,无奈只能bottomHeight=1,这样只有底部有个小白线。

    MARGINS margins = new MARGINS()
                            {
                                bottomHeight = 1,
                                leftWidth = 0,
                                rightWidth = 0,
                                topHeight = 0
                            };

    2.如果窗体上弄个pannel设置成Fill模式,阴影效果也会消失,费解。。。所以不能全部填充满,为此我想了个办法,设计界面还是弄一个pannel设置成FIll模式,这样不影响我们继续在页面布局,但是在ShadowForm_Resize中动态设置Dock为Top,高度为父容器Height -1就可以了。

    这样一个自带阴影效果的Form就做好了。

    private void ShadowForm_Resize(object sender, EventArgs e)
            {
                pnlClient.Dock = DockStyle.Top;
                pnlClient.Height = this.Height - 1;
            }

    效果如下:

  • 相关阅读:
    四大组件之BroadcastReceiver基础
    SQLiteOpenHelper与SQLiteDatabase的使用
    SharedPreferences实现保存用户名功能
    Fragment加载方式与数据通信
    ProgressBar、ProgessDialog用法解析
    GridView添加事件监听和常用属性解析
    ListView添加item的事件监听
    ArrayAdapter、SimpleAdapter简单用法
    MySQL入门笔记(二)
    MySQL入门笔记(一)
  • 原文地址:https://www.cnblogs.com/hejoy91/p/13611058.html
Copyright © 2020-2023  润新知