求大神啊~!烦死我啦~!C#实现窗体自动隐藏+Form圆角

博客园铁粉 2014-07-22 06:08:19

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Drawing.Drawing2D;

namespace AutoApp
{
public partial class Form1 : Form
{
[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;
int formwidth;
int formheight;
public Form1()
{
InitializeComponent();
}
private void form_toolStyle_MouseDown(object sender, MouseEventArgs e)
{
ReleaseCapture();
SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
}
private void form_toolStyle_MouseLeave(object sender, EventArgs e)
{
int nowx = Cursor.Position.X;
int nowy = Cursor.Position.Y;
if (nowx >= (this.Location.X + this.Width) | nowx <= this.Location.X | nowy <= this.Location.Y | nowy >= (this.Location.Y + this.Height))
{
if (this.Location.X == 0)
{
this.Width = 0;
}
if (this.Location.Y == 0)
{
this.Height = 0;
}
}
}
private void form_toolStyle_Move(object sender, EventArgs e)
{
formwidth = this.Width;
formheight = this.Height;
int x = this.Location.X;
int y = this.Location.Y;
if (x <= 0)
{
this.Location = new System.Drawing.Point(0, y);
this.Width = 0;
}
if (y <= 0)
{
this.Location = new System.Drawing.Point(x, 0);
this.Height = 0;
}
}
private void form_toolStyle_MouseEnter(object sender, EventArgs e)
{
this.Width = formwidth;
this.Height = formheight;
}
//public void SetWindowRegion()
//{
//GraphicsPath FormPath;
//FormPath = new System.Drawing.Drawing2D.GraphicsPath();
//Rectangle rect = new Rectangle(-1, -1, this.Width + 1, this.Height);
//FormPath = GetRoundedRectPath(rect, 25);
//this.Region = new Region(FormPath);
//}
//private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
//{
//int diameter = radius;
//Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
//GraphicsPath path = new GraphicsPath();
//path.AddArc(arcRect, 185, 90);
//arcRect.X = rect.Right - diameter;
//path.AddArc(arcRect, 275, 90);
//arcRect.Y = rect.Bottom - diameter;
//path.AddArc(arcRect, 356, 90);
//arcRect.X = rect.Left;
//path.AddArc(arcRect, 90, 90);
//path.CloseFigure();
//return path;
//}
//protected override void OnPaint(PaintEventArgs e)
//{
//base.OnPaint(e);
//SetWindowRegion();
//}
private void Form1_Load(object sender, EventArgs e)
{
this.FormBorderStyle = FormBorderStyle.None;
}
}
}

额,我知道代码有点多,不过这是全部的了。
不加注释的部分是实现把窗体拖到屏幕上边和右边可以自动隐藏;加注释的部分实现的是窗体边缘呈圆形。
问题是:现在两部分一起用的话,窗体可以变圆角,但是拖到屏幕上方时会有不同的效果。怎么能解决?
...全文
325 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
博客园铁粉 2014-07-24
  • 打赏
  • 举报
回复
引用 17 楼 save4me 的回复:
下面代码实现上边和左边靠边隐藏,我把处理Form宽高的提取到SetDimension();里面。你原来的代码中43和47行的逻辑应该和59和64行一样才对,不然每次都要刚好为0,这个是考验用户的精准度吗

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace AutoApp
{
	public partial class Form1 : Form
	{
		[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;
		
		int formwidth;
		int formheight;
		
		public Form1()
		{
			InitializeComponent();
			formwidth = this.Width;
			formheight = this.Height;
		}
		
		private void form_toolStyle_MouseDown(object sender, MouseEventArgs e)
		{
			ReleaseCapture();
			SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
		}
		
		private void form_toolStyle_MouseLeave(object sender, EventArgs e)
		{
			int nowx = Cursor.Position.X;
			int nowy = Cursor.Position.Y;
			
			if (nowx >= (this.Location.X + this.Width)
			    || nowx <= this.Location.X
			    || nowy <= this.Location.Y
			    || nowy >= (this.Location.Y + this.Height)
			   )
			{
				SetDimension();
			}
		}
		
		private void form_toolStyle_Move(object sender, EventArgs e)
		{
			SetDimension();
		}
		
		private void form_toolStyle_MouseEnter(object sender, EventArgs e)
		{
			this.Width = formwidth;
			this.Height = formheight;
			System.Diagnostics.Debug.Print(this.Location.X.ToString() + ":" + this.Location.Y.ToString());
		}
		
		private void SetDimension()
		{
			int x = this.Location.X;
			int y = this.Location.Y;
			if (x <= 0)
			{
				this.Location = new System.Drawing.Point(0, y);
				this.Width = 0;
			}
			if (y <= 0)
			{
				this.Location = new System.Drawing.Point(x, 0);
				this.Height = 0;
			}
		}
		
		public void SetWindowRegion()
		{
			GraphicsPath FormPath;
			FormPath = new System.Drawing.Drawing2D.GraphicsPath();
			Rectangle rect = new Rectangle(-1, -1, this.Width + 1, this.Height);
			FormPath = GetRoundedRectPath(rect, 25);
			this.Region = new Region(FormPath);
		}
		
		private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
		{
			int diameter = radius;
			Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
			GraphicsPath path = new GraphicsPath();
			path.AddArc(arcRect, 185, 90);
			arcRect.X = rect.Right - diameter;
			path.AddArc(arcRect, 275, 90);
			arcRect.Y = rect.Bottom - diameter;
			path.AddArc(arcRect, 356, 90);
			arcRect.X = rect.Left;
			path.AddArc(arcRect, 90, 90);
			path.CloseFigure();
			return path;
		}
		
		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint(e);
			SetWindowRegion();
		}
		
		private void Form1_Load(object sender, EventArgs e)
		{
			this.FormBorderStyle = FormBorderStyle.None;
		}
	}
}
引用 16 楼 h2041075 的回复:
按我开始上传的代码,不加注释的部分是可以实现自动缩出缩回屏幕边缘的(屏幕左、上边可以)。问题在于加了注释部分后,也就是窗体圆角之后,只能从屏幕右边缩回不能从上边缩回了。
爱你~!
於黾 2014-07-23
  • 打赏
  • 举报
回复
你不会在sizechanged事件里执行的重绘吧
博客园铁粉 2014-07-23
  • 打赏
  • 举报
回复
引用 11 楼 Z65443344 的回复:
而且你真的把高度设置成0,如何判断鼠标已经回到你的窗体上,从而应该显示出来了? 不会还要鼠标钩子去取坐标吧
额现在发现问题了,其实不是高度0什么的问题。而是我加了断电之后,发现已经执行了缩回部分后,又执行了一边重写的OnPaint,所以界面完整地又出现了...但是不知道为什么会又执行一次..
於黾 2014-07-23
  • 打赏
  • 举报
回复
而且你真的把高度设置成0,如何判断鼠标已经回到你的窗体上,从而应该显示出来了? 不会还要鼠标钩子去取坐标吧
於黾 2014-07-23
  • 打赏
  • 举报
回复
引用 8 楼 h2041075 的回复:
[quote=引用 7 楼 porenasckx 的回复:] 这应该是个动画效果
不算是动画吧,就是想让窗体变成圆角,然后当窗体拖到屏幕上边或者右边的时候可以像QQ那样自动缩回,然后鼠标再划过后能再出现。现在有点问题。[/quote] 那你也不用真的把宽高变成0吧. 向上缩进,宽度不变,高度应该留一点,QQ也是这样做的.否则你就找不到了,只能鼠标在屏幕上乱划拉. 其他方向同理.
欢乐的小猪 2014-07-23
  • 打赏
  • 举报
回复
你怎么不用wpf,实现不叫太简单。
博客园铁粉 2014-07-23
  • 打赏
  • 举报
回复
引用 7 楼 porenasckx 的回复:
这应该是个动画效果
不算是动画吧,就是想让窗体变成圆角,然后当窗体拖到屏幕上边或者右边的时候可以像QQ那样自动缩回,然后鼠标再划过后能再出现。现在有点问题。
E次奥 2014-07-23
  • 打赏
  • 举报
回复
这应该是个动画效果
博客园铁粉 2014-07-23
  • 打赏
  • 举报
回复
引用 3 楼 Z65443344 的回复:
同上,隐藏就好了啊 宽高变0,再圆角?不会出错?
应该是先圆角,再宽高为0。而且我不是做那种单纯的Hide隐藏,是像QQ那样的自动缩回似的隐藏
博客园铁粉 2014-07-23
  • 打赏
  • 举报
回复
引用 2 楼 kkkksunday 的回复:
变成宽高为零?为什么不隐藏呢?
不是单纯的隐藏,是像QQ那样自动缩回似的隐藏
博客园铁粉 2014-07-23
  • 打赏
  • 举报
回复
引用 1 楼 save4me 的回复:
在Form1初始化后,给formwidth和formheight赋初始值

