MFC 无边框窗体实现用鼠标拖动窗体边缘实现窗体大小变化
时间: 2024-05-18 08:12:53 浏览: 96
可改变大小的无边框窗体
实现 MFC 无边框窗体可以通过以下步骤:
1. 创建一个派生自 CWnd 的类,作为无边框窗口的基类。
2. 重载 OnNcCalcSize 函数,计算非客户区的大小。
3. 重载 OnNcPaint 函数,绘制非客户区的背景和边框。
4. 重载 OnNcLButtonDown 函数,处理鼠标左键按下事件,如果鼠标位于窗口边缘,则将鼠标捕获,并设置窗口大小变化标志。
5. 重载 OnNcLButtonUp 函数,处理鼠标左键释放事件,释放鼠标捕获,并清除窗口大小变化标志。
6. 重载 OnMouseMove 函数,处理鼠标移动事件,如果窗口大小变化标志被设置,则根据鼠标位置改变窗口大小。
下面是一个简单的示例代码:
```
class CMyWnd : public CWnd
{
public:
CMyWnd()
{
m_bSizing = FALSE;
}
protected:
BOOL m_bSizing;
afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
lpncsp->rgrc[0].left += 2;
lpncsp->rgrc[0].top += 2;
lpncsp->rgrc[0].right -= 2;
lpncsp->rgrc[0].bottom -= 2;
}
afx_msg void OnNcPaint()
{
CWindowDC dc(this);
CRect rect;
GetWindowRect(rect);
rect.OffsetRect(-rect.left, -rect.top);
rect.DeflateRect(2, 2);
dc.FillSolidRect(rect, RGB(192, 192, 192));
dc.Draw3dRect(rect, RGB(0, 0, 0), RGB(0, 0, 0));
}
afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point)
{
if (nHitTest == HTLEFT || nHitTest == HTRIGHT ||
nHitTest == HTTOP || nHitTest == HTBOTTOM ||
nHitTest == HTTOPLEFT || nHitTest == HTTOPRIGHT ||
nHitTest == HTBOTTOMLEFT || nHitTest == HTBOTTOMRIGHT)
{
SetCapture();
m_bSizing = TRUE;
}
else
{
CWnd::OnNcLButtonDown(nHitTest, point);
}
}
afx_msg void OnNcLButtonUp(UINT nHitTest, CPoint point)
{
if (m_bSizing)
{
ReleaseCapture();
m_bSizing = FALSE;
}
else
{
CWnd::OnNcLButtonUp(nHitTest, point);
}
}
afx_msg void OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bSizing)
{
CRect rect;
GetWindowRect(rect);
switch (GetHitTest(point))
{
case HTLEFT:
rect.left = point.x;
break;
case HTRIGHT:
rect.right = point.x;
break;
case HTTOP:
rect.top = point.y;
break;
case HTBOTTOM:
rect.bottom = point.y;
break;
case HTTOPLEFT:
rect.left = point.x;
rect.top = point.y;
break;
case HTTOPRIGHT:
rect.right = point.x;
rect.top = point.y;
break;
case HTBOTTOMLEFT:
rect.left = point.x;
rect.bottom = point.y;
break;
case HTBOTTOMRIGHT:
rect.right = point.x;
rect.bottom = point.y;
break;
}
MoveWindow(rect);
}
else
{
CWnd::OnMouseMove(nFlags, point);
}
}
int GetHitTest(CPoint point)
{
CRect rect;
GetWindowRect(rect);
int cx = rect.Width() / 3;
int cy = rect.Height() / 3;
if (point.x < rect.left + cx)
{
if (point.y < rect.top + cy)
{
return HTTOPLEFT;
}
else if (point.y > rect.bottom - cy)
{
return HTBOTTOMLEFT;
}
else
{
return HTLEFT;
}
}
else if (point.x > rect.right - cx)
{
if (point.y < rect.top + cy)
{
return HTTOPRIGHT;
}
else if (point.y > rect.bottom - cy)
{
return HTBOTTOMRIGHT;
}
else
{
return HTRIGHT;
}
}
else
{
if (point.y < rect.top + cy)
{
return HTTOP;
}
else if (point.y > rect.bottom - cy)
{
return HTBOTTOM;
}
else
{
return HTCLIENT;
}
}
}
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CMyWnd, CWnd)
ON_WM_NCCALCSIZE()
ON_WM_NCPAINT()
ON_WM_NCLBUTTONDOWN()
ON_WM_NCLBUTTONUP()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
```
在这个示例代码中,GetHitTest 函数用于确定鼠标位置相对于窗口的位置,以便按照相应的方法改变窗口大小。这个函数是基于窗口分成 9 个区域的思想,每个区域都对应一个鼠标消息。当鼠标位于边缘时,根据鼠标位置判断应该执行哪个消息。
阅读全文