无边框和可调整大小的窗体(C#)

14
我在网上找到了一些代码并复制了它们,到目前为止,除了一个问题之外,我已经成功地做完了所有事情,那就是我想要使表单(窗口)完全没有边框。
我正在使用Visual Studio 2013,这个问题仅涉及需要编写的代码,以使表单(窗口)无边框。问题在于,当您将其设置为无边框时,它不再可调整大小,但当它有边框时,它是可调整大小的。
我知道使用一些代码可以覆盖和实现两者。这就是我目前所拥有的(从另一个网站复制而来)。这会取消顶部带有程序名称的栏,使表单可以通过单击和拖动表单进行移动,并且可以调整大小。
唯一的问题是边框还在那里。我该添加什么代码,以便去掉边框?我想保留这个当前代码,因为它已经满足了我需要的几个功能。
顺便说一句,我查看了一些旧的类似主题的问题,但没有找到我需要的正确代码。
对于指导我去另一个线程的mod:我尝试了那里的代码,它并不完全符合我的需求,虽然它是一个相似的问题。当我尝试那个代码时,我无法在表单(窗口)上的任何地方单击以移动它。而且,它只有右下角一个可调整大小的角,这不是我想要的。我需要在四个角和所有边框上都具有调整大小功能,就像普通窗口一样。
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 BoxHider
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //Next line doesn't seem to be working
            this.FormBorderStyle = FormBorderStyle.None;
        }
        const int WM_NCHITTEST = 0x0084;
        const int HTCLIENT = 1;
        const int HTCAPTION = 2;
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            switch (m.Msg)
            {
                case WM_NCHITTEST:
                    if (m.Result == (IntPtr)HTCLIENT)
                    {
                        m.Result = (IntPtr)HTCAPTION;
                    }
                    break;
            }
        }
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.Style |= 0x40000;
                return cp;
            }
        }               
    }
}

What I need


1
你希望如何调整没有边框可拖动的窗体大小呢?只能通过拖动窗体的边缘来实现吗? - dub stylee
2
可见的边框已经消失,但当你将鼠标移动到窗体的边缘时,鼠标指针会改变形状,通过单击和拖动来调整大小。 - Code Man
3个回答

21

试试这个:

public Form1()
{
    InitializeComponent();
    this.FormBorderStyle = FormBorderStyle.None;
}

protected override void WndProc(ref Message m)
{
    const int RESIZE_HANDLE_SIZE = 10;

    switch (m.Msg)
    {
        case 0x0084/*NCHITTEST*/ :
            base.WndProc(ref m);

            if ((int)m.Result == 0x01/*HTCLIENT*/)
            {
                Point screenPoint = new Point(m.LParam.ToInt32());
                Point clientPoint = this.PointToClient(screenPoint);                        
                if (clientPoint.Y <= RESIZE_HANDLE_SIZE)
                {
                    if (clientPoint.X <= RESIZE_HANDLE_SIZE)
                        m.Result = (IntPtr) 13/*HTTOPLEFT*/ ;
                    else if (clientPoint.X < (Size.Width - RESIZE_HANDLE_SIZE))
                        m.Result = (IntPtr) 12/*HTTOP*/ ;
                    else
                        m.Result = (IntPtr) 14/*HTTOPRIGHT*/ ;
                }
                else if (clientPoint.Y <= (Size.Height - RESIZE_HANDLE_SIZE))
                {
                    if (clientPoint.X <= RESIZE_HANDLE_SIZE)
                        m.Result = (IntPtr) 10/*HTLEFT*/ ;
                    else if (clientPoint.X < (Size.Width - RESIZE_HANDLE_SIZE))
                        m.Result = (IntPtr) 2/*HTCAPTION*/ ;
                    else
                        m.Result = (IntPtr) 11/*HTRIGHT*/ ;
                }
                else
                {
                    if (clientPoint.X <= RESIZE_HANDLE_SIZE)
                        m.Result = (IntPtr) 16/*HTBOTTOMLEFT*/ ;
                    else if (clientPoint.X < (Size.Width - RESIZE_HANDLE_SIZE))
                        m.Result = (IntPtr) 15/*HTBOTTOM*/ ;
                    else
                        m.Result = (IntPtr)17/*HTBOTTOMRIGHT*/ ;
                }
            }
            return;
    }
    base.WndProc(ref m);
}

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.Style |= 0x20000; // <--- use 0x20000
        return cp;
    }
}

信息来源:


4
去掉边框,但使其不可调整大小。 - Code Man
1
这是专业的代码。它正按照我所需的方式工作。 - Code Man
1
我也点赞。这是我见过的最好的调整大小代码。 - LuckyLuke82
2
非常好,谢谢。别忘了给表单添加填充。 - Mutley
2
唯一的问题是表单必须在顶部,不被任何其他控件覆盖,如果您将像dataGridView这样的控件放置到边缘,表单将无法调整大小。 - user5583316
显示剩余6条评论

0

最近我需要一个与你相同的问题的类似答案。我重写了WndProc函数,代码可以正常工作。注意:在标题栏顶部不应该有任何控件,否则它将无法工作!

protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case 0x84:
                base.WndProc(ref m);
                if ((int)m.Result == 0x1)
                {
                    if (Cursor.Position.Y <= (this.Location.Y + HeightOfTitleBar) && Cursor.Position.Y >= this.Location.Y + 4)
                        m.Result = (IntPtr)0x2;


                    if (Cursor.Position.Y <= this.Location.Y + this.Height && Cursor.Position.Y >= this.Location.Y + this.Height - 4)
                        m.Result = (IntPtr)15;
                    if (Cursor.Position.Y <= this.Location.Y + 4 && Cursor.Position.Y >= this.Location.Y)
                        m.Result = (IntPtr)12;
                    if (Cursor.Position.X <= this.Location.X + this.Width && Cursor.Position.X >= this.Location.X + this.Width - 4)
                        m.Result = (IntPtr)11;
                    if (Cursor.Position.X <= this.Location.X + 4 && Cursor.Position.X >= this.Location.X)
                        m.Result = (IntPtr)10;


                    if (Cursor.Position.Y <= this.Location.Y + 8 && Cursor.Position.Y >= this.Location.Y && Cursor.Position.X <= this.Location.X + 8 && Cursor.Position.X >= this.Location.X)
                        m.Result = (IntPtr)13;
                    if (Cursor.Position.Y <= this.Location.Y + this.Height && Cursor.Position.Y >= this.Location.Y + this.Height - 8 && Cursor.Position.X <= this.Location.X + this.Width && Cursor.Position.X >= this.Location.X + this.Width - 8)
                        m.Result = (IntPtr)17;
                    if (Cursor.Position.Y <= this.Location.Y + this.Height && Cursor.Position.Y >= this.Location.Y + this.Height - 8 && Cursor.Position.X <= this.Location.X + 8 && Cursor.Position.X >= this.Location.X)
                        m.Result = (IntPtr)16;
                    if (Cursor.Position.Y <= this.Location.Y + 8 && Cursor.Position.Y >= this.Location.Y && Cursor.Position.X <= this.Location.X + this.Width && Cursor.Position.X >= this.Location.X + this.Width - 8)
                        m.Result = (IntPtr)14;
                }
                return;
        }

        base.WndProc(ref m);
    }

0

在加载表单后,您应该设置边框样式:

protected override void OnLoad(EventArgs e)
{
  base.OnLoad(e);
  this.FormBorderStyle = FormBorderStyle.None;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接