我正在为一个使用Windows窗体的应用程序做UI。在咨询了this question和这个窗体后,我做了一个可调整大小的无边框窗体。
我有一台多屏幕计算机。当我在主屏幕上最大化时,窗体正常地最大化。如果我将窗体完全移动到第二个屏幕,然后使用最大化,窗体消失。经过调查,我发现,即使第二个屏幕的属性'this.MaximizedBounds'正确地确定,即{X=-1440,Y = 0,Width =1440,Height=900},当我使用语句时,
this.WindowState = FormWindowState.Maximized;
字符串
窗体在{X=-2880,Y = 0,Width =1440,Height=900}处绘制,好像由于某种原因绘制方向被反转了?鉴于此,我知道我可以通过编程确定绘制窗体,但我想知道我是否缺少设置一些附加属性以确保绘制方向正确?
以编程方式最大化的窗体的问题是窗体的状态仍然是FormWindowState.Normal,我不能将其更改为FormWindowState.Maximized而不会导致在错误的位置重绘from
使表单无边界的代码
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
cp.ClassStyle |= 0x08;
return cp;
}
}
型
代码退出,最大化/恢复,最小化
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void button2_Click(object sender, EventArgs e)
{
if(this.WindowState==FormWindowState.Normal)
{
this.button2.Image = ((System.Drawing.Image)(Properties.Resources.Restore_Down));
this.MaximizedBounds = Screen.FromHandle(this.Handle).WorkingArea;
this.WindowState = FormWindowState.Maximized;
}
else if(this.WindowState == FormWindowState.Maximized)
{
this.WindowState = FormWindowState.Normal;
this.button2.Image = ((System.Drawing.Image)(Properties.Resources.Maximize));
}
}
private void button3_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
}
型
3条答案
按热度按时间rseugnpd1#
我的假设是,你正在创建一个无边框的表单,然后创建你自己的工具栏。这种最大化,最小化和恢复可以在没有
WndProc
的情况下实现。所有人都需要三个按钮和它们的点击事件处理程序,就像这样(它也可以在多个显示器上工作):字符串
要移动窗体,你需要使用
WndProc
。特别是处理WM_NCLBUTTONDOWN
windows消息。这应该在MouseDown
事件处理程序中完成。型
ReleaseCapture
和SendMessage
都是user32.dll
的一部分。要调整大小,您将再次需要使用WndProc。然而,由于您有2个显示器,您将需要自己获取屏幕坐标。以下接受的响应来自this问题。它可能会帮助您获得正确的坐标。
型
wtlkbnrh2#
为什么要使用WndProc来实现无边界?
Windows窗体具有“FormBorderStyle”属性,
字符串
这应该使它无边框,也许这种更默认的方法也解决了窗口位置的问题
hmmo2u0o3#
MaximizedBounds设置取决于窗体所在的屏幕,因此Left和Top必须为0或更大。