StickyNote开发笔记4

@adens 11/28/2016 8:06:21 AM

WinForm FormBorderStyle设置为None后鼠标拖动改变大小

在开发便签软件时,便签上的大边框带有最小化最大化关闭的按钮给便签带来了不可控制的意外操作,于是将FormBorderStyle设置为none后,WinForm自带的大边框就不见了。

但是,就出了问题了,便签的大小不能通过拖动Form边缘进行放大缩小了,所以就有了以下代码解决问题:

private const int
         HTLEFT = 10,
         HTRIGHT = 11,
         HTTOP = 12,
         HTTOPLEFT = 13,
         HTTOPRIGHT = 14,
         HTBOTTOM = 15,
         HTBOTTOMLEFT = 16,
         HTBOTTOMRIGHT = 17;

     const int Bound = 10; // you can rename this variable if you like

     Rectangle Top { get { return new Rectangle(0, 0, this.ClientSize.Width, Bound); } }
     Rectangle Left { get { return new Rectangle(0, 0, Bound, this.ClientSize.Height); } }
     Rectangle Bottom { get { return new Rectangle(0, this.ClientSize.Height - Bound, this.ClientSize.Width, Bound); } }
     Rectangle Right { get { return new Rectangle(this.ClientSize.Width - Bound, 0, Bound, this.ClientSize.Height); } }

     Rectangle TopLeft { get { return new Rectangle(0, 0, Bound, Bound); } }
     Rectangle TopRight { get { return new Rectangle(this.ClientSize.Width - Bound, 0, Bound, Bound); } }
     Rectangle BottomLeft { get { return new Rectangle(0, this.ClientSize.Height - Bound, Bound, Bound); } }
     Rectangle BottomRight { get { return new Rectangle(this.ClientSize.Width - Bound, this.ClientSize.Height - Bound, Bound, Bound); } }


     protected override void WndProc(ref Message message)
     {
         base.WndProc(ref message);

         if (message.Msg == 0x84) // WM_NCHITTEST
         {
             var cursor = this.PointToClient(Cursor.Position);

             if (TopLeft.Contains(cursor)) message.Result = (IntPtr)HTTOPLEFT;
             else if (TopRight.Contains(cursor)) message.Result = (IntPtr)HTTOPRIGHT;
             else if (BottomLeft.Contains(cursor)) message.Result = (IntPtr)HTBOTTOMLEFT;
             else if (BottomRight.Contains(cursor)) message.Result = (IntPtr)HTBOTTOMRIGHT;

             else if (Top.Contains(cursor)) message.Result = (IntPtr)HTTOP;
             else if (Left.Contains(cursor)) message.Result = (IntPtr)HTLEFT;
             else if (Right.Contains(cursor)) message.Result = (IntPtr)HTRIGHT;
             else if (Bottom.Contains(cursor)) message.Result = (IntPtr)HTBOTTOM;
         }
     }

解决办法来自stackoverflow

代码很容易就解决了无边框的Form的拖动边缘的放大缩小,但是Form内的控件不是随着Form的变化而变化的。于是就有了以下解决方案。

1.在Form1.Designer.cs里找到添加Form1.SizeChanged的委托事件

this.SizeChanged += new System.EventHandler(this.ResizeAll);

2.在Form1.cs里添加ResizeAll事件

	private void ResizeAll(object sender, EventArgs e)
 	{
         //获取Form1的所有子控件
		//计算每个子控件与Form1的长宽比,得出新的子控件的Size赋值给该控件
     }

以上方法做的非常吃力不讨好,控件的长宽都是int类型,在计算的时候存在损失精度的问题,多次缩放之后 比例就已经完全变了。有可能某些控件作为定长控件还要加以区分。所以该方法非常不好用。

在查看属性的时候看到了Anchor锚点属性,有了更好的解决办法。

1.将需要窗口大小改变的控件的Anchor属性设置为:Top, Bottom, Left, Right;就可以了。

anchor

这样一来随着窗口大小的改变,子控件就会根据锚点重新计算大小和位置。自动完成缩放,美滋滋。

Last Modification : 11/28/2016 8:06:21 AM


In This Document