本篇介绍如何分别在c#,MFC,WIN32程序中移动无标题窗口
C#
C#中总结起来有两种方法:
1.自己控制,鼠标左键点击、移动时窗体的状态,代码见下:
Point offSet;
privatevoid frm_MouseDown(object sender, MouseEventArgs e)
{
offSet =new Point(-e.X, -e.Y);
}
privatevoid frm_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point newPoint = Control.MousePosition;
newPoint.Offset(offSet.X, offSet.Y);
Location = newPoint;
}
}
这个算法也很容易分析,不用多说了(只要注意:在MouseDown中记录的坐标是相对于窗体的坐标,而在MouseMove中是相对于桌面的坐标)。但感觉这种方法的效率不是很高。
2.重载WndProc方法
protectedoverridevoid WndProc(ref Message m)
{
if (m.Msg ==0x0201) { //鼠标左键按下的消息
m.Msg =0x00A1; //更改消息为非客户区按下鼠标
m.LParam = IntPtr.Zero; //默认值
m.WParam =new IntPtr(2); //鼠标放在标题栏内
base.WndProc(ref m);
}
}
感觉这种方法在C#中实现起来是最好的。
MFC
MFC程序分为对话框程序和文档程序
对话框:
在对话框程序里有两种方法都可以:
1.在对话框中添加对消息WM_LBUTTONDOWN的响应,并添加代码
void CTestDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));
CDialog::OnLButtonDown(nFlags, point);
{
PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));
CDialog::OnLButtonDown(nFlags, point);
2.或者添加对消息WM_NCHITTEST的响应,并添加代码
LRESULT CTestDlg::OnNcHitTest(CPoint point)
{
CRect rc;
GetClientRect(&rc);
ClientToScreen(&rc);
return rc.PtInRect(point) ? HTCAPTION : CDialog::OnNcHitTest(point);
//return CDialog::OnNcHitTest(point);
}
MFC文档程序中:
在文档程序中就不能用上面的方法了,本人在CView的派生类中尝试了一下上面的代码,发现只能移动客户区,而不能移动整个程序窗口。只能用C#中的那第一种方法了。
具体的代码为:
在CView类的派生类中定义一个字段 CPoint offset 用来记录鼠标点击时的坐标
鼠标左击消息代码为:
void CtryView::OnLButtonDown(UINT nFlags, CPoint point)
{
//ClientToScreen(&point);
offset =CPoint (-point .x,-point .y);
//这里减65,太硬性了。
offset.y -=65;
CView::OnLButtonDown(nFlags, point);
}
响应鼠标移动的函数为:
void CtryView::OnMouseMove(UINT nFlags, CPoint point)
{
ClientToScreen(&point);
if(nFlags &MK_LBUTTON)
{
CPoint newpoint=point;
newpoint .Offset(offset.x,offset.y);
GetParentFrame()->SetWindowPos(&wndNoTopMost,newpoint .x,newpoint .y,0,0,SWP_NOSIZE);
}
CView::OnMouseMove(nFlags, point);
}
上面那个offset.y 要减去非客户区的高度,才能让程序运行得合理。不过这个65太硬性了,如果程序中没有工具栏或者菜单栏就不能用65了。希望哪位朋友给出计算这个高度的方法!!
WIN32
在WndProc函数中添加对WM_LBUTTONDOWN消息的响应,代码如下
case WM_LBUTTONDOWN: SendMessage(hWnd,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0); break;