[转载]学习:C#无标题窗体移动
(2010-12-08 16:19:10)标签: | 分类: |
C#无标题窗体移动,三类代码:
第一种采用,需注意窗体上的控件是否把窗体覆盖了。。。MouseDown、MouseMove、MouseUp事件应该是鼠标所处位置最顶层的控件的事件
在窗体的类中声明两个变量
创建该窗体 MouseDown、MouseMove、MouseUp事件的相应处理程序
来源:
第二种调用API 未验证
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); public const int WM_SYSCOMMAND = 0x0112; public const int SC_MOVE = 0xF010; public const int HTCAPTION = 0x0002; private void Form1_MouseDown(object sender, MouseEventArgs e) { ReleaseCapture(); SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0); }
来源:
第三种 未验证
private bool isMouseDown = false;
private Point FormLocation; //form的location
private Point mouseOffset; //鼠标的按下位置
[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 WM_SYSCOMMAND = 0x0112;//点击窗口左上角那个图标时的系统信息
private const int SC_MOVE = 0xF010;//移动信息
private const int HTCAPTION = 0x0002;//表示鼠标在窗口标题栏时的系统信息
private const int WM_NCHITTEST = 0x84;//鼠标在窗体客户区(除了标题栏和边框以外的部分)时发送的消息
private const int HTCLIENT = 0x1;//表示鼠标在窗口客户区的系统消息
private const int SC_MAXIMIZE = 0xF030;//最大化信息
private const int SC_MINIMIZE = 0xF020;//最小化信息
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_SYSCOMMAND:
if (m.WParam == (IntPtr)SC_MAXIMIZE)
{
m.WParam = (IntPtr)SC_MINIMIZE;
}
break;
case WM_NCHITTEST: //如果鼠标移动或单击
base.WndProc(ref m);//调用基类的窗口过程——WndProc方法处理这个消息
if (m.Result == (IntPtr)HTCLIENT)//如果返回的是HTCLIENT
{
m.Result = (IntPtr)HTCAPTION;//把它改为HTCAPTION
return;//直接返回退出方法
}
break;
}
base.WndProc(ref m);//如果不是鼠标移动或单击消息就调用基类的窗口过程进行处理
}
private void Form1_Load(object sender, EventArgs e)
{
}
来源:
参考网上的代码,写了此文。
先引入API函数ReleaseCapture、SendMessage
- [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 WM_SYSCOMMAND = 0x0112;//点击窗口左上角那个图标时的系统信息
- private const int WM_MOVING = 0x216;//鼠标移动消息
- private const int SC_MOVE = 0xF010;//移动信息
- private const int HTCAPTION = 0x0002;//表示鼠标在窗口标题栏时的系统信息
- private const int WM_NCHITTEST = 0x84;//鼠标在窗体客户区(除了标题栏和边框以外的部分)时发送的消息
- private const int HTCLIENT = 0x1;//表示鼠标在窗口客户区的系统消息
- private const int SC_MAXIMIZE = 0xF030;//最大化信息
- private const int SC_MINIMIZE = 0xF020;//最小化信息
再override 一下WindProc函数
- protected override void WndProc(ref Message m)
- {
- switch (m.Msg)
- {
- case WM_MOVING: //如果鼠标移
- base.WndProc(ref m);//调用基类的窗口过程——WndProc方法处理这个消息
- if (m.Result == (IntPtr)HTCLIENT)//如果返回的是HTCLIENT
- {
- m.Result = (IntPtr)HTCAPTION;//把它改为HTCAPTION
- return;//直接返回退出方法
- }
- break;
- }
- base.WndProc(ref m);//如果不是鼠标移动或单击消息就调用基类的窗口过程进行处理
- }
再override一下OnMouseMove函数
- protected override void OnMouseMove(MouseEventArgs e)
- {
- if (e.Button == MouseButtons.Left)
- {
- ReleaseCapture();
- SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
- }
- base.OnMouseMove(e);
- }
运行程序,可以在窗体任意位置拖动改变窗体的位置,而不仅仅像普通的windows程序那样只能在标题栏用鼠标拖动窗口。
外加让textbox内容改变后自动滚动到最底端:
- private void btnAddText_Click(object sender, EventArgs e)
- {
- textBox1.AppendText(DateTime.Now.ToString() + "/r/n");
- textBox1.SelectionStart = textBox1.Text.Length;
- //textBox1.SelectionLength = 0;
- textBox1.ScrollToCaret();
- }
实现窗体类似于QQ最小化的动画效果
using System.Runtime.InteropServices;
……
#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);private const int WM_SYSCOMMAND = 0x0112;//点击窗口左上角那个图标时的系统信息
private const int SC_MOVE = 0xF010;//移动信息 private const int HTCAPTION = 0x0002;//表示鼠标在窗口标题栏时的系统信息 private const int WM_NCHITTEST = 0x84;//鼠标在窗体客户区(除了标题栏和边框以外的部分)时发送的消息 private const int HTCLIENT = 0x1;//表示鼠标在窗口客户区的系统消息 private const int SC_MAXIMIZE = 0xF030;//最大化信息 private const int SC_MINIMIZE = 0xF020;//最小化信息private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{ Application.Exit(); }//第一种实现可拖动窗体的方法
private void FormAlert_MouseDown(object sender, MouseEventArgs e) { //这里只允许鼠标在窗体是“指定区域”有拖动功能,因为其它区域还要处理鼠标单击事件 //这里的“指定区域”指窗体上面高25个像素,宽是窗体宽度减20像素,因为最右侧要处理关闭按钮事件 if (e.Y < 25 && e.X < this.Width - 20) { ReleaseCapture();//首先释放鼠标焦点捕获,这样就不会再发出WM_NCHITTEST消息 SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);//然后向当前窗体发送消息,消息是移动+表示鼠标在标题栏上 } } //如果用这种重写的方法,就把上面的部分注释掉……/*
第二种实现可拖动窗体的方法,用这个方法有个问题,双击鼠标时窗体会最大化 */ //protected override void WndProc(ref Message m) //{ // switch (m.Msg) // { // case WM_SYSCOMMAND: // if (m.WParam == (IntPtr)SC_MAXIMIZE) // { // m.WParam = (IntPtr)SC_MINIMIZE; // } // break; // case WM_NCHITTEST: //如果鼠标移动或单击 // base.WndProc(ref m);//调用基类的窗口过程——WndProc方法处理这个消息 // if (m.Result == (IntPtr)HTCLIENT)//如果返回的是HTCLIENT // { // m.Result = (IntPtr)HTCAPTION;//把它改为HTCAPTION // return;//直接返回退出方法 // } // break; // } // base.WndProc(ref m);//如果不是鼠标移动或单击消息就调用基类的窗口过程进行处理 //} #endregion