C# WinForm开发系列之自定义无边框窗体(最大化,最小化,关闭,拉伸和移动的相关知识)

本片博客主要讲的事最近总结的一些关于窗体的自定义:
1.首先创建一个BaseForm窗体,通过设置属性FormBorderStyle=None为无边框窗体,代码如下:
 public partial class BaseForm : Form
 {
        // 图片名称
        public const String IMG_MIN = "btn_min";
        public const String IMG_MAX = "btn_max";
        public const String IMG_RESTORE = "btn_restore";
        public const String IMG_CLOSE = "btn_close";
        public const String IMG_BG = "img_bg";
        // 图片缓存
        private Bitmap closeBmp = null;
        private Bitmap minBmp = null;
        private Bitmap maxBmp = null;
        private Bitmap restoreBmp = null;
        public BaseForm()
        {
            InitializeComponent();
            initForm();
        }
        // 初始化界面的方法
        private void initForm()
        {
            // 获取最大化、最小化、关闭的背景图片
            this.minBmp = ResUtils.GetResAsImage(IMG_MIN);
            this.maxBmp = ResUtils.GetResAsImage(IMG_MAX);
            this.closeBmp = ResUtils.GetResAsImage(IMG_CLOSE);
            this.restoreBmp = ResUtils.GetResAsImage(IMG_RESTORE);
            // 设置Tip提示信息
            this.TipMain.SetToolTip(this.BtnClose, "关闭");
            this.TipMain.SetToolTip(this.BtnMin, "最小化");
            this.TipMain.SetToolTip(this.BtnMax, "最大化");
            if (this.WindowState == FormWindowState.Maximized)
            {
                this.TipMain.SetToolTip(this.BtnMax, "还原");
                this.BtnMax.BackgroundImage = this.restoreBmp;
                this.BtnMax.Invalidate();
            }
        }
        // 重写窗体消息轮询方法(不熟悉的可以搜索下win32api)
        //protected void WndProc2(ref Message m){//TODO下篇}
        // 鼠标单击(这里为节省代码篇幅将最小化、最大化、关闭的事件统一处理,也可以分单处理)
        private void BtnWnd_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (sender == this.BtnClose)
                {
                    this.Close();
                }
                else if (sender == this.BtnMax)
                {
                    if (this.WindowState == FormWindowState.Normal)
                    {
                        this.WindowState = FormWindowState.Maximized;
                        this.BtnMax.BackgroundImage = this.restoreBmp;
                        this.TipMain.SetToolTip(this.BtnMax, "还原");
                        this.BtnMax.Invalidate();
                    }
                    else
                    {
                        this.WindowState = FormWindowState.Normal;
                        this.BtnMax.BackgroundImage = this.maxBmp;
                        this.TipMain.SetToolTip(this.BtnMax, "最大化");
                    }
                }
                else if (sender == this.BtnMin)
                {
                    if (!this.ShowInTaskbar)
                    {
                        this.Hide();
                    }
                    else
                    {
                        this.WindowState = FormWindowState.Minimized;
                    }
                }
            }
        }
        // 鼠标进入
        private void BtnWnd_MouseEnter(object sender, EventArgs e)
        {
            Bitmap backImage = null;
            if (sender == this.BtnClose)
            {
                backImage = ResUtils.GetResWithState(IMG_CLOSE, ControlState.MouseOver);
            }
            else if (sender == this.BtnMin)
            {
                backImage = ResUtils.GetResWithState(IMG_MIN, ControlState.MouseOver);
            }
            else if (sender == this.BtnMax)
            {
                if (this.WindowState == FormWindowState.Normal)
                {
                    backImage = ResUtils.GetResWithState(IMG_MAX, ControlState.MouseOver);
                }
                else
                {
                    backImage = ResUtils.GetResWithState(IMG_RESTORE, ControlState.MouseOver);
                }
            }
            else
            {
                return;
            }
            Control control = (Control)sender;
            control.BackgroundImage = backImage;
            control.Invalidate();
        }
        // 鼠标移开
        private void BtnWnd_MouseLeave(object sender, EventArgs e)
        {
            Bitmap backImage = null;
            if (sender == this.BtnClose)
            {
                backImage = closeBmp;
            }
            else if (sender == this.BtnMin)
            {
                backImage = minBmp;
            }
            else if (sender == this.BtnMax)
            {
                if (this.WindowState == FormWindowState.Normal)
                {
                    backImage = maxBmp;
                }
                else
                {
                    backImage = restoreBmp;
                }
            }
            else
            {
                return;
            }
            Control control = (Control)sender;
            control.BackgroundImage = backImage;
            control.Invalidate();
        }
        // 鼠标按下
        private void BtnWnd_MouseDown(object sender, MouseEventArgs e)
        {
            Bitmap backImage = null;
            if (sender == this.BtnClose)
            {
                backImage = ResUtils.GetResWithState(IMG_CLOSE, ControlState.MouseDown);
            }
            else if (sender == this.BtnMin)
            {
                backImage = ResUtils.GetResWithState(IMG_MIN, ControlState.MouseDown);
            }
            else if (sender == this.BtnMax)
            {
                if (this.WindowState == FormWindowState.Normal)
                {
                    backImage = ResUtils.GetResWithState(IMG_MAX, ControlState.MouseDown);
                }
                else
                {
                    backImage = ResUtils.GetResWithState(IMG_RESTORE, ControlState.MouseDown);
                }
            }
            else
            {
                return;
            }
            Control control = (Control)sender;
            control.BackgroundImage = backImage;
            control.Invalidate();
        }
        // 鼠标弹起
        private void BtnWnd_MouseUp(object sender, MouseEventArgs e)
        {
            Bitmap backImage = null;
            if (sender == this.BtnClose)
            {
                backImage = closeBmp;
            }
            else if (sender == this.BtnMin)
            {
                backImage = minBmp;
            }
            else if (sender == this.BtnMax)
            {
                if (this.WindowState == FormWindowState.Normal)
                {
                    backImage = maxBmp;
                }
                else
                {
                    backImage = restoreBmp;
                }
            }
            else
            {
                return;
            }
            Control control = (Control)sender;
            control.BackgroundImage = backImage;
            control.Invalidate();
        }

}

