【转】【C#】C#重绘windows窗体标题栏和边框

[Win32] 窗体暗色模式, C++, WinForm, WPF 使用方法, 判断颜色模式, 响应颜色变更消息, 设置标题栏暗色. Win32 暗色模式适配, C++, WinForm, WPF 判断当前颜色模式, 响应颜色变更消息, 设置标题栏暗色 阅读详情

摘要

windows桌面应用程序都有标准的标题栏和边框,大部分程序也默认使用这些样式,一些对视觉效果要求较高的程序,如QQ, MSN,迅雷等聊天工具的样式则与传统的windows程序大不相同,其中迅雷还将他们的BOLT界面引擎开放,使得大家也可以创建类似迅雷一样的界面。那么这些软件的界面是怎样实现的呢,使用C#是否也可以实现类似界面?

重绘方式

常见的自定义标题栏和边框的方式有两种,一种是隐藏标题栏和边框(称为非客户区),然后在客户区(可以放置控件的空间)使用一些常用的控件和图片来表示边框,这种方式较简单而麻烦,但如标题栏的拖动,边框的拖拽来改变窗体大小等效果,则有需要重新实现,另外有些客户区的鼠标事件,控件布局等也需要注意调整;另一种则是大部分软件实现方式,也较难一些;它利用windows的消息机制,截获windows消息,从而改变消息的行为。即windows的一些消息,会引起窗体绘制或重绘标题栏和边框的行为,因此只要结果这部分消息,然后开发人员自己处理绘制过程,并忽略默认行为,从而达到自定义的目的。

C#绘制接口

windows消息对于C#开发新手来说较生疏,原因是.net已经将windows消息机制进行了封装,使得我们很难发现windows消息的踪迹,其实它是以另一个身份存在着--事件。如控件的OnClick,Mouse等事件,都是对windows消息的封装,这样的目的更容易理解,和运用。.net提供了处理消息的接口,常用的方法为Control控件的void WndProc(ref Message m)方法,该方法用于接收任何发送到该控件的windows消息。那么我们就可以通过重写该方法来截获绘制窗体标题栏和边框的消息了。

