C# 无边框窗体的移动,任务栏右键菜单,调整大小

本文详细介绍了如何实现无边框窗体的各种功能,包括自定义最大化、最小化及关闭按钮,通过不同方法实现窗体拖动,添加任务栏右键菜单,调整窗体大小,以及解决最大化后的全屏问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近做了一个无边框的主窗体界面,过程中遇到了很多问题,解决的过程也费了不少精力,因此做完了之后就想把过程写下来,留个纪念,也给遇到同样问题的网友一点帮助。由于没有了边框,所以最大化、最小化、关闭等按钮都没有了,也不能拖动窗体了,任务栏没有右键菜单了,不能调整大小了,设置全屏的时候填满了整个屏幕,把任务栏都给遮盖了,这些都是遇到的问题,下面对每个问题逐一解决:

1、最大化、最小化、关闭按钮,这三个按钮只要拖三个普通的按钮上去就可以了,当然,需要把背景图片设置好,以达到看上去漂亮的结果,这个没什么可说的,就很简单的三个按钮,对应的事件中分别设置窗体的windowstate为最大化,最小化,和关闭就可以了。

 

2、拖动窗体,这个方法很多,主要有两种,一种是使用windows api,另一种是自己添加mousemove事件,下面分别是两种方法的介绍:

第一种方法:

在窗体类中加入如下代码:

  1. using System.Runtime.InteropServices;   
  2.   
  3.     [DllImport("user32.dll")]   
  4.     public static extern bool ReleaseCapture();   
  5.     [DllImport("user32.dll")]   
  6.     public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);   
  7.     public const int WM_SYSCOMMAND = 0x0112;   
  8.     public const int SC_MOVE = 0xF010;   
  9.     public const int HTCAPTION = 0x0002;   
using System.Runtime.InteropServices; 

    [DllImport("user32.dll")] 
    public static extern bool ReleaseCapture(); 
    [DllImport("user32.dll")] 
    public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam); 
    public const int WM_SYSCOMMAND = 0x0112; 
    public const int SC_MOVE = 0xF010; 
    public const int HTCAPTION = 0x0002; 

然后,在窗体的MouseDown事件中加入以下两句:

    ReleaseCapture();
    SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
就搞定了。

第二种方法:

窗体类中添加两个变量:

  Point mouseOff;

 bool leftFlag;

在窗体的MouseDown、MouseUp、MouseMove 事件中分别加入如下代码:

//MouseDown

  1. if (e.Button == MouseButtons.Left)  
  2. {  
  3.     mouseOff = new Point(-e.X, -e.Y);   
  4.   
  5.     leftFlag = true;  
  6.   
  7. }  
            if (e.Button == MouseButtons.Left)
            {
                mouseOff = new Point(-e.X, -e.Y); 

                leftFlag = true;

            }

 //MouseUp

  1. if (leftFlag)  
  2. {  
  3.     leftFlag = false;  
  4.   
  5. }  
            if (leftFlag)
            {
                leftFlag = false;

            }

//MouseMove

  1. if (leftFlag)  
  2. {  
  3.     Point mouseSet = System.Windows.Forms.Control.MousePosition;  
  4.     mouseSet.Offset(mouseOff.X, mouseOff.Y);    
  5.   
  6.     Location = mouseSet;  
  7. }  
            if (leftFlag)
            {
                Point mouseSet = System.Windows.Forms.Control.MousePosition;
                mouseSet.Offset(mouseOff.X, mouseOff.Y);  

                Location = mouseSet;
            }

3、添加任务栏右键菜单

在窗体类中加入如下代码:

  1. [DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)]  
  2. public static extern int GetWindowLong(HandleRef hWnd, int nIndex);  
  3.   
  4. [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]  
  5. public static extern IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong);  
        [DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)]
        public static extern int GetWindowLong(HandleRef hWnd, int nIndex);

        [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
        public static extern IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong);

然后在构造函数或者窗体Load事件中加入下面三句代码:

  1. int WS_SYSMENU = 0x00080000;  
  2. int windowLong = (GetWindowLong(new HandleRef(thisthis.Handle), -16));  
  3. SetWindowLong(new HandleRef(thisthis.Handle), -16, windowLong | WS_SYSMENU);  
            int WS_SYSMENU = 0x00080000;
            int windowLong = (GetWindowLong(new HandleRef(this, this.Handle), -16));
            SetWindowLong(new HandleRef(this, this.Handle), -16, windowLong | WS_SYSMENU);


4、 调整窗体大小