        public Form1()
        {
            InitializeComponent();
            formwidth = this.Width;
            formheight = this.Height;
        }
不行额,还是没效果
於黾 2014-07-23
  • 打赏
  • 举报
回复
同上,隐藏就好了啊 宽高变0,再圆角?不会出错?
啊呀 2014-07-23
  • 打赏
  • 举报
回复
变成宽高为零?为什么不隐藏呢?
save4me 2014-07-23
  • 打赏
  • 举报
回复
下面代码实现上边和左边靠边隐藏,我把处理Form宽高的提取到SetDimension();里面。你原来的代码中43和47行的逻辑应该和59和64行一样才对,不然每次都要刚好为0,这个是考验用户的精准度吗

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace AutoApp
{
	public partial class Form1 : Form
	{
		[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;
		
		int formwidth;
		int formheight;
		
		public Form1()
		{
			InitializeComponent();
			formwidth = this.Width;
			formheight = this.Height;
		}
		
		private void form_toolStyle_MouseDown(object sender, MouseEventArgs e)
		{
			ReleaseCapture();
			SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
		}
		
		private void form_toolStyle_MouseLeave(object sender, EventArgs e)
		{
			int nowx = Cursor.Position.X;
			int nowy = Cursor.Position.Y;
			
			if (nowx >= (this.Location.X + this.Width)
			    || nowx <= this.Location.X
			    || nowy <= this.Location.Y
			    || nowy >= (this.Location.Y + this.Height)
			   )
			{
				SetDimension();
			}
		}
		
		private void form_toolStyle_Move(object sender, EventArgs e)
		{
			SetDimension();
		}
		
		private void form_toolStyle_MouseEnter(object sender, EventArgs e)
		{
			this.Width = formwidth;
			this.Height = formheight;
			System.Diagnostics.Debug.Print(this.Location.X.ToString() + ":" + this.Location.Y.ToString());
		}
		
		private void SetDimension()
		{
			int x = this.Location.X;
			int y = this.Location.Y;
			if (x <= 0)
			{
				this.Location = new System.Drawing.Point(0, y);
				this.Width = 0;
			}
			if (y <= 0)
			{
				this.Location = new System.Drawing.Point(x, 0);
				this.Height = 0;
			}
		}
		
		public void SetWindowRegion()
		{
			GraphicsPath FormPath;
			FormPath = new System.Drawing.Drawing2D.GraphicsPath();
			Rectangle rect = new Rectangle(-1, -1, this.Width + 1, this.Height);
			FormPath = GetRoundedRectPath(rect, 25);
			this.Region = new Region(FormPath);
		}
		
		private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
		{
			int diameter = radius;
			Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
			GraphicsPath path = new GraphicsPath();
			path.AddArc(arcRect, 185, 90);
			arcRect.X = rect.Right - diameter;
			path.AddArc(arcRect, 275, 90);
			arcRect.Y = rect.Bottom - diameter;
			path.AddArc(arcRect, 356, 90);
			arcRect.X = rect.Left;
			path.AddArc(arcRect, 90, 90);
			path.CloseFigure();
			return path;
		}
		
		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint(e);
			SetWindowRegion();
		}
		
		private void Form1_Load(object sender, EventArgs e)
		{
			this.FormBorderStyle = FormBorderStyle.None;
		}
	}
}
引用 16 楼 h2041075 的回复:
按我开始上传的代码,不加注释的部分是可以实现自动缩出缩回屏幕边缘的(屏幕左、上边可以)。问题在于加了注释部分后,也就是窗体圆角之后,只能从屏幕右边缩回不能从上边缩回了。
博客园铁粉 2014-07-23
  • 打赏
  • 举报
回复
引用 15 楼 save4me 的回复:
用你的代码,在我本机上加上我说明的两句后测试,窗口上边缘到达屏幕顶部,会自动向上收缩隐藏的,像QQ窗口一样。和你预期的效果一样。 你的代码55,56行可以去掉,因为已经移到窗口初始化那里了。 你确定一下你的窗体的MouseDown,MouseEnter,MouseLeave,Move这四个事件都绑定了代码里面的相应函数了。你在试一下,如果不行,我可以把我的项目上传。 [quote=引用 4 楼 h2041075 的回复:] [quote=引用 1 楼 save4me 的回复:] 在Form1初始化后,给formwidth和formheight赋初始值

