C#无标题窗体移动,三类代码:
第一种采用,需注意窗体上的控件是否把窗体覆盖了。。。MouseDown、MouseMove、MouseUp事件应该是鼠标所处位置最顶层的控件的事件
在窗体的类中声明两个变量
private bool isMouseDown = false; //记录鼠标按键是否按下
创建该窗体 MouseDown、MouseMove、MouseUp事件的相应处理程序
{
int xOffset;
int yOffset;
if (e.Button == MouseButtons.Left)
{
xOffset = -e.X ;
yOffset = -e.Y ;
mouseOffset = new Point(xOffset, yOffset);
isMouseDown = true ;
}
}
{
if (isMouseDown)
{
Point mousePos = Control.MousePosition;
mousePos.Offset(mouseOffset.X, mouseOffset.Y);
Location = mousePos;
}
}
{
// 修改鼠标状态isMouseDown的值
// 确保只有鼠标左键按下并移动时,才移动窗体
if (e.Button == MouseButtons.Left)
{
isMouseDown = false ;
}
}
来源:http://www.cnblogs.com/XingfuStar/archive/2006/02/15/331242.html
第二种调用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);
}
来源:http://topic.csdn.net/u/20081117/14/74b212a4-7e5f-41e2-87b7-bbc78a63227f.html
第三种 未验证
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)
{
}
来源:http://www.xrss.cn/Dev/DotNet/200851519504.Html
让鼠标拖动WinForm窗体
参考网上的代码,写了此文。
先引入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