C# 系统应用之无标题窗体移动的两种方法

简介:

在做项目界面设计中,常常为了美观需要设置窗体属性"FormBorderStyle"(窗体边框和标题栏外观)为None无标题窗口.此时隐藏标题的窗口怎样实现移动呢?我根据自己的项目从自己完成的两种方法进行讲解.

一.MouseDown\MouseMove事件方法实现

第一种方法我采用常用的根据MouseDown、MouseMove、MouseUp、MouseLeave事件中鼠标移动的距离,窗体坐标也跟着移动的方法.具体代码如下:

bool formMove = false;       //是否开始移动
int currentXPosition = 0;    //当前鼠标X坐标
int currentYPosition = 0;    //当前鼠标Y坐标
        
//函数:鼠标按下
private void WelcomeWindow_MouseDown(object sender, MouseEventArgs e)
{
    formMove = true;                       //鼠标按下开始移动
    currentXPosition = MousePosition.X;    //鼠标的X坐标为当前窗体左上角X坐标
    currentYPosition = MousePosition.Y;    //鼠标的Y坐标为当前窗体的左上角Y坐标
}
//函数:鼠标移动
private void WelcomeWindow_MouseMove(object sender, MouseEventArgs e)
{
    if (formMove)
    {
        //鼠标xy坐标确定窗体XY坐标 鼠标移动XY距离
        this.Left += MousePosition.X - currentXPosition;
        this.Top += MousePosition.Y - currentYPosition;
        //鼠标当前位置赋值
        currentXPosition = MousePosition.X;
        currentYPosition = MousePosition.Y;
    }
}
//函数:鼠标松开
private void WelcomeWindow_MouseUp(object sender, MouseEventArgs e)
{
    formMove = false;     //停止移动
}
//函数:鼠标离开
private void WelcomeWindow_MouseLeave(object sender, EventArgs e)
{
    //初始状态
    currentXPosition = 0;
    currentYPosition = 0;
    formMove = false;
}

同时有的设置变量Point formPoint通过Offset和Location变换位置亦类似.但是第一种方法可能由于每次获取鼠标坐标,移动时如果鼠标不在窗口位置会产生窗体总是向屏幕外移动的现象,因此推荐第二种调用API函数的方法.

二.调用API函数实现

第二种方法是采用API函数ReleaseCapture和SendMessage来实现的,ReleaseCapture函数从当前线程中窗口释放鼠标捕获,SendMessage函数的作用是调用一个窗口的窗口函数,将一条消息命令发给那个窗口.
SendMessage(
IntPtr hwnd,   //要接收消息的那个窗口的句柄
int wMsg,       //消息的标识符
int wParam,   //具体取决于发送的消息
int lParam      //具体取决于发送的消息
)

其中调用API函数需要引用命名空间System.Runtime.InteropServices.代码中WM_SYSCOMMAND常量代表要向窗口发送消息,SC_MOVE常代表要向窗口发送移动的消息.代码如下:

#region 鼠标移动操作
//该函数从当前线程中窗口释放鼠标捕获
[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;

//鼠标位于窗体(底部位置)按下移动操作
private void EMSecure_MouseDown(object sender, MouseEventArgs e)
{
    ReleaseCapture();
    SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
}
#endregion

其中,EMSecure是对话框Form,当鼠标点击到图片或控件Panel时不会响应移动,所以对需要移动的控件也响应该API函数即可.如我的程序界面Panel1位于窗体顶部,故也响应该移动事件,即panel1_MouseDown(object sender, MouseEventArgs e).运行结果如下图所示,红色部分可以实现移动(顶部为Panel控件):

提示如果是WPF可以响应Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){this.DragMove();}实现窗体移动.最后希望该文章对大家有所帮助,如果有错误或不足之处,请海涵.
(By:Eastmount 2014-3-7 夜2点 原创:
http://blog.csdn.net/eastmount)

目录
相关文章
|
26天前
|
SQL 小程序 API
如何运用C#.NET技术快速开发一套掌上医院系统?
本方案基于C#.NET技术快速构建掌上医院系统,结合模块化开发理念与医院信息化需求。核心功能涵盖用户端的预约挂号、在线问诊、报告查询等,以及管理端的排班管理和数据统计。采用.NET Core Web API与uni-app实现前后端分离,支持跨平台小程序开发。数据库选用SQL Server 2012,并通过读写分离与索引优化提升性能。部署方案包括Windows Server与负载均衡设计,确保高可用性。同时针对API差异、数据库老化及高并发等问题制定应对措施,保障系统稳定运行。推荐使用Postman、Redgate等工具辅助开发,提升效率与质量。
|
4月前
|
存储 监控 算法
企业内网监控系统中基于哈希表的 C# 算法解析
在企业内网监控系统中,哈希表作为一种高效的数据结构,能够快速处理大量网络连接和用户操作记录,确保网络安全与效率。通过C#代码示例展示了如何使用哈希表存储和管理用户的登录时间、访问IP及操作行为等信息,实现快速的查找、插入和删除操作。哈希表的应用显著提升了系统的实时性和准确性,尽管存在哈希冲突等问题,但通过合理设计哈希函数和冲突解决策略,可以确保系统稳定运行,为企业提供有力的安全保障。
|
5月前
|
存储 安全 物联网
C# 在物联网 (IoT) 应用中的应用
本文介绍了C#在物联网(IoT)应用中的应用,涵盖基础概念、优势、常见问题及其解决方法。重点讨论了网络通信、数据处理和安全问题,并提供了相应的代码示例,旨在帮助开发者更好地利用C#进行IoT开发。
236 3
|
5月前
|
JSON 程序员 C#
使用 C# 比较两个对象是否相等的7个方法总结
比较对象是编程中的一项基本技能,在实际业务中经常碰到,比如在ERP系统中,企业的信息非常重要,每一次更新,都需要比较记录更新前后企业的信息,直接比较通常只能告诉我们它们是否指向同一个内存地址,那我们应该怎么办呢?分享 7 个方法给你!
129 2
|
5月前
|
C# UED SEO
C# 异步方法async / await任务超时处理
通过使用 `Task.WhenAny`和 `Task.Delay`方法,您可以在C#中有效地实现异步任务的超时处理机制。这种方法允许您在指定时间内等待任务完成,并在任务超时时采取适当的措施,如抛出异常或执行备用操作。希望本文提供的详细解释和代码示例能帮助您在实际项目中更好地处理异步任务超时问题,提升应用程序的可靠性和用户体验。
222 3
|
5月前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
79 3
|
5月前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
141 2
|
6月前
|
存储 C#
【C#】大批量判断文件是否存在的两种方法效率对比
【C#】大批量判断文件是否存在的两种方法效率对比
120 1
|
5月前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
50 0
|
6月前
|
消息中间件 网络协议 安全
C# 一分钟浅谈:WebSocket 协议应用
【10月更文挑战第6天】在过去的一年中,我参与了一个基于 WebSocket 的实时通信系统项目,该项目不仅提升了工作效率,还改善了用户体验。本文将分享在 C# 中应用 WebSocket 协议的经验和心得,包括基础概念、C# 实现示例、常见问题及解决方案等内容,希望能为广大开发者提供参考。
428 0