zl程序教程

您现在的位置是:首页 >  后端

当前栏目

winform无边框和标题栏窗体变化、移动实现

Winform 实现 移动 变化 窗体 边框 标题栏
2023-09-14 09:16:29 时间

窗体的最大化、最小化、还原

 winform窗体在无边框和标题栏的情况下,实现最大化会将任务栏遮挡,防止这种情况也很简单:

  • 只需在窗体初始化的时候加上下面短短的代码即可
MaximumSize = new Size(Screen.PrimaryScreen.WorkingArea.Width + 10, Screen.PrimaryScreen.WorkingArea.Height + 1);

WindowState属性控制窗体的形态
在这里插入图片描述
窗体最大化及还原:

 WindowState = WindowState == FormWindowState.Maximized ? FormWindowState.Normal : FormWindowState.Maximized;

最小化同理

重写窗体,使窗体可以不通过自带标题栏实现移动

  • 首先必须了解Windows的消息传递机制,当有鼠标活动消息时,
  • 系统发送WM_NCHITTEST 消息给窗体作为判断消息发生地的根据。 nchittest
  • 假如你点击的是标题栏,窗体收到的消息值就是 HTCAPTION ,
  • 同样地,若接受到的消息是 HTCLIENT,说明用户点击的是客户区,也就是鼠标消息发生在客户区。
private const int WM_NCHITTEST = 0x84;
private const int HTCLIENT = 0x1;
private const int HTCAPTION = 0x2;
  • 当重载窗体的 WndProc 方法时,可以截获 WM_NCHITTEST 消息并改些该消息,
  • 当判断鼠标事件发生在客户区时,改写改消息,发送 HTCAPTION 给窗体,
  • 这样,窗体收到的消息就时 HTCAPTION ,在客户区通过鼠标来拖动窗体就如同通过标题栏来拖动一样。
    注意:当你重载 WndProc 并改写鼠标事件后,整个窗体的鼠标事件也就随之改变了
protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case WM_NCHITTEST:
            base.WndProc(ref m);
            if ((int)m.Result == HTCLIENT)
                m.Result = (IntPtr)HTCAPTION;
            return;
    }
    base.WndProc(ref m);
}

panel容器控件移动窗口

  • 利用控件的鼠标按下离开两个事件即可
  • 原理便是重绘
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
    downPoint = new Point(e.X, e.Y);
}

private void panel1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        Location = new Point(Location.X + e.X - downPoint.X,
            Location.Y + e.Y - downPoint.Y);
    }
}

关闭窗体的几种实现和利弊

  • 1.this.Close(); 只是关闭当前窗口,若不是主窗体的话,是无法退出程序的,另外若有托管线程(非主线程),也无法干净地退出
  • 2.Application.Exit(); 强制所有消息中止,退出所有的窗体,但是若有托管线程(非主线程),也无法干净地退出
  • 3.Application.ExitThread(); 强制中止调用线程上的所有消息,同样面临其它线程无法正确退出的问题
  • 4.System.Environment.Exit(0); 这是最彻底的退出方式,不管什么线程都被强制退出,把程序结束的很干净