找到了截获windows消息的接口,那么就需要知道哪些windows消息会引起窗体标题栏和边框的重绘。使用工具SPY++查看消息,发现windows消息WM_NCPAINT(0x85)和WM_NCACTIVATE(0x86),WM_NCRBUTTONDOWN(0x00A4),WM_SETCURSOR(0x0020),WM_NCLBUTTONUP(0x00A2),WM_NCLBUTTONDOWN(0xA1)等会重绘标题栏和边框。其中WM_NCPAINT和WM_NCACTIVATE会引起重绘标题栏和边框,消息WM_NCRBUTTONDOWN会触发标题栏的右键菜单,截获该消息可以自定义标题栏的右键菜单;其他消息会引起ConrtolBox(最小化,最大化,关闭按钮区域)的重绘。因此我们可以从截获这些消息入手。如下为WndProc方法的结构:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace CaptionBox {
    public class ThemeForm : Form {
        #region private structs

        struct _NonClientSizeInfo {
            public Size CaptionButtonSize;
            public Size BorderSize;
            public int CaptionHeight;
            public Rectangle CaptionRect;
            public Rectangle Rect;
            public Rectangle ClientRect;
            public int Width;
            public int Height;
        };

        #endregion

        #region constants

        const int WM_NCACTIVATE = 0x86;
        const int WM_NCPAINT = 0x85;
        const int WM_NCLBUTTONDOWN = 0xA1;
        const int WM_NCRBUTTONDOWN = 0x00A4;
        const int WM_NCRBUTTONUP = 0x00A5;
        const int WM_NCMOUSEMOVE = 0x00A0;
        const int WM_NCLBUTTONUP = 0x00A2;
        const int WM_NCCALCSIZE = 0x0083;
        const int WM_NCMOUSEHOVER = 0x02A0;
        const int WM_NCMOUSELEAVE = 0x02A2;
        const int WM_NCHITTEST = 0x0084;
        const int WM_NCCREATE = 0x0081;
        //const int WM_RBUTTONUP = 0x0205;

        const int WM_LBUTTONDOWN = 0x0201;
        const int WM_CAPTURECHANGED = 0x0215;
        const int WM_LBUTTONUP = 0x0202;
        const int WM_SETCURSOR = 0x0020;
        const int WM_CLOSE = 0x0010;
        const int WM_SYSCOMMAND = 0x0112;
        const int WM_MOUSEMOVE = 0x0200;
        const int WM_SIZE = 0x0005;
        const int WM_SIZING = 0x0214;
        const int WM_GETMINMAXINFO = 0x0024;
        const int WM_ENTERSIZEMOVE = 0x0231;
        const int WM_WINDOWPOSCHANGING = 0x0046;


        // FOR WM_SIZING MSG WPARAM
        const int WMSZ_BOTTOM = 6;
        const int WMSZ_BOTTOMLEFT = 7;
        const int WMSZ_BOTTOMRIGHT = 8;
        const int WMSZ_LEFT = 1;
        const int WMSZ_RIGHT = 2;
        const int WMSZ_TOP = 3;
        const int WMSZ_TOPLEFT = 4;
        const int WMSZ_TOPRIGHT = 5;

        // left mouse button is down.
        const int MK_LBUTTON = 0x0001;

        const int SC_CLOSE = 0xF060;
        const int SC_MAXIMIZE = 0xF030;
        const int SC_MINIMIZE = 0xF020;
        const int SC_RESTORE = 0xF120;
        const int SC_CONTEXTHELP = 0xF180;

        const int HTCAPTION = 2;
        const int HTCLOSE = 20;
        const int HTHELP = 21;
        const int HTMAXBUTTON = 9;
        const int HTMINBUTTON = 8;
        const int HTTOP = 12;

        const int SM_CYBORDER = 6;
        const int SM_CXBORDER = 5;
        const int SM_CYCAPTION = 4;

        const int CS_DropSHADOW = 0x20000;
        const int GCL_STYLE = (-26);

        #endregion

        #region windows api

        [DllImport("User32.dll")]
        private static extern IntPtr GetWindowDC(IntPtr hwnd);
        [DllImport("User32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GetWindowRect(IntPtr hwnd, ref _RECT rect);
        [DllImport("User32.dll")]
        private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SetClassLong(IntPtr hwnd, int nIndex, int dwNewLong);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetClassLong(IntPtr hwnd, int nIndex);

        #endregion

        #region default constructor

        public ThemeForm() {
            Text = "ThemeForm1";
            CloseButtonImage = Properties.Resources.close.ToBitmap();
            CloseButtonHoverImage = Properties.Resources.close2.ToBitmap();
            CloseButtonPressDownImage = Properties.Resources.close2.ToBitmap();

            MaximumButtonImage = Properties.Resources.max.ToBitmap();
            MaximumButtonHoverImage = Properties.Resources.max2.ToBitmap();
            MaximumButtonPressDownImage = Properties.Resources.max2.ToBitmap();

            MaximumNormalButtonImage = Properties.Resources.maxnorm.ToBitmap();
            MaximumNormalButtonHoverImage = Properties.Resources.maxnorm2.ToBitmap();
            MaximumNormalButtonPressDownImage = Properties.Resources.maxnorm2.ToBitmap();

            MinimumButtonImage = Properties.Resources.min.ToBitmap();
            MinimumButtonHoverImage = Properties.Resources.min2.ToBitmap();
            MinimumButtonPressDownImage = Properties.Resources.min2.ToBitmap();

            HelpButtonImage = Properties.Resources.help.ToBitmap();
            HelpButtonHoverImage = Properties.Resources.help2.ToBitmap();
            HelpButtonPressDownImage = Properties.Resources.help2.ToBitmap();
            CaptionColor = Brushes.White;
            CaptionBackgroundColor = Color.DimGray;

            SetClassLong(this.Handle, GCL_STYLE, GetClassLong(this.Handle, GCL_STYLE) | CS_DropSHADOW); //API函数加载,实现窗体边框阴影效果
        }

        #endregion

        [DefaultValue("")]
        [Browsable(true)]
        [Category("ControlBox")]
        public virtual ContextMenuStrip CaptionContextMenu { get; set; }

        protected virtual void OnCaptionContextMenu(int x, int y) {
            if (this.CaptionContextMenu != null)
                this.CaptionContextMenu.Show(x, y);
        }
        
        #region properties

        [Category("ControlBox")]
        [Description("Close button image in control box.")]
        [DisplayName("CloseButtonImage")]
        [DesignOnly(true)]
        public Image CloseButtonImage { get; set; }

        [Category("ControlBox")]
        [Description("Close button image pressed down in control box.")]
        [DisplayName("CloseButtonPressDownImage")]
        [DesignOnly(true)]
        public Image CloseButtonPressDownImage { get; set; }

        [Category("ControlBox")]
        [Description("Close button image hover in control box.")]
        [DisplayName("CloseButtonHoverImage")]
        [DesignOnly(true)]
        public Image CloseButtonHoverImage { get; set; }

        [Category("ControlBox")]
        [Description("Maximum button image in control box.")]
        [DisplayName("MaximumButtonImage")]
        [DesignOnly(true)]
        public Image MaximumButtonImage { get; set; }

        [Category("ControlBox")]
        [Description("Maximum button hover image in control box.")]
        [DisplayName("MaximumButtonHoverImage")]
        [DesignOnly(true)]
        public Image MaximumButtonHoverImage { get; set; }

        [Category("ControlBox")]
        [Description("Maximum button pressed down image in control box.")]
        [DisplayName("MaximumButtonPressDownImage")]
        [DesignOnly(true)]
        public Image MaximumButtonPressDownImage { get; set; }

        [Category("ControlBox")]
        [Description("Maximum Normal button image in control box.")]
        [DisplayName("MaximumNormalButtonImage")]
        [DesignOnly(true)]
        public Image MaximumNormalButtonImage { get; set; }

        [Category("ControlBox")]
        [Description("Maximum Normal button hover image in control box.")]
        [DisplayName("MaximumNormalButtonHoverImage")]
        [DesignOnly(true)]
        public Image MaximumNormalButtonHoverImage { get; set; }

        [Category("ControlBox")]
        [Description("Maximum Normal button pressed down image in control box.")]
        [DisplayName("MaximumNormalButtonPressDownImage")]
        [DesignOnly(true)]
        public Image MaximumNormalButtonPressDownImage { get; set; }

        [Category("ControlBox")]
        [Description("Minimum button image in control box.")]
        [DisplayName("MinimumButtonImage")]
        [DesignOnly(true)]
        public Image MinimumButtonImage { get; set; }

        [Category("ControlBox")]
        [Description("Minimum button hover image in control box.")]
        [DisplayName("MinimumButtonHoverImage")]
        [DesignOnly(true)]
        public Image MinimumButtonHoverImage { get; set; }

        [Category("ControlBox")]
        [Description("Minimum button pressed down image in control box.")]
        [DisplayName("MinimumButtonPressDownImage")]
        [DesignOnly(true)]
        public Image MinimumButtonPressDownImage { get; set; }

        [Category("ControlBox")]
        [Description("Help button image in control box.")]
        [DisplayName("HelpButtonImage")]
        [DesignOnly(true)]
        public Image HelpButtonImage { get; set; }

        [Category("ControlBox")]
        [Description("Help button hover image in control box.")]
        [DisplayName("HelpButtonHoverImage")]
        [DesignOnly(true)]
        public Image HelpButtonHoverImage { get; set; }

        [Category("ControlBox")]
        [Description("Help button pressed down image in control box.")]
        [DisplayName("HelpButtonPressDownImage")]
        [DesignOnly(true)]
        public Image HelpButtonPressDownImage { get; set; }

        [Category("CaptionColor")]
        [Description("The color of caption.")]
        [DisplayName("CaptionColor")]
        [DesignOnly(true)]
        public Brush CaptionColor { get; set; }

        [Category("CaptionColor")]
        [Description("The color of caption.")]
        [DisplayName("CaptionBackgroundColor")]
        [DefaultValue(typeof(Color), "Black")]
        [DesignOnly(true)]
        public Color CaptionBackgroundColor { get; set; }

        #endregion

        #region help methods

        private _NonClientSizeInfo GetNonClientInfo(IntPtr hwnd) {
            _NonClientSizeInfo info = new _NonClientSizeInfo();
            info.CaptionButtonSize = SystemInformation.CaptionButtonSize;
            info.CaptionHeight = SystemInformation.CaptionHeight;

            switch (this.FormBorderStyle) {
                case System.Windows.Forms.FormBorderStyle.Fixed3D:
                    info.BorderSize = SystemInformation.FixedFrameBorderSize;
                    break;
                case System.Windows.Forms.FormBorderStyle.FixedDialog:
                    info.BorderSize = SystemInformation.FixedFrameBorderSize;
                    break;
                case System.Windows.Forms.FormBorderStyle.FixedSingle:
                    info.BorderSize = SystemInformation.FixedFrameBorderSize;
                    break;
                case System.Windows.Forms.FormBorderStyle.FixedToolWindow:
                    info.BorderSize = SystemInformation.FixedFrameBorderSize;
                    info.CaptionButtonSize = SystemInformation.ToolWindowCaptionButtonSize;
                    info.CaptionHeight = SystemInformation.ToolWindowCaptionHeight;
                    break;
                case System.Windows.Forms.FormBorderStyle.Sizable:
                    info.BorderSize = SystemInformation.FrameBorderSize;
                    break;
                case System.Windows.Forms.FormBorderStyle.SizableToolWindow:
                    info.CaptionButtonSize = SystemInformation.ToolWindowCaptionButtonSize;
                    info.BorderSize = SystemInformation.FrameBorderSize;
                    info.CaptionHeight = SystemInformation.ToolWindowCaptionHeight;
                    break;
                default:
                    info.BorderSize = SystemInformation.BorderSize;
                    break;
            }

            _RECT areatRect = new _RECT();
            GetWindowRect(hwnd, ref areatRect);

            int width = areatRect.right - areatRect.left;
            int height = areatRect.bottom - areatRect.top;

            info.Width = width;
            info.Height = height;

            Point xy = new Point(areatRect.left, areatRect.top);
            xy.Offset(-areatRect.left, -areatRect.top);

            info.CaptionRect = new Rectangle(xy.X, xy.Y + info.BorderSize.Height, width, info.CaptionHeight);
            info.Rect = new Rectangle(xy.X, xy.Y, width, height);
            info.ClientRect = new Rectangle(xy.X + info.BorderSize.Width,
                xy.Y + info.CaptionHeight + info.BorderSize.Height,
                width - info.BorderSize.Width * 2,
                height - info.CaptionHeight - info.BorderSize.Height * 2);

            return info;
        }

        private void DrawTitle(Graphics g, _NonClientSizeInfo ncInfo, bool active) {
            int titleX;

            if (this.ShowIcon &&
                this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&
                this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow) {
                Size iconSize = SystemInformation.SmallIconSize;
                g.DrawIcon(this.Icon, new Rectangle(new Point(ncInfo.BorderSize.Width, ncInfo.BorderSize.Height + (ncInfo.CaptionHeight - iconSize.Height) / 2), iconSize));
                titleX = ncInfo.BorderSize.Width + iconSize.Width + ncInfo.BorderSize.Width;
            } else {
                titleX = ncInfo.BorderSize.Width;
            }

            SizeF captionTitleSize = g.MeasureString(this.Text, SystemFonts.CaptionFont);
            g.DrawString(this.Text, SystemFonts.CaptionFont, CaptionColor,
                    new RectangleF(titleX,
                        (ncInfo.BorderSize.Height + ncInfo.CaptionHeight - captionTitleSize.Height) / 2,
                        ncInfo.CaptionRect.Width - ncInfo.BorderSize.Width * 2 - SystemInformation.MinimumWindowSize.Width,
                        ncInfo.CaptionRect.Height), StringFormat.GenericTypographic);
        }

        private void DrawBorder(Graphics g, _NonClientSizeInfo ncInfo, Brush background, bool active) {
            Rectangle borderTop = new Rectangle(ncInfo.Rect.Left,
                    ncInfo.Rect.Top,
                    ncInfo.Rect.Left + ncInfo.Rect.Width,
                    ncInfo.Rect.Top + ncInfo.BorderSize.Height);
            Rectangle borderLeft = new Rectangle(
                    new Point(ncInfo.Rect.Location.X, ncInfo.Rect.Location.Y + ncInfo.BorderSize.Height),
                    new Size(ncInfo.BorderSize.Width, ncInfo.ClientRect.Height + ncInfo.CaptionHeight + ncInfo.BorderSize.Height));
            Rectangle borderRight = new Rectangle(ncInfo.Rect.Left + ncInfo.Rect.Width - ncInfo.BorderSize.Width,
                    ncInfo.Rect.Top + ncInfo.BorderSize.Height,
                    ncInfo.BorderSize.Width,
                    ncInfo.ClientRect.Height + ncInfo.CaptionHeight + ncInfo.BorderSize.Height);
            Rectangle borderBottom = new Rectangle(ncInfo.Rect.Left + ncInfo.BorderSize.Width,
                    ncInfo.Rect.Top + ncInfo.Rect.Height - ncInfo.BorderSize.Height,
                    ncInfo.Rect.Width - ncInfo.BorderSize.Width * 2,
                    ncInfo.Rect.Height);

            //Rectangle leftbottom = new Rectangle(new Point(ncInfo.Rect.Location.X, ncInfo.Rect.Height - ncInfo.BorderSize.Width * 2),
            //    new Size(ncInfo.BorderSize.Width * 2, ncInfo.BorderSize.Width * 2));

            //g.FillPie(Brushes.Red, leftbottom, 90, 180);
            //g.FillRectangle(Brushes.Red, leftbottom);
            // top border
            g.FillRectangle(background, borderTop);
            // left border
            g.FillRectangle(background, borderLeft);
            // right border
            g.FillRectangle(background, borderRight);
            // bottom border
            g.FillRectangle(background, borderBottom);
        }

        private void DrawCaption(IntPtr hwnd, bool active) {
            IntPtr dc;
            Graphics g;
            Size iconSize;
            _NonClientSizeInfo ncInfo;
            Brush backgroundColor = new SolidBrush(CaptionBackgroundColor);
            Brush foregroundColor = CaptionColor;

            iconSize = SystemInformation.SmallIconSize;

            dc = GetWindowDC(hwnd);
            ncInfo = GetNonClientInfo(hwnd);
            g = Graphics.FromHdc(dc);

            g.FillRectangle(backgroundColor, ncInfo.CaptionRect);

            DrawBorder(g, ncInfo, backgroundColor, active);
            DrawTitle(g, ncInfo, active);
            DrawControlBox(g, ncInfo, backgroundColor, this.ControlBox, this.MaximizeBox, this.MinimizeBox, this.HelpButton);
        
            g.Dispose();
            ReleaseDC(hwnd, dc);
        }

        private void DrawControlBox(Graphics g, _NonClientSizeInfo info, Brush background, bool closeBtn, bool maxBtn, bool minBtn, bool helpBtn) {
            if (this.ControlBox) {
                int closeBtnPosX = info.CaptionRect.Left + info.CaptionRect.Width - info.BorderSize.Width - info.CaptionButtonSize.Width;
                int maxBtnPosX = closeBtnPosX - info.CaptionButtonSize.Width;
                int minBtnPosX = maxBtnPosX - info.CaptionButtonSize.Width;
                int btnPosY = info.BorderSize.Height + (info.CaptionHeight - info.CaptionButtonSize.Height) / 2;

                Rectangle btnRect = new Rectangle(new Point(closeBtnPosX, btnPosY), info.CaptionButtonSize);
                Rectangle maxRect = new Rectangle(new Point(maxBtnPosX, btnPosY), info.CaptionButtonSize);
                Rectangle minRect = new Rectangle(new Point(minBtnPosX, btnPosY), info.CaptionButtonSize);

                Brush backgroundColor = new SolidBrush(CaptionBackgroundColor);

                g.FillRectangle(backgroundColor, btnRect);
                g.FillRectangle(backgroundColor, maxRect);
                g.FillRectangle(backgroundColor, minRect);

                g.DrawImage(CloseButtonImage, btnRect);

                if (this.MaximizeBox || this.MinimizeBox) {
                    if (this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&
                        this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow) {
                        if (this.WindowState == FormWindowState.Maximized) {
                            g.DrawImage(MaximumNormalButtonImage, maxRect);
                        } else {
                            g.DrawImage(MaximumButtonImage, maxRect);
                        }
                        g.DrawImage(MinimumButtonImage, minRect);
                    }
                } else if (this.HelpButton) {
                    if (this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&
                        this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow) {
                        g.DrawImage(HelpButtonImage, maxRect);
                    }
                }
            }
        }

        #endregion

        #region Major method WndProc

        private int LOBYTE(long p) { return (int)(p & 0x0000FFFF); }
        private int HIBYTE(long p) { return (int)(p >> 16); }

        protected override void WndProc(ref Message m) {
            if (this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.None) {
                switch (m.Msg) {
                    case WM_NCPAINT:
                        DrawCaption(m.HWnd, Form.ActiveForm == this);
                        return;
                    case WM_NCACTIVATE:
                        DrawCaption(m.HWnd, m.WParam.ToInt32() > 0);
                        return;
                    case WM_NCRBUTTONDOWN: {
                            int posX, posY;
                            int wp = m.WParam.ToInt32();
                            long lp = m.LParam.ToInt64();
                            posX = LOBYTE(lp);
                            posY = HIBYTE(lp);

                            if (wp == HTCAPTION) {
                                Point pt = this.PointToClient(new Point(posX, posY));
                                if (this.CaptionContextMenu != null) {
                                    this.CaptionContextMenu.Show(posX, posY);
                                    return;
                                }
                            }
                            break;
                        }
                    case WM_SETCURSOR:
                        if (this.ControlBox) {
                            int posX, posY;
                            int wp = m.WParam.ToInt32();
                            long lp = m.LParam.ToInt64();
                            posX = LOBYTE(lp);
                            posY = HIBYTE(lp);

                            Brush backgroundColor = new SolidBrush(CaptionBackgroundColor);
                            _NonClientSizeInfo ncInfo = GetNonClientInfo(m.HWnd);
                            IntPtr dc = GetWindowDC(m.HWnd);

                            Graphics g = Graphics.FromHdc(dc);
                            int closeBtnPosX = ncInfo.CaptionRect.Left + ncInfo.CaptionRect.Width - ncInfo.BorderSize.Width - ncInfo.CaptionButtonSize.Width;
                            int maxBtnPosX, minBtnPosX;
                            maxBtnPosX = closeBtnPosX - ncInfo.CaptionButtonSize.Width;
                            minBtnPosX = maxBtnPosX - ncInfo.CaptionButtonSize.Width;

                            int btnPosY = ncInfo.BorderSize.Height + (ncInfo.CaptionHeight - ncInfo.CaptionButtonSize.Height) / 2;

                            Rectangle btnRect = new Rectangle(new Point(closeBtnPosX, btnPosY), ncInfo.CaptionButtonSize);
                            Rectangle maxRect = new Rectangle(new Point(maxBtnPosX, btnPosY), ncInfo.CaptionButtonSize);
                            Rectangle minRect = new Rectangle(new Point(minBtnPosX, btnPosY), ncInfo.CaptionButtonSize);

                            g.FillRectangle(backgroundColor, btnRect);
                            g.FillRectangle(backgroundColor, maxRect);
                            g.FillRectangle(backgroundColor, minRect);

                            if (posX != HTCLOSE) {
                                g.DrawImage(CloseButtonImage, btnRect);
                            } else if (MouseButtons != System.Windows.Forms.MouseButtons.Left) {
                                g.DrawImage(CloseButtonHoverImage, btnRect);
                            } else {
                                g.DrawImage(CloseButtonPressDownImage, btnRect);
                            }

                            if (this.MaximizeBox || this.MinimizeBox) {
                                if (this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&
                                    this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow) {
                                    if (this.WindowState == FormWindowState.Maximized) {
                                        if (this.MaximizeBox) {
                                            if (posX != HTMAXBUTTON) {
                                                g.DrawImage(MaximumNormalButtonImage, maxRect);
                                            } else if (MouseButtons != System.Windows.Forms.MouseButtons.Left) {
                                                g.DrawImage(MaximumNormalButtonHoverImage, maxRect);
                                            } else {
                                                g.DrawImage(MaximumNormalButtonPressDownImage, maxRect);
                                            }
                                        } else {
                                            g.DrawImage(MaximumNormalButtonImage, maxRect);
                                        }
                                    } else {
                                        if (this.MaximizeBox) {
                                            if (posX != HTMAXBUTTON) {
                                                g.DrawImage(MaximumButtonImage, maxRect);
                                            } else if (MouseButtons != System.Windows.Forms.MouseButtons.Left) {
                                                g.DrawImage(MaximumButtonHoverImage, maxRect);
                                            } else {
                                                g.DrawImage(MaximumButtonPressDownImage, maxRect);
                                            }
                                        } else {
                                            g.DrawImage(MaximumButtonImage, maxRect);
                                        }
                                    }

                                    if (this.MinimizeBox) {
                                        if (posX != HTMINBUTTON) {
                                            g.DrawImage(MinimumButtonImage, minRect);
                                        } else if (MouseButtons != System.Windows.Forms.MouseButtons.Left) {
                                            g.DrawImage(MinimumButtonHoverImage, minRect);
                                        } else {
                                            g.DrawImage(MinimumButtonPressDownImage, minRect);
                                        }
                                    } else {
                                        g.DrawImage(MinimumButtonImage, minRect);
                                    }
                                }
                            } else if (this.HelpButton) {
                                if (this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&
                                    this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow) {
                                    if (posX != HTHELP) {
                                        g.DrawImage(HelpButtonImage, maxRect);
                                    } else if (MouseButtons != System.Windows.Forms.MouseButtons.Left) {
                                        g.DrawImage(HelpButtonHoverImage, maxRect);
                                    } else {
                                        g.DrawImage(HelpButtonPressDownImage, maxRect);
                                    }
                                }
                            }

                            g.Dispose();
                            ReleaseDC(m.HWnd, dc);
                        }
                        break;
                    case WM_NCLBUTTONUP: {
                            int wp = m.WParam.ToInt32();
                            switch (wp) {
                                case HTCLOSE:
                                    m.Msg = WM_SYSCOMMAND;
                                    m.WParam = new IntPtr(SC_CLOSE);
                                    break;
                                case HTMAXBUTTON:
                                    if (this.MaximizeBox) {
                                        m.Msg = WM_SYSCOMMAND;
                                        if (this.WindowState == FormWindowState.Maximized) {
                                            m.WParam = new IntPtr(SC_RESTORE);
                                        } else {
                                            m.WParam = new IntPtr(SC_MAXIMIZE);
                                        }
                                    }
                                    break;
                                case HTMINBUTTON:
                                    if (this.MinimizeBox) {
                                        m.Msg = WM_SYSCOMMAND;
                                        m.WParam = new IntPtr(SC_MINIMIZE);
                                    }
                                    break;
                                case HTHELP:
                                    m.Msg = WM_SYSCOMMAND;
                                    m.WParam = new IntPtr(SC_CONTEXTHELP);
                                    break;
                                default:
                                    break;
                            }
                            break;
                        }

                    case WM_NCLBUTTONDOWN:
                        if (this.ControlBox) {
                            bool ret = false;
                            int posX, posY;
                            int wp = m.WParam.ToInt32();
                            long lp = m.LParam.ToInt64();
                            posX = LOBYTE(lp);
                            posY = HIBYTE(lp);

                            _NonClientSizeInfo ncInfo = GetNonClientInfo(m.HWnd);
                            IntPtr dc = GetWindowDC(m.HWnd);
                            Brush backgroundColor = new SolidBrush(CaptionBackgroundColor);

                            Graphics g = Graphics.FromHdc(dc);
                            int closeBtnPosX = ncInfo.CaptionRect.Left + ncInfo.CaptionRect.Width - ncInfo.BorderSize.Width - ncInfo.CaptionButtonSize.Width;
                            int maxBtnPosX, minBtnPosX;
                            int btnPosY = ncInfo.BorderSize.Height + (ncInfo.CaptionHeight - ncInfo.CaptionButtonSize.Height) / 2;
                            maxBtnPosX = closeBtnPosX - ncInfo.CaptionButtonSize.Width;
                            minBtnPosX = maxBtnPosX - ncInfo.CaptionButtonSize.Width;

                            Rectangle btnRect = new Rectangle(new Point(closeBtnPosX, btnPosY), ncInfo.CaptionButtonSize);
                            Rectangle maxRect = new Rectangle(new Point(maxBtnPosX, btnPosY), ncInfo.CaptionButtonSize);
                            Rectangle minRect = new Rectangle(new Point(minBtnPosX, btnPosY), ncInfo.CaptionButtonSize);

                            g.FillRectangle(backgroundColor, btnRect);
                            g.FillRectangle(backgroundColor, maxRect);
                            g.FillRectangle(backgroundColor, minRect);

                            if (wp == HTCLOSE) {
                                g.DrawImage(CloseButtonPressDownImage, btnRect);
                                ret = true;
                            } else {
                                g.DrawImage(CloseButtonImage, btnRect);
                            }

                            if (this.MaximizeBox || this.MinimizeBox) {
                                if (this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow &&
                                    this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow) {
                                    if (this.WindowState == FormWindowState.Maximized) {
                                        if (wp == HTMAXBUTTON && this.MaximizeBox) {
                                            minBtnPosX = maxBtnPosX - ncInfo.CaptionButtonSize.Width;
                                            g.DrawImage(MaximumNormalButtonPressDownImage, maxRect);
                                            ret = true;
                                        } else {
                                            g.DrawImage(MaximumNormalButtonImage, maxRect);
                                        }
                                    } else {
                                        if (wp == HTMAXBUTTON && this.MaximizeBox) {
                                            minBtnPosX = maxBtnPosX - ncInfo.CaptionButtonSize.Width;
                                            g.DrawImage(MaximumButtonPressDownImage, maxRect);
                                            ret = true;
                                        } else {
                                            g.DrawImage(MaximumButtonImage, maxRect);
                                        }
                                    }
                                    if (wp == HTMINBUTTON && this.MinimizeBox) {
                                        g.DrawImage(MinimumButtonPressDownImage, minRect);
                                        ret = true;
                                    } else {
                                        g.DrawImage(MinimumButtonImage, minRect);
                                    }
                                }
                            } else if (this.HelpButton) {
                                if (this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&
                                    this.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow) {
                                    if (wp == HTHELP) {
                                        g.DrawImage(HelpButtonPressDownImage, maxRect);
                                        ret = true;
                                    } else {
                                        g.DrawImage(HelpButtonImage, maxRect);
                                    }
                                }
                            }

                            g.Dispose();
                            ReleaseDC(m.HWnd, dc);

                            if (ret)
                                return;
                        }
                        break;
                }
            }

            base.WndProc(ref m);
        }

        #endregion
    }
}

运行效果:

原文及源码下载地址:http://blog.csdn.net/guangboo/article/details/8264293

C# Windows API 去掉窗口标题栏 以及边框 写这篇博客的目的,就是防止忘记找不到。 实际项目中使用,测试有效。 调用: IntPtr CurrentAppHandle = GetForegroundWindow(); HandleRef ParentHandle = new HandleRef(this, CurrentAppHandle); // 初始化窗口风格 IntPtr Style = GetWindowLongPtr(C... 阅读详情

相关推荐

C#修改标题栏边框颜色

可以通过拦截窗口消息实现汇窗口边框标题栏,无需设置winform为None模式自己去边框

C#实现窗体颜色改变

在程序设计时,可以通过设置窗体的BackColor属性来改变窗口的背景颜色。但是这个属性改变后整个窗体的客户区都会变成这种颜色,并且非常单调。如果窗体的客户区可以向标题栏一样能够体现颜色的渐变效果,那么窗体风格将会另有一番风味。C#中可以通过Color.FromArgb( )方法返回一种颜色,下面详细介绍一下该方法。Color.FromArgb( )方法用来返回Color的颜色值,该方法语

jiangxinyu的专栏 2万+

c#窗体颜色更改_c#窗体颜色更改_

C#窗体颜色更改,可以改变窗体的颜色一个人员工作为了解决定的是否则是否则是否则是否则是否则1223456雪白以及其他们

c#更改标题栏颜色收藏

 #region 改变窗口样式        #if !DEBUG        [DllImport ("User32.dll")]        private static extern IntPtr GetWindowDC(IntPtr hwnd);        [DllImport ("User32.dll")]        private static extern

朩冰雲的专栏 8737

[]C#windows窗体标题栏边框

原文:http://www.2cto.com/kf/201212/173988.html 摘要windows桌面应用程序都有标准的标题栏边框,大部分程序也默认使用这些样式,一些对视觉效果要求较高的程序,如QQ, MSN,迅雷等聊天工具的样式则与传统的windows程序大不相同,其中迅雷还将他们的BOLT界面引擎开放,使得大家也可以创建类似迅雷一样的界面。那么这些软件的界面是怎样实现的呢,使用C...

weixin_30337157的博客 539

CWindows窗体标题栏边框教程

C#Windows窗体标题栏边框教程 【下载地址】CWindows窗体标题栏边框教程 想要为你的Windows应用程序打造独特的界面风格?本开源项目为你提供了详细的C#教程,教你如何Windows窗体标题栏边框。通过继承Form类并写OnPaint方法,你可以轻松实现窗体的自定义制。此外,教程还详...

gitblog_06775的博客 736

C#windows窗体标题栏边框

摘要 windows桌面应用程序都有标准的标题栏边框,大部分程序也默认使用这些样式,一些对视觉效果要求较高的程序,如QQ, MSN,迅雷等聊天工具的样式则与传统的windows程序大不相同,其中迅雷还将他们的BOLT界面引擎开放,使得大家也可以创建类似迅雷一样的界面。那么这些软件的界面是怎样实现的呢,使用C#是否也可以实现类似界面? 方式 常见的自定义标题栏边框的方式有两种,一种

爱上了月儿就注定要为她挡太阳 2569

C# wndproc windows窗体标题栏边框

C#windows窗体标题栏边框 摘要 windows桌面应用程序都有标准的标题栏边框,大部分程序也默认使用这些样式,一些对视觉效果要求较高的程序,如QQ, MSN,迅雷等聊天工具的样式则与传统的windows程序大不相同,其中迅雷还将他们的BOLT界面引擎开放,使得大家也可以创建类似迅雷一样的界面。 那么这些软件的界面是怎样实现的呢,使用C#是否也可以实现类似界面? 方式 ...

MayMatrix 的博客 839

CWindows窗体标题栏边框教程:打造个性化界面

C#Windows窗体标题栏边框教程:打造个性化界面 【下载地址】CWindows窗体标题栏边框教程 想要为你的Windows应用程序打造独特的界面风格?本开源项目为你提供了详细的C#教程,教你如何Windows窗体标题栏边框。通过继承Form类并写OnPaint方法,你可以轻松实现窗体的自定义制...

gitblog_06701的博客 333

Windows窗体学这一篇就够了(C#控件讲解)

常用控件包括文本控件、选择控件、分组控件、菜单控件、工具栏控件以及状态栏控件常用控件的作用控件分类作用文本控件文本控件可以在控件上显示文本选择控件主要为用户提供选择的项目分组控件使用分组控件可以将窗体中的其他控件进行分组处理菜单控件为系统制作功能菜单,将应用程序命令分组,使它们更容易访问工具栏控件提供了主菜单中常用的相关工具状态栏控件用于显示窗体上的对象的相关信息,或者可以显示应用程序的信息通过设置DateTimePicker控件的CustomFormat属性,可自定义日期时间格式字符串。

weixin_51263756的博客 6万+

[]C#边框窗体移动的三种方法

[]C#边框窗体移动的三种方法1. 写WndProc 写WndProc<br />protected override void WndProc(ref Message m)<br />{       <br />        const int WM_NCHITTEST = 0x84;<br />        const int HTCLIENT = 0x01;<br />        const int HTCAPTION = 0x02;<br />         if (m.Msg 

skyQQ的专栏 671

C#窗体相关笔记

有格式的文本控件(RichTextBox) 1、滚动条 参数: None:没有滚动条 Horizontal:文本超过控件宽度,水平滚动条(同时WordWrap属性设置为false) Vertical:文本超过控件高度,垂直滚动条 Both:当文本长宽超过控件,显示对应的滚动条(水平想显示,还要把WordWrap属性设置为false) ForcedHorizintal:有水平滚动条, ...

minglinhwsrg的博客 3847

c# 窗口不显示标题栏及周围有/无边框的设置

一 : 不显示标题栏也无边框: 方法1:属性里直接设置 方法2:手写代码(两种效果一样) this.FormBorderStyle = FormBorderStyle.None; 二 : 不显示标题栏,但有边框 在属性里设置(或直接写代码实现) FormBorderStyle 设置想要的边框类型 ControlBox = falseMinimizeBox = falseMaxim...

weixin_34029949的博客 2398
上一篇: 【转】【矩阵】三维坐标旋转矩阵算法
下一篇: 【MFC】ID命名和数字约定
梦琪小生
博客等级 码龄16年 96粉丝 348原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值