C#窗体越界时鼠标还能回到初始坐标位置
对窗体加越界限制后,鼠标拖动窗体越界时,窗体不能动,鼠标位置可动,但窗体不再越界时,鼠标位置还能回到鼠标按下时相对窗体的坐标:
1、首先创建一个窗体Form1,然后在窗体上拖一个button1按钮(主要通过这个按钮来拖动窗体)
2、然后对按钮添加鼠标按下事件、鼠标移动事件和鼠标抬起事件,事件里面是对窗体和鼠标坐标的操作,整体代码如下:
using System.Drawing;
using System.Windows.Forms;
namespace 窗体越界鼠标还能回到初始坐标
{
public partial class Form1 : System.Windows.Forms.Form
{
#region 变量定义
public Point mainFormPosition;//主窗口左上角位置
int workingAreaHeight = SystemInformation.WorkingArea.Height;
int workingAreaWidth = SystemInformation.WorkingArea.Width;
private Point relativetMousePosition;//鼠标相对窗体的相对坐标
bool FirstLeft = false;//是否左边第一次按下时坐标
bool FirstRight = false;//是否右边第一次按下时坐标
bool FirstUp = false;//是否上边第一次按下时坐标
bool FirstDown = false;//是否下边第一次按下时坐标
bool isFirstDown = true;//是否第一次按下,鼠标越界纠正时判断是否是第一次按下,不是按下后又拖动了
bool isMoveOut = false;//是否拖出
//这两个变量做差,差值为拖出的距离时软件弹出侧边
int oldMove_X = 0;//侧边停靠拖出时起始坐标
//上一个时刻、鼠标的位置
private Point oldMousePosition;
//当前时刻、鼠标的位置
private Point currentMousePosition;
//鼠标事件
[System.Runtime.InteropServices.DllImport("user32")]
private static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
//移动鼠标
const int MOUSEEVENTF_MOVE = 0x0001;
//模拟鼠标左键按下
const int MOUSEEVENTF_LEFTDOWN = 0x0002;
//模拟鼠标左键抬起
const int MOUSEEVENTF_LEFTUP = 0x0004;
//模拟鼠标右键按下
const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
//模拟鼠标右键抬起
const int MOUSEEVENTF_RIGHTUP = 0x0010;
//模拟鼠标中键按下
const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
//模拟鼠标中键抬起
const int MOUSEEVENTF_MIDDLEUP = 0x0040;
//标示是否采用绝对坐标
const int MOUSEEVENTF_ABSOLUTE = 0x8000;
#endregion
#region 窗体初始化
public Form1()
{
InitializeComponent();
}
#endregion
//-------------------------按钮button1鼠标事件---------------------------------------------------------------
#region 鼠标左键按下Button1按钮事件
private void Button1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
currentMousePosition = Control.MousePosition;
oldMousePosition = currentMousePosition; //鼠标按下时、两个时刻的坐标变成一样,防止错误移动
mainFormPosition = Location;
if (isFirstDown)//鼠标按下时,记录第一次鼠标按下相对主窗体的坐标
{
relativetMousePosition.X = currentMousePosition.X - Location.X;
relativetMousePosition.Y = currentMousePosition.Y - Location.Y;
isFirstDown = false;
}
if (isMoveOut)//鼠标按下时,记录拖出时的初始坐标
{
oldMove_X = currentMousePosition.X;
}
}
}
#endregion
#region 鼠标左键按住Button1按钮移动事件
private void Button1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
currentMousePosition = Control.MousePosition;
if (currentMousePosition.X < relativetMousePosition.X && currentMousePosition.Y > relativetMousePosition.Y && currentMousePosition.Y < workingAreaHeight - this.ClientSize.Height + relativetMousePosition.Y)//左边窗体越界坐标纠正
{
mainFormPosition.X = 0;
mainFormPosition.Y += currentMousePosition.Y - oldMousePosition.Y;
//保存上一个时刻的鼠标位置
oldMousePosition.Y = currentMousePosition.Y;
FirstLeft = true;
}
else if (currentMousePosition.X > workingAreaWidth - this.ClientSize.Width + relativetMousePosition.X && currentMousePosition.Y > relativetMousePosition.Y && currentMousePosition.Y < workingAreaHeight - this.ClientSize.Height + relativetMousePosition.Y)//右边窗体越界坐标纠正
{
mainFormPosition.X = workingAreaWidth - this.ClientSize.Width;
mainFormPosition.Y += currentMousePosition.Y - oldMousePosition.Y;
//保存上一个时刻的鼠标位置
oldMousePosition.Y = currentMousePosition.Y;
FirstRight = true;
}
else if (currentMousePosition.Y < relativetMousePosition.Y && currentMousePosition.X > relativetMousePosition.X && currentMousePosition.X < workingAreaWidth - this.ClientSize.Width + relativetMousePosition.X)//上边窗体越界坐标纠正
{
mainFormPosition.Y = 0;
mainFormPosition.X += currentMousePosition.X - oldMousePosition.X;
//保存上一个时刻的鼠标位置
oldMousePosition.X = currentMousePosition.X;
FirstUp = true;
}
else if (currentMousePosition.Y > workingAreaHeight - this.ClientSize.Height + relativetMousePosition.Y && currentMousePosition.X > relativetMousePosition.X && currentMousePosition.X < workingAreaWidth - this.ClientSize.Width + relativetMousePosition.X)//下边窗体越界坐标纠正
{
mainFormPosition.Y = workingAreaHeight - this.ClientSize.Height;
mainFormPosition.X += currentMousePosition.X - oldMousePosition.X;
//保存上一个时刻的鼠标位置
oldMousePosition.X = currentMousePosition.X;
FirstDown = true;
}
else if (currentMousePosition.X < relativetMousePosition.X && currentMousePosition.Y < relativetMousePosition.Y)//左上角窗体越界坐标纠正
{
mainFormPosition.X = 0;
mainFormPosition.Y = 0;
mainFormPosition.X += currentMousePosition.X - oldMousePosition.X;
mainFormPosition.Y += currentMousePosition.Y - oldMousePosition.Y;
//保存上一个时刻的鼠标位置
oldMousePosition.X = currentMousePosition.X;
oldMousePosition.Y = currentMousePosition.Y;
FirstLeft = true;
FirstUp = true;
}
else if (currentMousePosition.X > workingAreaWidth - this.ClientSize.Width + relativetMousePosition.X && currentMousePosition.Y < relativetMousePosition.Y)//右上角窗体越界坐标纠正
{
mainFormPosition.X = workingAreaWidth - this.ClientSize.Width;
mainFormPosition.Y = 0;
mainFormPosition.X += currentMousePosition.X - oldMousePosition.X;
mainFormPosition.Y += currentMousePosition.Y - oldMousePosition.Y;
//保存上一个时刻的鼠标位置
oldMousePosition.X = currentMousePosition.X;
oldMousePosition.Y = currentMousePosition.Y;
FirstRight = true;
FirstUp = true;
}
else if (currentMousePosition.X < relativetMousePosition.X && currentMousePosition.Y > workingAreaHeight - this.ClientSize.Height + relativetMousePosition.Y)//左下角窗体越界坐标纠正
{
mainFormPosition.X = 0;
mainFormPosition.Y = workingAreaHeight - this.ClientSize.Height;
mainFormPosition.X += currentMousePosition.X - oldMousePosition.X;
mainFormPosition.Y += currentMousePosition.Y - oldMousePosition.Y;
//保存上一个时刻的鼠标位置
oldMousePosition.X = currentMousePosition.X;
oldMousePosition.Y = currentMousePosition.Y;
FirstLeft = true;
FirstDown = true;
}
else if (currentMousePosition.X > workingAreaWidth - this.ClientSize.Width + relativetMousePosition.X && currentMousePosition.Y > workingAreaHeight - this.ClientSize.Height + relativetMousePosition.Y)//右下角窗体越界坐标纠正
{
mainFormPosition.Y = workingAreaHeight - this.ClientSize.Height;
mainFormPosition.X = workingAreaWidth - this.ClientSize.Width;
mainFormPosition.X += currentMousePosition.X - oldMousePosition.X;
mainFormPosition.Y += currentMousePosition.Y - oldMousePosition.Y;
//保存上一个时刻的鼠标位置
oldMousePosition.X = currentMousePosition.X;
oldMousePosition.Y = currentMousePosition.Y;
FirstRight = true;
FirstDown = true;
}
if (FirstLeft)
{
currentMousePosition.X = relativetMousePosition.X;
FirstLeft = false;
}
if (FirstRight)
{
currentMousePosition.X = workingAreaWidth - this.ClientSize.Width + relativetMousePosition.X;
FirstRight = false;
}
if (FirstUp)
{
currentMousePosition.Y = relativetMousePosition.Y;
FirstUp = false;
}
if (FirstDown)
{
currentMousePosition.Y = workingAreaHeight - this.ClientSize.Height + relativetMousePosition.Y;
FirstDown = false;
}
if (FirstLeft && FirstUp)
{
currentMousePosition.X = relativetMousePosition.X;
currentMousePosition.Y = relativetMousePosition.Y;
FirstLeft = false;
FirstUp = false;
}
if (FirstRight && FirstUp)
{
currentMousePosition.X = workingAreaWidth - this.ClientSize.Width + relativetMousePosition.X;
currentMousePosition.Y = relativetMousePosition.Y;
FirstUp = false;
FirstRight = false;
}
if (FirstLeft && FirstDown)
{
currentMousePosition.X = relativetMousePosition.X;
currentMousePosition.Y = workingAreaHeight - this.ClientSize.Height + relativetMousePosition.Y;
FirstLeft = false;
FirstDown = false;
}
if (FirstRight && FirstDown)
{
currentMousePosition.X = workingAreaWidth - this.ClientSize.Width + relativetMousePosition.X;
currentMousePosition.Y = workingAreaHeight - this.ClientSize.Height + relativetMousePosition.Y;
FirstRight = false;
FirstDown = false;
}
//对窗体进行移动
mainFormPosition.X += currentMousePosition.X - oldMousePosition.X;
mainFormPosition.Y += currentMousePosition.Y - oldMousePosition.Y;
//保存上一个时刻的鼠标位置
oldMousePosition = currentMousePosition;
#region 越界处理
if (mainFormPosition.X < 0)//左边越界
{
mainFormPosition.X = 0;
}
else if (mainFormPosition.Y < 0)//上边越界
{
mainFormPosition.Y = 0;
}
else if (mainFormPosition.X > workingAreaWidth - this.ClientSize.Width)//右边越界
{
mainFormPosition.X = workingAreaWidth - this.ClientSize.Width;
}
else if (mainFormPosition.Y > workingAreaHeight - this.ClientSize.Height)//下边越界
{
mainFormPosition.Y = workingAreaHeight - this.ClientSize.Height;
}
//更新主窗口位置
Location = mainFormPosition;
#endregion
}
}
#endregion
#region 鼠标在按钮Button1抬起事件
private void Button1_MouseUp(object sender, MouseEventArgs e)
{
isFirstDown = true;
//如果主窗体在这个位置,就判断允许主窗体在鼠标抬起后执行移动事件
if (mainFormPosition.X == workingAreaWidth - this.ClientSize.Width)
{
isMoveOut = false;
}
if (mainFormPosition.X == 0)
{
isMoveOut = false;
}
}
#endregion
}
}
动画效果如下:

