背景:
你好我目前正在尝试在Windows窗体中为学校项目创建自定义平面样式窗口。想法是使用此窗口作为基础并创建从其继承的其他窗口。我试图实现的样式类似于Visual Studio 2017本身的样式(深色主题)。我正在尝试向窗口添加功能,例如:
尝试通过拖动边框使窗口可调整大小时出现问题。
我所拥有的:
这是window的图片。
该表单包含2个面板:
表单的填充为1px(边框会改变颜色,稍后会显示)
问题:
我找到了似乎可以解决我问题的答案:https://stackoverflow.com/a/32261547/70345,但是当我尝试实现它时,并不能完全解决问题。人们似乎要做的就是在窗体周围绘制矩形,并在WndProc函数中检测光标是否悬停在矩形上:
protected override void OnPaint(PaintEventArgs e) // you can safely omit this method if you want
{
e.Graphics.FillRectangle(Brushes.Green, Top);
e.Graphics.FillRectangle(Brushes.Green, Left);
e.Graphics.FillRectangle(Brushes.Green, Right);
e.Graphics.FillRectangle(Brushes.Green, Bottom);
}
private const int
HTLEFT = 10,
HTRIGHT = 11,
HTTOP = 12,
HTTOPLEFT = 13,
HTTOPRIGHT = 14,
HTBOTTOM = 15,
HTBOTTOMLEFT = 16,
HTBOTTOMRIGHT = 17;
const int _ = 10; // you can rename this variable if you like
Rectangle Top { get { return new Rectangle(0, 0, this.ClientSize.Width, _); } }
Rectangle Left { get { return new Rectangle(0, 0, _, this.ClientSize.Height); } }
Rectangle Bottom { get { return new Rectangle(0, this.ClientSize.Height - _, this.ClientSize.Width, _); } }
Rectangle Right { get { return new Rectangle(this.ClientSize.Width - _, 0, _, this.ClientSize.Height); } }
Rectangle TopLeft { get { return new Rectangle(0, 0, _, _); } }
Rectangle TopRight { get { return new Rectangle(this.ClientSize.Width - _, 0, _, _); } }
Rectangle BottomLeft { get { return new Rectangle(0, this.ClientSize.Height - _, _, _); } }
Rectangle BottomRight { get { return new Rectangle(this.ClientSize.Width - _, this.ClientSize.Height - _, _, _); } }
protected override void WndProc(ref Message message)
{
base.WndProc(ref message);
if (message.Msg == 0x84) // WM_NCHITTEST
{
var cursor = this.PointToClient(Cursor.Position);
if (TopLeft.Contains(cursor)) message.Result = (IntPtr)HTTOPLEFT;
else if (TopRight.Contains(cursor)) message.Result = (IntPtr)HTTOPRIGHT;
else if (BottomLeft.Contains(cursor)) message.Result = (IntPtr)HTBOTTOMLEFT;
else if (BottomRight.Contains(cursor)) message.Result = (IntPtr)HTBOTTOMRIGHT;
else if (Top.Contains(cursor)) message.Result = (IntPtr)HTTOP;
else if (Left.Contains(cursor)) message.Result = (IntPtr)HTLEFT;
else if (Right.Contains(cursor)) message.Result = (IntPtr)HTRIGHT;
else if (Bottom.Contains(cursor)) message.Result = (IntPtr)HTBOTTOM;
}
}}
但是,当我这样做时,矩形是在面板后面绘制的,因此即使我将矩形的大小(“ _”变量)设置为10px或20px,我可以单击以调整窗口大小的区域始终为1px (由于存在表格填充)。
我还尝试使用某种叠加层并在其中绘制矩形:https://www.codeproject.com/Articles/26071/Draw-Over-WinForms-Controls
但是我有同样的问题。
我需要什么
我需要以某种方式在面板前面绘制矩形,以便可以有更大的区域来调整窗体的大小。我在编程方面不是很有经验,所以我愿意接受任何建议和改进。也欢迎使用其他解决方案。
这是我的表格:
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 BaseWindow
{
public partial class BaseWindowForm : Form
{
public BaseWindowForm()
{
InitializeComponent();
}
#region draggable window
private bool windowDragging = false;
private Point startPoint = new Point(0, 0);
private void TopPanel_MouseDown(object sender, MouseEventArgs e)
{
windowDragging = true; // _dragging is your variable flag
startPoint = new Point(e.X, e.Y);
}
private void TopPanel_MouseUp(object sender, MouseEventArgs e)
{
windowDragging = false;
}
private void TopPanel_MouseMove(object sender, MouseEventArgs e)
{
if (windowDragging)
{
Point p = PointToScreen(e.Location);
Location = new Point(p.X - this.startPoint.X, p.Y - this.startPoint.Y);
}
}
#endregion
#region border color focus
private void BaseWindowForm_Activated(object sender, EventArgs e)
{
this.BackColor = Color.FromArgb(0, 122, 204);
}
private void BaseWindowForm_Deactivate(object sender, EventArgs e)
{
this.BackColor = Color.FromArgb(63, 63, 70);
}
#endregion
#region maximize/minimize
private void BaseWindowForm_Maximize(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Normal)
{
this.WindowState = FormWindowState.Maximized;
}
else if (this.WindowState == FormWindowState.Maximized)
{
this.WindowState = FormWindowState.Normal;
}
}
private void ButtonMinimize_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
}
#endregion
private const int
HTLEFT = 10,
HTRIGHT = 11,
HTTOP = 12,
HTTOPLEFT = 13,
HTTOPRIGHT = 14,
HTBOTTOM = 15,
HTBOTTOMLEFT = 16,
HTBOTTOMRIGHT = 17;
const int _ = 10; // you can rename this variable if you like
Rectangle Top { get { return new Rectangle(0, 0, this.ClientSize.Width, _); } }
Rectangle Left { get { return new Rectangle(0, 0, _, this.ClientSize.Height); } }
Rectangle Bottom { get { return new Rectangle(0, this.ClientSize.Height - _, this.ClientSize.Width, _); } }
Rectangle Right { get { return new Rectangle(this.ClientSize.Width - _, 0, _, this.ClientSize.Height); } }
Rectangle TopLeft { get { return new Rectangle(0, 0, _, _); } }
Rectangle TopRight { get { return new Rectangle(this.ClientSize.Width - _, 0, _, _); } }
Rectangle BottomLeft { get { return new Rectangle(0, this.ClientSize.Height - _, _, _); } }
Rectangle BottomRight { get { return new Rectangle(this.ClientSize.Width - _, this.ClientSize.Height - _, _, _); } }
protected override void WndProc(ref Message message)
{
base.WndProc(ref message);
if (message.Msg == 0x84) // WM_NCHITTEST
{
var cursor = this.PointToClient(Cursor.Position);
if (TopLeft.Contains(cursor)) message.Result = (IntPtr)HTTOPLEFT;
else if (TopRight.Contains(cursor)) message.Result = (IntPtr)HTTOPRIGHT;
else if (BottomLeft.Contains(cursor)) message.Result = (IntPtr)HTBOTTOMLEFT;
else if (BottomRight.Contains(cursor)) message.Result = (IntPtr)HTBOTTOMRIGHT;
else if (Top.Contains(cursor)) message.Result = (IntPtr)HTTOP;
else if (Left.Contains(cursor)) message.Result = (IntPtr)HTLEFT;
else if (Right.Contains(cursor)) message.Result = (IntPtr)HTRIGHT;
else if (Bottom.Contains(cursor)) message.Result = (IntPtr)HTBOTTOM;
}
}
}
}
如果您需要更多详细信息,可以在此处下载源代码:https://github.com/RndmDud/FormBaseWindow
答案 0 :(得分:2)
您可以增加表格填充(将其设置为ex:2,2,2,2) 请检查:(Can't resize a borderless winform from top because of a docked panel)
编辑:
与@Outman建议更改边框颜色的链接相同:
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e); //comment this out to prevent default painting
using (SolidBrush brush = new SolidBrush(Color.FromArgb(45, 45, 48))) //any color you like }
{
e.Graphics.FillRectangle(brush, e.ClipRectangle);
}
}
答案 1 :(得分:0)
我认为您的程序没有边界。你能把你的项目寄给我吗?