幾個小時以來,我一直在搞亂無邊界表單,我已經能夠從中獲得我需要的所有功能。唯一困擾我的是當從頂部、左上角或左側調整大小時,表單會在另一側閃爍。組件也會,但我想出了如何處理這個問題。現在我專注于嘗試讓閃爍停止,同時保持無邊界表單完全無邊界。我知道問題源于繪制移動距離然后重新繪制大小(反之亦然)的表格,但我無法讓它停止。
我嘗試了幾種不同的方法來調整表單的大小,從使用 PInvoke WndProc 方法到僅設定表單的位置和大小,再到在更改位置和大小時嘗試鎖定表單。除非我使用相當大的表格,否則似乎沒有什么能擺脫這種閃爍。我可以隱藏大部分相當大的表單,但標題欄仍然有幾個像素。我在搜索時發現的每種方法都產生了相同的結果。
這是我目前用來從我的主表單繼承的內容:
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;
}
}
uj5u.com熱心網友回復:
呵呵,感覺自己很傻。
我能夠通過以下方式停止閃爍......
我切換到 WndProc 以調整大小和拖動,如我上面的編輯
我使用 FixedSingle 而不是 None 作為表單邊框樣式。從技術上講,它不是一個無邊框視窗,但是當將 Text 設定為空并將 ControlBox 設定為 false 時,它??具有我正在尋找的行為。
除了上面修改過的代碼,這是我的建構式現在的樣子:
public MainForm()
{
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.Text = string.Empty;
this.ControlBox = false;
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
}
正如您在這張圖片中看到的那樣,視窗的行為就像一個相當大的視窗,在對面的邊緣沒有跳躍或閃爍。

編輯:
我遇到的另一個問題是在任務欄和任務管理器中為視窗命名。我可以使用修改后的 CreateParams 吸氣劑來做到這一點。修改的部分是 cp.Style 值和 cp.Caption。該cp.Style &= ~0xC00000線隱藏標題欄,cp.Style |= 0x00800000顯示使用此方法時防止閃爍所必需的細線邊框,cp.Caption = "TEST"然后在任務欄和任務管理器中設定標題。
protected override CreateParams CreateParams
{
get
{
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
// Extend the CreateParams property of the Button class.
var cp = base.CreateParams;
// Update the button Style.
cp.Style &= ~0xC00000; //WS_CAPTION;
cp.Style |= 0x00800000;
cp.ExStyle |= 0x02000000;
cp.Caption = "TEST";
return cp;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/528328.html
標籤:C#表格无边界