        public Form1()
        {
            InitializeComponent();
            formwidth = this.Width;
            formheight = this.Height;
        }
不行额,还是没效果[/quote][/quote] 按我开始上传的代码,不加注释的部分是可以实现自动缩出缩回屏幕边缘的(屏幕左、上边可以)。问题在于加了注释部分后,也就是窗体圆角之后,只能从屏幕右边缩回不能从上边缩回了。
save4me 2014-07-23
  • 打赏
  • 举报
回复
用你的代码,在我本机上加上我说明的两句后测试,窗口上边缘到达屏幕顶部,会自动向上收缩隐藏的,像QQ窗口一样。和你预期的效果一样。 你的代码55,56行可以去掉,因为已经移到窗口初始化那里了。 你确定一下你的窗体的MouseDown,MouseEnter,MouseLeave,Move这四个事件都绑定了代码里面的相应函数了。你在试一下,如果不行,我可以把我的项目上传。
引用 4 楼 h2041075 的回复:
[quote=引用 1 楼 save4me 的回复:] 在Form1初始化后,给formwidth和formheight赋初始值

        public Form1()
        {
            InitializeComponent();
            formwidth = this.Width;
            formheight = this.Height;
        }
不行额,还是没效果[/quote]
博客园铁粉 2014-07-23
  • 打赏
  • 举报
回复
引用 13 楼 Z65443344 的回复:
你不会在sizechanged事件里执行的重绘吧
没有,就直接一个paint
save4me 2014-07-22
  • 打赏
  • 举报
回复
在Form1初始化后,给formwidth和formheight赋初始值

        public Form1()
        {
            InitializeComponent();
            formwidth = this.Width;
            formheight = this.Height;
        }

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