C#实现移动窗体的两种共方法
作者:火星papa
在C#Form窗体设计中,如果我们不需要使用默认边框设计自己个性化的窗体,这时候你会发现拖动窗体的功能就没有了,这里需要自己构建方法让用户可以拖动整个窗体,下面就介绍两种方法来实现,需要的朋友可以参考下
引言
在C#Form窗体设计中,如果我们不需要使用默认边框设计自己个性化的窗体(FromBorderStyle=none时),这时候你会发现拖动窗体的功能就没有了,这里需要自己构建方法让用户可以拖动整个窗体,这里我们使用前辈的方法实现和描述一下。即可以通过窗体中的控件事件来控制拖动整个窗体,也可以通过系统API 捕获鼠标拖动窗体,下面就介绍这两方法。
一、通过控件事件移动窗体
1、创建窗体界面
在项目中添加窗体,我这里添加一个窗体test1,并添加一个label作为操作目标,添加上自己的文字,颜色突显一下。
2、添加控件事件
通过属性栏中的事件添加三个事件,分别是鼠标的MouseDown、MouseMove以及MouseUp事件。
3、添加代码
在窗体代码中添加代码,详见下面代码和注释。
//鼠标是否拖动标志 private bool isDragging = false; //鼠标按下时的位置 private Point downPosition; //鼠标按下时的窗体位置 private Point lastFormPosition; /// <summary> /// 鼠标按下事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void label_MouseDown(object sender, MouseEventArgs e) { //判断是否为鼠标左键按下 if (e.Button == MouseButtons.Left) { //置标志为true isDragging = true; //保存当前鼠标坐标 downPosition = Cursor.Position; //保存当前窗体坐标 lastFormPosition = this.Location; } } /// <summary> /// 鼠标移动事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void label_MouseMove(object sender, MouseEventArgs e) { //判断鼠标左键是否按下 if (isDragging) { // 计算鼠标移动的偏移量 int moveX = Cursor.Position.X - downPosition.X; int moveY = Cursor.Position.Y - downPosition.Y; // 更新窗体的位置 this.Location = new Point(lastFormPosition.X + moveX, lastFormPosition.Y + moveY); } } /// <summary> /// 鼠标松开事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void label_MouseUp(object sender, MouseEventArgs e) { //如果是鼠标左键松开,则修改标志为false if (e.Button == MouseButtons.Left) { isDragging = false; } }
二、通过windowsAPI移动窗体
1、 构建窗体和添加事件
构建窗体和添加事件同上一个个方法,我就不详细说明了,只是添加事件的主题更换成窗体test1。
2、代码展示
构建窗体和添加事件通过鼠标移动事件中,调用windows系统API的SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam)函数,可以看到除控件外的部分都可以用来拖动整个窗体。
private const int HT_CAPTION = 0x2;//窗体标题 private const int WM_NCLBUTTONDOWN = 0xA1;//鼠标点击的是非客户区 [DllImport("user32.dll")] public static extern bool ReleaseCapture(); [DllImport("user32.dll")] public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); /// <summary> /// 窗体鼠标移动事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void test1_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { //释放鼠标捕获 ReleaseCapture(); //非客户区鼠标的拖动窗体消息 SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0); } }
三、其它方式
也可以直接通过系统钩子, WndProc(ref Message m)重载实现。代码如下:
internal static int WM_NCHITTEST = 0x84; internal static IntPtr HTCLIENT = (IntPtr)0x1; internal static IntPtr HTCAPTION = (IntPtr)0x2; internal static int WM_NCLBUTTONDBLCLK = 0x00A3; protected override void WndProc(ref Message m) { if (m.Msg == WM_NCLBUTTONDBLCLK) { return; } if (m.Msg == WM_NCHITTEST) { base.WndProc(ref m); if (m.Result == HTCLIENT) { m.HWnd = this.Handle; m.Result = HTCAPTION; } return; } base.WndProc(ref m); }
到此这篇关于C#移动窗体的两种共方法的文章就介绍到这了,更多相关C#移动窗体内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!