在网上看到一种方案,是在窗体类中加入如下代码(源自:http://blog.sina.com.cn/s/blog_7010d0100100lqpu.html

  1. #region 控制改变窗体大小   
  2.   
  3.         const int WM_NCHITTEST = 0x0084;  
  4.        const int HTLEFT = 10;    //左边界   
  5.         const int HTRIGHT = 11;   //右边界   
  6.         const int HTTOP = 12; //上边界   
  7.         const int HTTOPLEFT = 13; //左上角   
  8.         const int HTTOPRIGHT = 14;    //右上角   
  9.         const int HTBOTTOM = 15;  //下边界   
  10.         const int HTBOTTOMLEFT = 0x10;    //左下角   
  11.         const int HTBOTTOMRIGHT = 17; //右下角   
  12.   
  13.         protected override void WndProc(ref Message m)  
  14.         {  
  15.                 base.WndProc(ref m);  
  16.                 switch (m.Msg)  
  17.                 {  
  18.                     case WM_NCHITTEST:  
  19.                         {  
  20.                             Point vPoint = new Point((int)m.LParam & 0xFFFF,  
  21.                                 (int)m.LParam >> 16 & 0xFFFF);  
  22.                             vPoint = PointToClient(vPoint);  
  23.                             //判断:仅当当前窗体状态不是最大化时,相关鼠标事件生效   
  24.                             if (this.WindowState != FormWindowState.Maximized)  
  25.                             {  
  26.                                 if (vPoint.X <= 5)  
  27.                                 {  
  28.                                     if (vPoint.Y <= 5)  
  29.                                     {  
  30.                                         m.Result = (IntPtr)HTTOPLEFT;  
  31.                                     }  
  32.                                     else if (vPoint.Y >= ClientSize.Height - 5)  
  33.                                     {  
  34.                                         m.Result = (IntPtr)HTBOTTOMLEFT;  
  35.                                     }  
  36.                                     else  
  37.                                     {  
  38.                                         m.Result = (IntPtr)HTLEFT;  
  39.                                     }  
  40.                                 }  
  41.                                 else if (vPoint.X >= ClientSize.Width - 5)  
  42.                                 {  
  43.                                     if (vPoint.Y <= 5)  
  44.                                     {  
  45.                                         m.Result = (IntPtr)HTTOPRIGHT;  
  46.                                     }  
  47.                                     else if (vPoint.Y >= ClientSize.Height - 5)  
  48.                                     {  
  49.                                         m.Result = (IntPtr)HTBOTTOMRIGHT;  
  50.                                     }  
  51.                                     else  
  52.                                     {  
  53.                                         m.Result = (IntPtr)HTRIGHT;  
  54.                                     }  
  55.                                 }  
  56.                                 else if (vPoint.Y <= 5)  
  57.                                 {  
  58.                                     m.Result = (IntPtr)HTTOP;  
  59.                                 }  
  60.                                 else if (vPoint.Y >= ClientSize.Height - 5)  
  61.                                 {  
  62.                                     m.Result = (IntPtr)HTBOTTOM;  
  63.                                 }  
  64.   
  65.                             }  
  66.                             break;  
  67.                         }  
  68.                 }  
  69.         }  
  70.         #endregion  
#region 控制改变窗体大小

        const int WM_NCHITTEST = 0x0084;
       const int HTLEFT = 10;    //左边界
        const int HTRIGHT = 11;   //右边界
        const int HTTOP = 12; //上边界
        const int HTTOPLEFT = 13; //左上角
        const int HTTOPRIGHT = 14;    //右上角
        const int HTBOTTOM = 15;  //下边界
        const int HTBOTTOMLEFT = 0x10;    //左下角
        const int HTBOTTOMRIGHT = 17; //右下角

        protected override void WndProc(ref Message m)
        {
                base.WndProc(ref m);
                switch (m.Msg)
                {
                    case WM_NCHITTEST:
                        {
                            Point vPoint = new Point((int)m.LParam & 0xFFFF,
                                (int)m.LParam >> 16 & 0xFFFF);
                            vPoint = PointToClient(vPoint);
                            //判断:仅当当前窗体状态不是最大化时,相关鼠标事件生效
                            if (this.WindowState != FormWindowState.Maximized)
                            {
                                if (vPoint.X <= 5)
                                {
                                    if (vPoint.Y <= 5)
                                    {
                                        m.Result = (IntPtr)HTTOPLEFT;
                                    }
                                    else if (vPoint.Y >= ClientSize.Height - 5)
                                    {
                                        m.Result = (IntPtr)HTBOTTOMLEFT;
                                    }
                                    else
                                    {
                                        m.Result = (IntPtr)HTLEFT;
                                    }
                                }
                                else if (vPoint.X >= ClientSize.Width - 5)
                                {
                                    if (vPoint.Y <= 5)
                                    {
                                        m.Result = (IntPtr)HTTOPRIGHT;
                                    }
                                    else if (vPoint.Y >= ClientSize.Height - 5)
                                    {
                                        m.Result = (IntPtr)HTBOTTOMRIGHT;
                                    }
                                    else
                                    {
                                        m.Result = (IntPtr)HTRIGHT;
                                    }
                                }
                                else if (vPoint.Y <= 5)
                                {
                                    m.Result = (IntPtr)HTTOP;
                                }
                                else if (vPoint.Y >= ClientSize.Height - 5)
                                {
                                    m.Result = (IntPtr)HTBOTTOM;
                                }

                            }
                            break;
                        }
                }
        }
        #endregion

经实验,在不加入SetWindowLong(new HandleRef(this, this.Handle), -16, windowLong | WS_SYSMENU);这句代码的时候是可用的,但是加上这句,上面的代码就无效了,也就说用前面的方法加上了任务栏右键菜单后使用上述代码不能够起到调整大小的作用了,于是,搜集其他解决方案,在MSDN论坛上看到一个外国网友的解决方法不错,就是拖一个panel放到窗体的右下角,让这个panel很小,设置panel的Cursor为SizeNWSE,然后在这个panel 的MouseMove事件中加入一下代码:

  1. if (e.Button == MouseButtons.Left)  
  2. {  
  3.   
  4.     this.Size = new Size(this.PointToClient(MousePosition).X, this.PointToClient(MousePosition).Y);  
  5.   
  6. }  
            if (e.Button == MouseButtons.Left)
            {

                this.Size = new Size(this.PointToClient(MousePosition).X, this.PointToClient(MousePosition).Y);

            }


这样就实现了类似的拖动效果,只不过在右下角有拖动的标志。

5、解决最大化后铺满全屏的问题

在构造函数中加入以下代码:

  1. this.MaximizedBounds = Screen.PrimaryScreen.WorkingArea;  
  2.            
 this.MaximizedBounds = Screen.PrimaryScreen.WorkingArea;
          

 

转自:http://blog.youkuaiyun.com/agoodchild/article/details/6697131#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值