You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Border设为None的C#窗体实现顶部Panel调整大小

自定义无边框窗体顶部标题栏缩放功能实现问题

我是C#新手,正在为Python项目制作一款基于Visual Studio的C#弹出窗体(追求美观性)。已完成以下操作:

  • 创建项目,将主窗体的Border属性设为None
  • 添加名为titleBarPanel的Panel控件
  • 实现窗体底部及侧边的调整大小功能
  • 实现通过titleBarPanel拖拽移动窗体的功能

目前需要实现通过顶部titleBarPanel调整窗体大小的功能,已搜索Stack Overflow、YouTube及咨询ChatGPT,但未找到可行方案。

完整代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace UI_Variables_Prompt
{
    public partial class Form1 : Form
    {
        private const int WM_NCHITTEST = 0x84;
        private const int HTCLIENT = 0x1;
        private const int HTCAPTION = 0x2;
        private const int HTBOTTOMLEFT = 0x10;
        private const int HTBOTTOMRIGHT = 0x11;
        private const int HTLEFT = 0xa;
        private const int HTRIGHT = 0xb;
        private const int HTBOTTOM = 0xf;
        private const int HTTOP = 0xc;
        private const int HTTOPLEFT = 0xd;
        private const int HTTOPRIGHT = 0xe;


        private bool isDragging = false;
        private Point dragStart;
        private bool isResizing = false;
        private int resizeDir = 0;

        public Form1()
        {
            InitializeComponent();
            titleBarPanel.MouseDown += new MouseEventHandler(titleBarPanel_MouseDown);
            titleBarPanel.MouseMove += new MouseEventHandler(titleBarPanel_MouseMove);
            titleBarPanel.MouseUp += new MouseEventHandler(titleBarPanel_MouseUp);
            this.MouseDown += new MouseEventHandler(Form1_MouseDown);
            this.MouseMove += new MouseEventHandler(Form1_MouseMove);
            this.MouseUp += new MouseEventHandler(Form1_MouseUp);

        }

        protected override void WndProc(ref Message m)
        {
            const int WM_NCHITTEST = 0x0084;
            const int HTCLIENT = 1;
            const int HTCAPTION = 2;
            const int HTTOP = 12;
            const int HTLEFT = 10;
            const int HTRIGHT = 11;
            const int HTBOTTOM = 15;
            const int HTTOPLEFT = 13;
            const int HTTOPRIGHT = 14;
            const int HTBOTTOMLEFT = 16;
            const int HTBOTTOMRIGHT = 17;

            if (m.Msg == WM_NCHITTEST)
            {
                base.WndProc(ref m);
                if (m.Result == (IntPtr)HTCLIENT)
                {
                    Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
                    pos = this.PointToClient(pos);
                    if (pos.Y < 10)
                    {
                        if (pos.X < 10)
                            m.Result = (IntPtr)HTTOPLEFT;
                        else if (pos.X > this.ClientSize.Width - 10)
                            m.Result = (IntPtr)HTTOPRIGHT;
                        else
                            m.Result = (IntPtr)HTTOP;
                    }
                    else if (pos.Y > this.ClientSize.Height - 10)
                    {
                        if (pos.X < 10)
                            m.Result = (IntPtr)HTBOTTOMLEFT;
                        else if (pos.X > this.ClientSize.Width - 10)
                            m.Result = (IntPtr)HTBOTTOMRIGHT;
                        else
                            m.Result = (IntPtr)HTBOTTOM;
                    }
                    else if (pos.X < 10)
                        m.Result = (IntPtr)HTLEFT;
                    else if (pos.X > this.ClientSize.Width - 10)
                        m.Result = (IntPtr)HTRIGHT;
                }
                else if (m.Result == (IntPtr)HTCAPTION)
                {
                    m.Result = (IntPtr)HTCLIENT;
                }
            }
            else
            {
                base.WndProc(ref m);
            }
        }

        private int ResizeDirection(Point cursorPos, Rectangle formBounds)
        {
            const int HTLEFT = 10;
            const int HTRIGHT = 11;
            const int HTTOP = 12;
            const int HTTOPLEFT = 13;
            const int HTTOPRIGHT = 14;
            const int HTBOTTOM = 15;
            const int HTBOTTOMLEFT = 16;
            const int HTBOTTOMRIGHT = 17;

            if (cursorPos.Y < formBounds.Top + 10)
            {
                if (cursorPos.X < formBounds.Left + 10)
                    return HTTOPLEFT;
                else if (cursorPos.X > formBounds.Right - 10)
                    return HTTOPRIGHT;
                else
                    return HTTOP;
            }
            else if (cursorPos.Y > formBounds.Bottom - 10)
            {
                if (cursorPos.X < formBounds.Left + 10)
                    return HTBOTTOMLEFT;
                else if (cursorPos.X > formBounds.Right - 10)
                    return HTBOTTOMRIGHT;
                else
                    return HTBOTTOM;
            }
            else if (cursorPos.X < formBounds.Left + 10)
                return HTLEFT;
            else if (cursorPos.X > formBounds.Right - 10)
                return HTRIGHT;

            return 0;
        }


        private void titleBarPanel_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isDragging = true;
                dragStart = new Point(e.X, e.Y);
            }
        }

        private void titleBarPanel_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragging)
            {
                Point p = PointToScreen(e.Location);
                Location = new Point(p.X - this.dragStart.X, p.Y - this.dragStart.Y);
            }
            else if (isResizing)
            {
                switch (resizeDir)
                {
                    case HTTOP:
                        this.Height = Math.Max(this.MinimumSize.Height, this.dragStart.Y - e.Y + this.Height);
                        break;
                    case HTTOPLEFT:
                        this.Width = Math.Max(this.MinimumSize.Width, this.dragStart.X - e.X + this.Width);
                        this.Height = Math.Max(this.MinimumSize.Height, this.dragStart.Y - e.Y + this.Height);
                        this.Left = Math.Min(this.Left + e.X - this.dragStart.X, this.Left + this.Width - this.MinimumSize.Width);
                        break;
                    case HTTOPRIGHT:
                        this.Width = Math.Max(this.MinimumSize.Width, e.X - this.dragStart.X + this.Width);
                        this.Height = Math.Max(this.MinimumSize.Height, this.dragStart.Y - e.Y + this.Height);
                        break;
                    case HTLEFT:
                        this.Width = Math.Max(this.MinimumSize.Width, this.dragStart.X - e.X + this.Width);
                        this.Left = Math.Min(this.Left + e.X - this.dragStart.X, this.Left + this.Width - this.MinimumSize.Width);
                        break;
                    case HTRIGHT:
                        this.Width = Math.Max(this.MinimumSize.Width, e.X - this.dragStart.X + this.Width);
                        break;
                    case HTBOTTOM:
                        this.Height = Math.Max(this.MinimumSize.Height, e.Y - this.dragStart.Y + this.Height);
                        break;
                    case HTBOTTOMLEFT:
                        this.Width = Math.Max(this.MinimumSize.Width, this.dragStart.X - e.X + this.Width);
                        this.Height = Math.Max(this.MinimumSize.Height, e.Y - this.dragStart.Y + this.Height);
                        this.Left = Math.Min(this.Left + e.X - this.dragStart.X, this.Left + this.Width - this.MinimumSize.Width);
                        break;
                    case HTBOTTOMRIGHT:
                        this.Width = Math.Max(this.MinimumSize.Width, e.X - this.dragStart.X + this.Width);
                        this.Height = Math.Max(this.MinimumSize.Height, e.Y - this.dragStart.Y + this.Height);
                        break;
                }
            }
        }

        private void titleBarPanel_MouseUp(object sender, MouseEventArgs e)
        {
            isDragging = false;
            isResizing = false;
            resizeDir = 0;
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            isResizing = false;
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && !isDragging)
            {
                this.dragStart = new Point(e.X, e.Y);
                isResizing = true;
                resizeDir = ResizeDirection(e.Location, this.Bounds);
            }
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (isResizing)
            {
                int cursorType = 0;
                switch (resizeDir)
                {
                    case HTTOP:
                    case HTBOTTOM:
                        cursorType = Cursors.SizeNS.Handle.ToInt32();
                        break;
                    case HTLEFT:
                    case HTRIGHT:
                        cursorType = Cursors.SizeWE.Handle.ToInt32();
                        break;
                    case HTTOPLEFT:
                    case HTBOTTOMRIGHT:
                        cursorType = Cursors.SizeNWSE.Handle.ToInt32();
                        break;
                    case HTTOPRIGHT:
                    case HTBOTTOMLEFT:
                        cursorType = Cursors.SizeNESW.Handle.ToInt32();
                        break;
                }

                Cursor.Current = new Cursor(new IntPtr(cursorType));
            }
            else
            {
                Cursor.Current = Cursors.Default;
            }
        }

    }
}

窗体外观展示

窗体外观展示

内容的提问来源于stack exchange,提问作者Jakub Szurlej

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 19:56:59