这是本人在一个项目中遇到的问题,所以特意总结出来分享给大家。
C#窗体越界时鼠标还能回到初始坐标位置的更多相关文章
- Javascript获取当前鼠标在元素内的坐标定位
代码如下: <!doctype html> <html> <head> <meta charset="utf-8"> <tit ...
- Qt无边框窗体-最大化时支持拖拽还原
目录 一.概述 二.效果展示 三.demo制作 1.设计窗体 2.双击放大 四.拖拽 五.相关文章 原文链接:Markdown模板 一.概述 用Qt进行开发界面时,既想要实现友好的用户交互又想界面漂亮 ...
- 黑马程序员 关于c# windows窗体关闭时线程未能完全退出问题(专题一)
<a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IO开发S</a> ...
- WPF 子窗体关闭时显示父窗体
这个问题纠结了两天,今天在一个朋友的帮助下,解决了,其实很简单,但是可能作为新手,接触WPF时间还是短,因此作为一个问题困扰了我. 父窗体部分代码 private void EditInformati ...
- Qt窗体关闭时,如何自动销毁窗体类对象
Qt窗体关闭时,如何自动销毁窗体类对象 要对你的窗口设置WA_DeleteOnClose属性,默认的情况下关闭窗口仅仅意味着隐藏它 ImgWindow1->setAttribute(Qt ...
- DirectUI中模态对话框和菜单的原理(自己控制整个Windows消息循环。或者,用菜单模拟窗体打开时用SetCapture取得控制权,一旦窗体收到WM_CAPTURECHANGED消息就把窗体退出)
经常有人问关于模态对话框和系统菜单内部实现原理方面的问题, 因为系统通过API隐藏了太多细节,这2个问题确实令初学者甚至是有经验的开发者困扰, 下面是我个人的一些经验总结. 先说模态对话框,外部看模态 ...
- 启动weblogic服务时,还需要输入用户名和密码的解决方法
当启动weblogic服务时,还需要输入用户名和密码,相当繁琐,如下: 而在生产环境中,一般会要求不要在每次启动时都输入用户名密码, 因此可以通过一些简单的配置达到此目的,通常的做法有两种: 1.修改 ...
- C# WinForm 关于窗体最大化时的是否全屏效果与是否遮盖任务栏
0.新建窗体 及添加按钮 1. 执行如下按钮事件 private void btnFormMax_Click(object sender, EventArgs e) { if (this ...
- sublime打开文本时会记忆上次关闭时鼠标停留的位置
sublime打开文本时会记忆上次关闭时鼠标停留的位置
随机推荐
- vue.js 2.0(1)
1.点击一个按钮打开,关闭弹框 2.实现滚动监听,导航看顶置,实现某元素吸顶 路由
- Redis Cluster [WARNING] Node 127.0.0.1:7003 has slots in migrating state (15495).
错误描述 在迁移一个节点上的slot到另一个节点的时候卡在其中的一个slot报错,截图如下: 查询发现在15495的这个slot上面存在一个key,但是并没有发现这个key有什么问题.使用fix进行修 ...
- xampp运行MySQL shutdown unexpectedly解决方案
昨天晚上自己的网站突然打不开了,以为被人黑了.想想不应该啊,这小站不会有人关注的,于是登录服务器看了下,发现是Mysql打不开了 很奇怪,因为今天白天还是可以打开的,下班后也没有碰过服务器 首先看看是 ...
- Java核心技术卷一基础技术-第13章-集合-读书笔记
第13章 集合 本章内容: * 集合接口 * 具体的集合 * 集合框架 * 算法 * 遗留的集合 13.1 集合接口 Enumeration接口提供了一种用于访问任意容器中各个元素的抽象机制. 13. ...
- eclipse对于标签的配置不会出现自动提示的解决
解决办法:引入 mybatis-3-config.dtd 文件Window-preferences-搜索 xml-xml catalog在 User Specified Entries 目录下 add ...
- HTTP 协议常见的状态码
HTTP状态码负责表示客户端HTTP请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作. 状态码的类别: 记录在RFC2616上的HTTP状态码有40种,再加上WebDAV等的扩展,数量 ...
- 第45节:Java当中的变量,面向对象
Java当中的变量 01 Java当中的实例变量和类变量 什么是实例变量和类变量呢? 实例变量为没有用static修饰符修饰的变量,而类变量为用static修饰符修饰的变量. public class ...
- 初识vw和vh
最近在项目里突然看到了一行css代码,height:100vh; 一时间有点蒙蔽 因为之前有听过这个css3新增单位,但没有去了解过. 那这个单位又跟px,rem,em,%有什么不同呢? 简述: ...
- soul开源网关项目搭建学习
1. soul开源网关项目搭建学习 1.1. 地址 https://gitee.com/shuaiqiyu/soul 1.2. 介绍 官方介绍:这是一个异步的,高性能的,跨语言的,响应式的API网关. ...
- python爬取猫眼电影top100
最近想研究下python爬虫,于是就找了些练习项目试试手,熟悉一下,猫眼电影可能就是那种最简单的了. 1 看下猫眼电影的top100页面 分了10页,url为:https://maoyan.com/b ...