Xiangism

从一个无知角落里开始,蹒跚学步,一个未知到另一个未知,在跌跌撞撞中越走越快,越走越远,最后宇宙也为之开源。对于探索者来说,最后他们的思想总是变得和自己的足迹一样伟大。
随笔 - 62, 文章 - 1, 评论 - 220, 阅读 - 20万
  博客园  :: 首页  :: 联系 :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

C#、MFC、Win32——移动无标题窗口

Posted on   Xiangism  阅读(1998)  评论(1编辑  收藏  举报

本篇介绍如何分别在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);
复制代码

 

      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;

 

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示