无边框窗体拖动大小

     今天有一个朋友问我怎样可以拖拽一个没有边框的窗体,使其改变大小。于是很快想到一个消息
WM_NCHITTEST

该消息用来描述,当关标移动或当按下或当释放了鼠标按扭的时候,就会发送一个WM_NCHITTEST消息给一个窗口若鼠标未被捕获,则这条消息发送给光标所在的窗口。否则,这条消息公布给捕获鼠标的窗口。
参数
   xPos = LOWORD(Lparam);//LParam低位字的值。指出光标的X坐标。该坐标值是相对于屏幕左上角的坐标。
   yPos = HIWORD(LParam);//LParam高位字的值。指出光标的y坐标。

返回值  DefWindowProc函数的返回值是下列值之一,以指示光标热点的位置:
    HTBORDER             光标热点在一个窗口的边界上,该窗口不具有可变大小的边界
    HBOTTOM                在一个窗口下面的水平边界上
    HBOTTOMLEFT      在一个窗口的边界的左下角
    HBOTTOMRIGHT   在边界右下脚
    HTCAPTION            在标题栏中
    HTCLIENT               在客户区
    HTERROR               在屏幕北京或窗口之间的分界线上(与HTNOWHERE类似,所不同的是DefWindowProc函数产生一个系统响铃以指示出错)
    HTGROWBOX         在尺寸框中(与HTSIZE相同)
    HTHSCROLL          在水平滚动栏
    HTLEFT                    在左边界
    HTMENU                  在菜单中
    HTNOWHERE         在屏幕或窗口之间的分界线上
    HTREDUCE             在一个最小化的按扭上
    HTRIGHT                  在窗口右边界
    HTSIZE                      在尺寸框中
    HTSYSMENU           在一个System菜单或在一个子窗口的Close按扭中
    HTTOP                       在上边界
   
HTTOPLEFT             在左上角
    HTTOPRIGHT          在右上角
    HTTRANSPARENT 在当前被其他窗口覆盖的窗口中
    HTVSCROLL            在垂直滚动栏中
    HTZOOM                   在最大化按扭上
注释                  可使用MAKEPOINTS宏将lParam参数转换为一个Points结构
参见                 DefWindowProc,GetCapture

   于是我们可知道要可拖动窗体主要就是要截获该消息,然后让消息的结果返回为
HBOTTOM, HBOTTOMLEFT, HBOTTOMRIGHT,HTLEFT , HTTOP ,HTTOPLEFT  ,HTTOPRIGHT 等则可。于是写下如下代码:


procedure TFo

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
可以通过以下步骤实现: 1. 在 MFC 应用程序中创建一个无边框窗体,可以通过在窗口类的 PreCreateWindow 函数中设置窗口样式来实现,例如: ```c++ BOOL CMyWnd::PreCreateWindow(CREATESTRUCT& cs) { if (!CWnd::PreCreateWindow(cs)) return FALSE; cs.style &= ~WS_BORDER; // 去掉边框样式 cs.style |= WS_THICKFRAME; // 添加调整大小的样式 return TRUE; } ``` 2. 在窗体类中添加以下成员变量: ```c++ BOOL m_bDrag; // 标记是否正在拖动窗体边缘 CPoint m_ptOrigin; // 记录鼠标按下时的位置 ``` 3. 响应 WM_NCHITTEST 消息,判断鼠标位置是否在窗体边缘,并返回对应的鼠标样式: ```c++ UINT CMyWnd::OnNcHitTest(CPoint point) { UINT nHitTest = CWnd::OnNcHitTest(point); if (nHitTest == HTCLIENT) { CRect rect; GetWindowRect(&rect); // 判断鼠标位置是否在窗体边缘 if (point.x < rect.left + 5) nHitTest = HTLEFT; else if (point.x > rect.right - 5) nHitTest = HTRIGHT; if (point.y < rect.top + 5) nHitTest = HTTOP; else if (point.y > rect.bottom - 5) nHitTest = HTBOTTOM; if (point.x < rect.left + 5 && point.y < rect.top + 5) nHitTest = HTTOPLEFT; else if (point.x < rect.left + 5 && point.y > rect.bottom - 5) nHitTest = HTBOTTOMLEFT; else if (point.x > rect.right - 5 && point.y < rect.top + 5) nHitTest = HTTOPRIGHT; else if (point.x > rect.right - 5 && point.y > rect.bottom - 5) nHitTest = HTBOTTOMRIGHT; } return nHitTest; } ``` 4. 响应 WM_NCLBUTTONDOWN 消息,判断鼠标按下的位置是否在窗体边缘,如果是,则记录鼠标按下时的位置,并标记正在拖动边缘: ```c++ void CMyWnd::OnNcLButtonDown(UINT nHitTest, CPoint point) { if (nHitTest == HTLEFT || nHitTest == HTRIGHT || nHitTest == HTTOP || nHitTest == HTBOTTOM || nHitTest == HTTOPLEFT || nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMLEFT || nHitTest == HTBOTTOMRIGHT) { m_bDrag = TRUE; m_ptOrigin = point; SetCapture(); } CWnd::OnNcLButtonDown(nHitTest, point); } ``` 5. 响应 WM_NCMOUSEMOVE 消息,如果正在拖动边缘,则根据鼠标移动的距离调整窗体大小: ```c++ void CMyWnd::OnNcMouseMove(UINT nHitTest, CPoint point) { if (m_bDrag) { CRect rect; GetWindowRect(&rect); int dx = point.x - m_ptOrigin.x; int dy = point.y - m_ptOrigin.y; switch (nHitTest) { case HTLEFT: rect.left += dx; break; case HTRIGHT: rect.right += dx; break; case HTTOP: rect.top += dy; break; case HTBOTTOM: rect.bottom += dy; break; case HTTOPLEFT: rect.left += dx; rect.top += dy; break; case HTTOPRIGHT: rect.right += dx; rect.top += dy; break; case HTBOTTOMLEFT: rect.left += dx; rect.bottom += dy; break; case HTBOTTOMRIGHT: rect.right += dx; rect.bottom += dy; break; } MoveWindow(&rect); } CWnd::OnNcMouseMove(nHitTest, point); } ``` 6. 响应 WM_NCLBUTTONUP 消息,结束拖动边缘: ```c++ void CMyWnd::OnNcLButtonUp(UINT nHitTest, CPoint point) { if (m_bDrag) { m_bDrag = FALSE; ReleaseCapture(); } CWnd::OnNcLButtonUp(nHitTest, point); } ``` 以上就是实现用鼠标拖动窗体边缘实现窗体大小变化的步骤。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值