我花了几个小时在无边框表单上,我已经能够从它那里得到我需要的所有功能。唯一困扰我的是当从顶部、左上角或者离开,窗体会在对面闪烁。组件也会闪烁,但我想出了如何处理这个问题。现在我我专注于试图让闪烁停止,同时保持无边框形式完全无边框。我知道这个问题源于形式绘制移动的距离,然后重新绘制大小(或反之亦然),但我不能让它停止。
我尝试了几种不同的方法来调整窗体大小,从使用PInvokeWndProc方法到只设置窗体的位置当我改变位置和大小时试图锁定窗体。似乎没有什么能消除这种闪烁,除非我使用的是一个相当大的窗体。我可以隐藏大部分相当大的窗体,但仍然有几个像素的标题栏离开。我在搜索时发现的每一种方法都产生了相同的结果。
以下是我目前在Main Form上用来继承的内容:
using System.Drawing;
using System.Windows.Forms;
namespace TestBorderlessModernGUI
{
/// <summary>
/// Inherit from EdgeDrag in the main form
/// </summary>
public class EdgeDrag : Form
{
protected bool isDragging = false;
protected bool canDrag = false;
protected Rectangle lastRectangle = new Rectangle();
public EdgeDrag()
{
}
/// <summary>
/// Call after component Initialization in the Main Form
/// </summary>
protected void InitialiseFormEdge()
{
int resizeWidth = 2;
this.MouseDown += new MouseEventHandler(form_MouseDown);
this.MouseMove += new MouseEventHandler(form_MouseMove);
this.MouseUp += new MouseEventHandler(form_MouseUp);
// bottom
UserControl uc1 = new UserControl()
{
Anchor = (AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right),
Height = resizeWidth,
Width = this.DisplayRectangle.Width - (resizeWidth * 2),
Left = resizeWidth,
Top = this.DisplayRectangle.Height - resizeWidth,
BackColor = Color.Transparent,
Cursor = Cursors.SizeNS
};
uc1.MouseDown += form_MouseDown;
uc1.MouseUp += form_MouseUp;
uc1.MouseMove += delegate (object sender, MouseEventArgs e)
{
if (isDragging)
{
this.Size = new Size(lastRectangle.Width, e.Y - lastRectangle.Y + this.Height);
}
};
uc1.BringToFront();
this.Controls.Add(uc1);
this.Controls.SetChildIndex(uc1, 0);
// right
UserControl uc2 = new UserControl()
{
Anchor = (AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom),
Height = this.DisplayRectangle.Height - (resizeWidth * 2),
Width = resizeWidth,
Left = this.DisplayRectangle.Width - resizeWidth,
Top = resizeWidth,
BackColor = Color.Transparent,
Cursor = Cursors.SizeWE
};
uc2.MouseDown += form_MouseDown;
uc2.MouseUp += form_MouseUp;
uc2.MouseMove += delegate (object sender, MouseEventArgs e)
{
if (isDragging)
{
this.Size = new Size(e.X - lastRectangle.X + this.Width, lastRectangle.Height);
}
};
uc2.BringToFront();
this.Controls.Add(uc2);
this.Controls.SetChildIndex(uc2, 0);
// bottom-right
UserControl uc3 = new UserControl()
{
Anchor = (AnchorStyles.Bottom | AnchorStyles.Right),
Height = resizeWidth,
Width = resizeWidth,
Left = this.DisplayRectangle.Width - resizeWidth,
Top = this.DisplayRectangle.Height - resizeWidth,
BackColor = Color.Transparent,
Cursor = Cursors.SizeNWSE
};
uc3.MouseDown += form_MouseDown;
uc3.MouseUp += form_MouseUp;
uc3.MouseMove += delegate (object sender, MouseEventArgs e)
{
if (isDragging)
{
this.Size = new Size((e.X - lastRectangle.X + this.Width), (e.Y - lastRectangle.Y + this.Height));
}
};
uc3.BringToFront();
this.Controls.Add(uc3);
this.Controls.SetChildIndex(uc3, 0);
// top-right
UserControl uc4 = new UserControl()
{
Anchor = (AnchorStyles.Top | AnchorStyles.Right),
Height = resizeWidth,
Width = resizeWidth,
Left = this.DisplayRectangle.Width - resizeWidth,
Top = 0,
BackColor = Color.Transparent,
Cursor = Cursors.SizeNESW
};
uc4.MouseDown += form_MouseDown;
uc4.MouseUp += form_MouseUp;
uc4.MouseMove += delegate (object sender, MouseEventArgs e)
{
if (isDragging)
{
int diff = (e.Location.Y - lastRectangle.Y);
int y = (this.Location.Y + diff);
this.Location = new Point(this.Location.X, y);
this.Size = new Size(e.X - lastRectangle.X + this.Width, (this.Height + (diff * -1)));
}
};
uc4.BringToFront();
//uc4.BackColor = Color.Firebrick;
this.Controls.Add(uc4);
this.Controls.SetChildIndex(uc4, 0);
// top
UserControl uc5 = new UserControl()
{
Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right),
Height = resizeWidth,
Width = this.DisplayRectangle.Width - (resizeWidth * 2),
Left = resizeWidth,
Top = 0,
BackColor = Color.Transparent,
Cursor = Cursors.SizeNS
};
uc5.MouseDown += form_MouseDown;
uc5.MouseUp += form_MouseUp;
uc5.MouseMove += delegate (object sender, MouseEventArgs e)
{
if (isDragging)
{
int diff = (e.Location.Y - lastRectangle.Y);
int y = (this.Location.Y + diff);
this.Location = new Point(this.Location.X, y);
this.Size = new Size(lastRectangle.Width, (this.Height + (diff * -1)));
}
};
uc5.BringToFront();
this.Controls.Add(uc5);
this.Controls.SetChildIndex(uc5, 0);
// left
UserControl uc6 = new UserControl()
{
Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom),
Height = this.DisplayRectangle.Height - (resizeWidth * 2),
Width = resizeWidth,
Left = 0,
Top = resizeWidth,
BackColor = Color.Transparent,
Cursor = Cursors.SizeWE
};
uc6.MouseDown += form_MouseDown;
uc6.MouseUp += form_MouseUp;
uc6.MouseMove += delegate (object sender, MouseEventArgs e)
{
if (isDragging)
{
int diff = (e.Location.X - lastRectangle.X);
int x = (this.Location.X + diff);
this.Location = new Point(x, this.Location.Y);
this.Size = new Size((this.Width + (diff * -1)), this.Height);
}
};
uc6.BringToFront();
this.Controls.Add(uc6);
this.Controls.SetChildIndex(uc6, 0);
// bottom-left
UserControl uc7 = new UserControl()
{
Anchor = (AnchorStyles.Bottom | AnchorStyles.Left),
Height = resizeWidth,
Width = resizeWidth,
Left = 0,
Top = this.DisplayRectangle.Height - resizeWidth,
BackColor = Color.Transparent,
Cursor = Cursors.SizeNESW
};
uc7.MouseDown += form_MouseDown;
uc7.MouseUp += form_MouseUp;
uc7.MouseMove += delegate (object sender, MouseEventArgs e)
{
if (isDragging)
{
int diff = (e.Location.X - lastRectangle.X);
int x = (this.Location.X + diff);
this.Location = new Point(x, this.Location.Y);
this.Size = new Size((this.Width + (diff * -1)), (e.Y - lastRectangle.Y + this.Height));
}
};
uc7.BringToFront();
this.Controls.Add(uc7);
this.Controls.SetChildIndex(uc7, 0);
// bottom-left
UserControl uc8 = new UserControl()
{
Anchor = (AnchorStyles.Top | AnchorStyles.Left),
Height = resizeWidth,
Width = resizeWidth,
Left = 0,
Top = 0,
BackColor = Color.Transparent,
Cursor = Cursors.SizeNWSE
};
uc8.MouseDown += form_MouseDown;
uc8.MouseUp += form_MouseUp;
uc8.MouseMove += delegate (object sender, MouseEventArgs e)
{
if (isDragging)
{
int dX = (e.Location.X - lastRectangle.X);
int dY = (e.Location.Y - lastRectangle.Y);
int x = (this.Location.X + dX);
int y = (this.Location.Y + dY);
this.Location = new Point(x, y);
this.Size = new Size((this.Width + (dX * -1)), (this.Height + (dY * -1)));
}
};
uc8.BringToFront();
this.Controls.Add(uc8);
this.Controls.SetChildIndex(uc8, 0);
}
private void form_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDragging = true;
lastRectangle = new Rectangle(e.Location.X, e.Location.Y, this.Width, this.Height);
// If the mouse is within the dragging area
if (e.Y <= 30 && e.X <= this.Size.Width - 120)
canDrag = true;
}
}
private void form_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
// If we can drag the form
if (canDrag)
{
int x = (this.Location.X + (e.Location.X - lastRectangle.X));
int y = (this.Location.Y + (e.Location.Y - lastRectangle.Y));
this.Location = new Point(x, y);
}
}
}
private void form_MouseUp(object sender, MouseEventArgs e)
{
if (isDragging)
isDragging = false;
if (canDrag)
canDrag = false;
}
}
}
有没有人知道一种方法来摆脱闪烁的无边界的形式边缘,使它类似于大小相当的形式?
**编辑:**我已经修改了代码,使用WndProc来调整大小,就像Jimi说的那样,它仍然像其他代码一样闪烁。我开始认为停止闪烁的唯一方法是使用一个可调大小的窗体。有人有什么想法吗?
表单构造器:
public MainForm()
{
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.ResizeRedraw, true);
}
调整边缘大小代码:
private const int HTLEFT = 10,
HTRIGHT = 11,
HTTOP = 12,
HTTOPLEFT = 13,
HTTOPRIGHT = 14,
HTBOTTOM = 15,
HTBOTTOMLEFT = 16,
HTBOTTOMRIGHT = 17,
HTCAPTION = 2;
const int edgeSize = 3; // you can rename this variable if you like
Rectangle Top { get { return new Rectangle(0, 0, this.ClientSize.Width, edgeSize); } }
Rectangle Left { get { return new Rectangle(0, 0, edgeSize, this.ClientSize.Height); } }
Rectangle Bottom { get { return new Rectangle(0, this.ClientSize.Height - edgeSize, this.ClientSize.Width, edgeSize); } }
Rectangle Right { get { return new Rectangle(this.ClientSize.Width - edgeSize, 0, edgeSize, this.ClientSize.Height); } }
Rectangle TopLeft { get { return new Rectangle(0, 0, edgeSize, edgeSize); } }
Rectangle TopRight { get { return new Rectangle(this.ClientSize.Width - edgeSize, 0, edgeSize, edgeSize); } }
Rectangle BottomLeft { get { return new Rectangle(0, this.ClientSize.Height - edgeSize, edgeSize, edgeSize); } }
Rectangle BottomRight { get { return new Rectangle(this.ClientSize.Width - edgeSize, this.ClientSize.Height - edgeSize, edgeSize, edgeSize); } }
protected override CreateParams CreateParams { get { var cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; } }
protected override void OnPaint(PaintEventArgs e)
{
if (this.WindowState == FormWindowState.Normal)
{
Rectangle rc = new Rectangle(this.ClientSize.Width - cGrip, this.ClientSize.Height - cGrip, cGrip, cGrip);
ControlPaint.DrawSizeGrip(e.Graphics, this.BackColor, rc);
}
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == 0x84)
{ // Trap WM_NCHITTEST
var cursor = this.PointToClient(Cursor.Position);
if (TopLeft.Contains(cursor)) m.Result = (IntPtr)HTTOPLEFT;
else if (TopRight.Contains(cursor)) m.Result = (IntPtr)HTTOPRIGHT;
else if (BottomLeft.Contains(cursor)) m.Result = (IntPtr)HTBOTTOMLEFT;
else if (BottomRight.Contains(cursor)) m.Result = (IntPtr)HTBOTTOMRIGHT;
else if (Top.Contains(cursor)) m.Result = (IntPtr)HTTOP;
else if (Left.Contains(cursor)) m.Result = (IntPtr)HTLEFT;
else if (Right.Contains(cursor)) m.Result = (IntPtr)HTRIGHT;
else if (Bottom.Contains(cursor)) m.Result = (IntPtr)HTBOTTOM;
else if (cursor.Y < cCaption) m.Result = (IntPtr)HTCAPTION;
}
}
1条答案
按热度按时间csga3l581#
我觉得自己很蠢。
我可以用下面的方法让闪烁停止...
1.我切换到WndProc来调整大小和拖动,就像我上面的编辑一样
1.我正在使用FixedSingle而不是None作为窗体边框样式。从技术上讲,它不是一个无边框窗口,但当将Text设置为空并将ControlBox设置为false时,它具有我正在寻找的行为。
除了上面修改过的代码之外,我的构造函数现在看起来如下:
正如您在此图像中所看到的,窗口的行为就像可调整大小的窗口一样,在相对的边缘上没有跳跃或闪烁。
**编辑:**我遇到的另一个问题是在任务栏和任务管理器中给窗口命名。我可以用修改过的CreateParams getter来完成这个任务。修改的部分是cp.Style值和cp. Caption。
cp.Style &= ~0xC00000
行隐藏了标题栏,cp.Style |= 0x00800000
显示了一个细线边框,这是使用此方法时防止闪烁所必需的,cp.Caption = "TEST"
然后在任务栏和任务管理器中设置标题。