我正在创建一个Windows窗体应用程序项目,其中我想要一个自定义边框和我自己设计的三个按钮(关闭,最小化和最大化)。我不知道该怎么做,我甚至不确定它是否可行。但如果有可能请告诉我解决方案。感谢
答案 0 :(得分:22)
是的,没有额外的库就可以。
首先,隐藏窗口的原始边框。
public Form1()
{
InitializeComponent();
FormBorderStyle = FormBorderStyle.None;
}
接下来,使用您的三个按钮创建一个面板或任何您想要的面板(我知道它很难看,用于演示目的):
然后,使用WindowState
:
private void minimizeButton_Click(object sender, System.EventArgs e)
{
WindowState = FormWindowState.Minimized;
}
private void maximizeButton_Click(object sender, System.EventArgs e)
{
WindowState = FormWindowState.Maximized;
}
private void closeButton_Click(object sender, System.EventArgs e)
{
Close();
}
最后,使用我们的面板使表单可拖动。在课程级别添加:
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HTCAPTION = 0x2;
[DllImport("User32.dll")]
public static extern bool ReleaseCapture();
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
并将它们插入面板的MouseDown事件中:
private void OnMouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
}
}
现在你有一个可拖动的表格,顶部有你自己的栏。
如果您希望它可以调整大小,正如@PhilWright所提到的那样,您可以捕获来自WM_NCHITTEST
的{{1}}消息并返回WndProc
以触发调整大小:
HTBOTTOMRIGHT
正如@BenVoigt所提到的,您可以使用按钮/面板上的protected override void WndProc(ref Message m)
{
if (m.Msg == 0x84)
{
const int resizeArea = 10;
Point cursorPosition = PointToClient(new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16));
if (cursorPosition.X >= ClientSize.Width - resizeArea && cursorPosition.Y >= ClientSize.Height - resizeArea )
{
m.Result = (IntPtr)17;
return;
}
}
base.WndProc(ref m);
}
和Dock
属性,以便他们可以正确调整大小。如果你没有,他们将不会在调整大小时遵循表格。
答案 1 :(得分:2)
只需完成 @ Pierre-Luc 的有用解决方案。当窗口最大化时,如果我们再次单击最大化按钮,如何将其调整到正常位置。这是代码:
private static bool MAXIMIZED = false;
private void maximizeButton_Click(object sender, System.EventArgs e)
{
if(MAXIMIZED)
{
WindowState = FormWindowState.Normal;
MAXIMIZED = false;
}
else
{
WindowState = FormWindowState.Maximized;
MAXIMIZED = true;
}
}
编辑:正如@LarsTech在评论
中所建议的那样private void maximizeButton_Click(object sender, System.EventArgs e)
{
if (this.WindowState != FormWindowState.Maximized)
this.WindowState = FormWindowState.Maximized;
else
this.WindowState = FormWindowState.Normal;
}
答案 2 :(得分:1)
@Pierre_Luc未涵盖的小细节。 如果您在该面板上添加任何控件,例如标题或图标,单击这些控件时将无法拖动该窗体。为此,我发现将相同的事件处理程序添加到窗体的加载事件中的所有控件(从“最小化”,“最大化”和“关闭”按钮中除外)控件很方便。
private void Form1_Load(object sender, EventArgs e)
{
foreach (Control Control in this.HeaderPanel.Controls)
{
if (!(Control is Button)) //Change here depending on the Library you use for your contols
{
Control.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnMouseDown);
}
}
}
Morevoer,这是 WndProc 的完整版本,可在各个方向(左,右,下)调整大小。
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x84)
{
const int resizeArea = 10;
Point cursorPosition = PointToClient(new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16));
if (cursorPosition.X >= ClientSize.Width - resizeArea && cursorPosition.Y >= ClientSize.Height - resizeArea)
{
m.Result = (IntPtr)17; //HTBOTTOMRIGHT
return;
}
else if (cursorPosition.X <= resizeArea && cursorPosition.Y >= ClientSize.Height - resizeArea)
{
m.Result = (IntPtr)16; //HTBOTTOMLEFT
return;
}
else if (cursorPosition.X <= resizeArea)
{
m.Result = (IntPtr)10; //HTLEFT
return;
}
else if (cursorPosition.X >= ClientSize.Width - resizeArea)
{
m.Result = (IntPtr)11; //HTRIGHT
return;
}
else if (cursorPosition.Y >= ClientSize.Height - resizeArea)
{
m.Result = (IntPtr)15; //HTBOTTOM
return;
}
}
base.WndProc(ref m);
}
答案 3 :(得分:0)
我知道它很旧,但希望它可以帮助某人...
不要使用“最大化”,而是使用“工作区”,否则它会覆盖任务栏。
有一个全局布尔值:private static bool trip = false;
然后在您的函数中:
if (trip == false)
{
Left = Top = 0;
Width = Screen.PrimaryScreen.WorkingArea.Width;
Height = Screen.PrimaryScreen.WorkingArea.Height;
trip = true;
}
else if (trip == true)
{
Width = 1535; // my original form size
Height = 937; // my original form size
this.Left = leftPOS; // POS are filled on form load for current positions
this.Top = topPOS;
trip = false;
}
没有trip bool,再次按下最大化按钮后,我无法将表单恢复到正常大小。
答案 4 :(得分:-2)
这当然是可能的,但不适合初学者。主要组件供应商,如Infragistics,DevExpress,ComponentOne,SyncFusion等,都有可以自定义表单外观的库。