窗体如下图1所示:
C# WinForm开发系列之自定义无边框窗体(最大化,最小化,关闭,拉伸和移动的相关知识)
                                                                                                                           图1

2.创建Form1窗体,继承BaseForm表单,
正常运行运行结果如下图2所示:
C# WinForm开发系列之自定义无边框窗体(最大化,最小化,关闭,拉伸和移动的相关知识)
                                                                                                                             图2

点击放大按钮如图3所示:
C# WinForm开发系列之自定义无边框窗体(最大化,最小化,关闭,拉伸和移动的相关知识)
                                                                                                                            图3


3,此时自定义的窗体只能放大,缩小和关闭,若要使窗体可移动,代码如下:
        //窗体移动相关常量设置
        const int Guying_HTLEFT = 10;
        const int Guying_HTRIGHT = 11;
        const int Guying_HTTOP = 12;
        const int Guying_HTTOPLEFT = 13;
        const int Guying_HTTOPRIGHT = 14;
        const int Guying_HTBOTTOM = 15;
        const int Guying_HTBOTTOMLEFT = 0x10;
        const int Guying_HTBOTTOMRIGHT = 17;

        ////重写系统WndProc函数,使无边框窗体可移动
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case 0x0084:
                    base.WndProc(ref m);
                    Point vPoint = new Point((int)m.LParam & 0xFFFF,
                        (int)m.LParam >> 16 & 0xFFFF);
                    vPoint = PointToClient(vPoint);
                    if (vPoint.X <= 5)
                        if (vPoint.Y <= 5)
                            m.Result = (IntPtr)Guying_HTTOPLEFT;
                        else if (vPoint.Y >= ClientSize.Height - 5)
                            m.Result = (IntPtr)Guying_HTBOTTOMLEFT;
                        else m.Result = (IntPtr)Guying_HTLEFT;
                    else if (vPoint.X >= ClientSize.Width - 5)
                        if (vPoint.Y <= 5)
                            m.Result = (IntPtr)Guying_HTTOPRIGHT;
                        else if (vPoint.Y >= ClientSize.Height - 5)
                            m.Result = (IntPtr)Guying_HTBOTTOMRIGHT;
                        else m.Result = (IntPtr)Guying_HTRIGHT;
                    else if (vPoint.Y <= 5)
                        m.Result = (IntPtr)Guying_HTTOP;
                    else if (vPoint.Y >= ClientSize.Height - 5)
                        m.Result = (IntPtr)Guying_HTBOTTOM;
                    break;
                case 0x0201:                //鼠标左键按下的消息   
                    m.Msg = 0x00A1;         //更改消息为非客户区按下鼠标   
                    m.LParam = IntPtr.Zero; //默认值   
                    m.WParam = new IntPtr(2);//鼠标放在标题栏内   
                    base.WndProc(ref m);
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }  

运行代码后,效果如图4,图5,图6所示:
C# WinForm开发系列之自定义无边框窗体(最大化,最小化,关闭,拉伸和移动的相关知识)
                                                                                                                          图4
C# WinForm开发系列之自定义无边框窗体(最大化,最小化,关闭,拉伸和移动的相关知识)
                                                                                                                          图5
C# WinForm开发系列之自定义无边框窗体(最大化,最小化,关闭,拉伸和移动的相关知识)

                                                                                                                          图6
注意: