VC mfc实现鼠标拖尾效果
时间: 2023-09-30 10:08:38 浏览: 212
实现鼠标拖尾效果的方法有很多,以下是一种使用 VC MFC 实现的方法:
1. 在 MFC 应用程序中创建一个新的类,命名为 CMFCDrawTrail。
2. 在 CMFCDrawTrail 类中添加以下成员变量:
```c++
CPoint m_ptCurrent;
CPoint m_ptPrevious;
CBitmap m_bmTrail;
CBitmap m_bmOld;
CDC m_dcTrail;
int m_nTrailWidth;
COLORREF m_crTrailColor;
```
其中,m_ptCurrent 和 m_ptPrevious 分别表示当前鼠标位置和上一个鼠标位置,m_bmTrail 和 m_bmOld 分别表示保存拖尾效果的位图和原始位图,m_dcTrail 是保存拖尾效果的设备上下文,m_nTrailWidth 是拖尾的宽度,m_crTrailColor 是拖尾的颜色。
3. 在 CMFCDrawTrail 类的构造函数中初始化成员变量:
```c++
CMFCDrawTrail::CMFCDrawTrail()
{
m_nTrailWidth = 20;
m_crTrailColor = RGB(255, 0, 0);
}
```
4. 在 CMFCDrawTrail 类中添加以下函数:
```c++
void CMFCDrawTrail::StartTrail(HWND hWnd)
{
CRect rect;
::GetClientRect(hWnd, &rect);
m_bmTrail.DeleteObject();
m_dcTrail.DeleteDC();
CDC* pDC = CWnd::FromHandle(hWnd)->GetDC();
m_bmTrail.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
m_dcTrail.CreateCompatibleDC(pDC);
m_dcTrail.SelectObject(&m_bmTrail);
m_dcTrail.FillSolidRect(rect, RGB(255, 255, 255));
CWnd::FromHandle(hWnd)->ReleaseDC(pDC);
m_ptCurrent.SetPoint(-1, -1);
}
void CMFCDrawTrail::StopTrail()
{
m_bmTrail.DeleteObject();
m_bmOld.DeleteObject();
m_dcTrail.DeleteDC();
}
void CMFCDrawTrail::UpdateTrail(HWND hWnd, CPoint pt)
{
CDC* pDC = CWnd::FromHandle(hWnd)->GetDC();
if (m_ptCurrent == CPoint(-1, -1))
{
m_ptCurrent = pt;
m_ptPrevious = pt;
}
CBrush brush;
brush.CreateStockObject(NULL_BRUSH);
CPen pen;
pen.CreatePen(PS_SOLID, m_nTrailWidth, m_crTrailColor);
CPen* pOldPen = m_dcTrail.SelectObject(&pen);
CBrush* pOldBrush = m_dcTrail.SelectObject(&brush);
m_dcTrail.MoveTo(m_ptPrevious);
m_dcTrail.LineTo(m_ptCurrent);
m_dcTrail.MoveTo(m_ptCurrent);
m_dcTrail.LineTo(pt);
m_ptPrevious = m_ptCurrent;
m_ptCurrent = pt;
m_dcTrail.SelectObject(pOldPen);
m_dcTrail.SelectObject(pOldBrush);
CRect rect(pt.x - m_nTrailWidth / 2, pt.y - m_nTrailWidth / 2, pt.x + m_nTrailWidth / 2, pt.y + m_nTrailWidth / 2);
InvalidateRect(hWnd, &rect, FALSE);
CWnd::FromHandle(hWnd)->ReleaseDC(pDC);
}
void CMFCDrawTrail::DrawTrail(CDC* pDC)
{
if (m_bmOld.GetSafeHandle() == NULL)
{
m_bmOld.CreateCompatibleBitmap(pDC, m_bmTrail.GetWidth(), m_bmTrail.GetHeight());
}
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap* pOldBitmap = memDC.SelectObject(&m_bmOld);
memDC.BitBlt(0, 0, m_bmTrail.GetWidth(), m_bmTrail.GetHeight(), &m_dcTrail, 0, 0, SRCCOPY);
BLENDFUNCTION blend;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 128;
blend.AlphaFormat = AC_SRC_ALPHA;
pDC->AlphaBlend(0, 0, m_bmTrail.GetWidth(), m_bmTrail.GetHeight(), &memDC, 0, 0, m_bmTrail.GetWidth(), m_bmTrail.GetHeight(), blend);
memDC.SelectObject(pOldBitmap);
}
```
其中,StartTrail 函数用来初始化拖尾效果的位图和设备上下文,StopTrail 函数用来释放资源,UpdateTrail 函数用来更新拖尾效果,DrawTrail 函数用来绘制拖尾效果。
5. 在窗口类的 OnMouseMove 函数中调用 UpdateTrail 函数:
```c++
void CMyWnd::OnMouseMove(UINT nFlags, CPoint point)
{
if (nFlags & MK_LBUTTON)
{
m_Trail.UpdateTrail(m_hWnd, point);
}
}
```
6. 在窗口类的 OnPaint 函数中调用 DrawTrail 函数:
```c++
void CMyWnd::OnPaint()
{
CPaintDC dc(this);
m_Trail.DrawTrail(&dc);
}
```
完成上述步骤后,即可实现鼠标拖尾效果。
阅读全文