C# 移动无标题栏无边框窗体的3种方法
目录第一种:手工移动第二种:调用系统API1.引入下面代码 前提需要引入命名空间using System.Runtime.InteropServices2.增加鼠标按下事件发送消息,让系统误以为按下是标题栏第三种,重写 WndProc第一种:手工移动直接通过修改窗体位置从而达到移动窗体的效果//定义一个位置信息Point用于存储鼠标位置private Point mPoint;/// <su
目录
1.引入下面代码 前提需要引入命名空间using System.Runtime.InteropServices
第一种:手工移动
直接通过修改窗体位置从而达到移动窗体的效果
//定义一个位置信息Point用于存储鼠标位置
private Point mPoint;
/// <summary>
/// 鼠标按下
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
mPoint = new Point(e.X, e.Y);
}
/// <summary>
/// 鼠标移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this.Location = new Point(this.Location.X + e.X - mPoint.X, this.Location.Y + e.Y - mPoint.Y);
}
}
第二种:调用系统API
原理:是当鼠标左键按下时,让系统认为是在标题栏按下的。
这里我们用到了winapi里的WM_LBUTTONDOWN(客户区鼠标左键按下,值:0x0201)和WM_NCLBUTTONDOWN(非客户区鼠标左键按下,值:0x00A1)及HTCAPTION(鼠标位置在标题栏,值:2,为什么是2,请参照https://msdn.microsoft.com/en-us/library/windows/desktop/ms645618(v=vs.85).aspx)这三个常量。
1.引入下面代码 前提需要引入命名空间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);
private const int VM_NCLBUTTONDOWN = 0XA1;//定义鼠标左键按下
private const int HTCAPTION = 2;
2.增加鼠标按下事件发送消息,让系统误以为按下是标题栏
/// <summary>
/// 鼠标按下
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
//为当前应用程序释放鼠标捕获
ReleaseCapture();
//发送消息 让系统误以为在标题栏上按下鼠标
SendMessage((IntPtr)this.Handle, VM_NCLBUTTONDOWN, HTCAPTION, 0);
}
第三种,重写 WndProc
这个方法是用来处理消息的,包括鼠标的各种消息。前一种方法中讲到了非客户区的鼠标消息,但我在msdn里找了半天,没找到相关的非客户区的鼠标事件。但WndProc里可以处理。
原理:将鼠标在客户区按下的消息更改为在非客户区的标题栏按下。
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0x0201://鼠标左键按下的消息
m.Msg = 0x00A1;//更改消息为非客户区按下鼠标
m.LParam = IntPtr.Zero;//默认值
m.WParam = new IntPtr(2);//鼠标放在标题栏内
break;
}
base.WndProc(ref m);
}
小结
除了第一种方法外,后两种都是用了模拟鼠标在标题的动作。这里我是实现了在非标题栏位置移动窗体。
由此我们可以引申开来,我们还可以模拟标题栏图标、关闭、最大化、最小化等操作。这样在一些无标题栏窗体中使用是很方便的。大家不仿尝试一下。
更多推荐
所有评论(0)