如何修改MFC标尺示例代码将PatBlt绘制的黑线改为红线?
修改MFC标尺光标线条为红色(类似Microsoft Paint样式)
问题背景
我正在基于MFC的标尺示例程序开发,当前移动光标时绘制的是黑色线条标记,想要改成像Microsoft Paint那样的红色线条。原绘制代码使用PatBlt的DSTINVERT模式,请问该如何修改?
原代码片段:
void CRulerView::DrawCursorPos(CPoint NewPos) { if (((m_rulerType == RT_HORIZONTAL) && (NewPos.x > m_DocSize.cx*m_fZoomFactor)) || ((m_rulerType == RT_VERTICAL) && ((NewPos.y) > m_DocSize.cy*m_fZoomFactor))) return; CDC* pDC = GetDC(); // set the map mode right int oldMapMode = pDC->SetMapMode(MM_TEXT); CRect clientRect; GetClientRect(&clientRect); if (m_rulerType==RT_HORIZONTAL) { // erase the previous position pDC->PatBlt(m_lastPos.x, clientRect.top, 1, clientRect.bottom, DSTINVERT); // draw the new position m_lastPos.x = NewPos.x; pDC->PatBlt(m_lastPos.x, clientRect.top, 1, clientRect.bottom, DSTINVERT); } else { // (m_rulerType==RT_VERTICAL) // erase the previous position pDC->PatBlt(clientRect.left, m_lastPos.y, clientRect.right, 1, DSTINVERT); // draw the new position m_lastPos.y = NewPos.y; pDC->PatBlt(clientRect.left, m_lastPos.y, clientRect.right, 1, DSTINVERT); } pDC->SetMapMode(oldMapMode); ReleaseDC(pDC); }
解决方案
原来的DSTINVERT是反转目标区域的颜色,所以在白色背景上会显示黑色,但没法直接指定红色。我们可以改用直接绘制红色线条的方式,同时处理旧线条的擦除(用背景色覆盖)。
修改后的代码如下:
void CRulerView::DrawCursorPos(CPoint NewPos) { if (((m_rulerType == RT_HORIZONTAL) && (NewPos.x > m_DocSize.cx*m_fZoomFactor)) || ((m_rulerType == RT_VERTICAL) && ((NewPos.y) > m_DocSize.cy*m_fZoomFactor))) return; CDC* pDC = GetDC(); // set the map mode right int oldMapMode = pDC->SetMapMode(MM_TEXT); // 保存原有GDI对象,避免影响后续绘制 CBrush* pOldBrush = pDC->GetCurrentBrush(); COLORREF oldBkColor = pDC->GetBkColor(); CRect clientRect; GetClientRect(&clientRect); if (m_rulerType == RT_HORIZONTAL) { // 用标尺背景色擦除旧线条(这里用系统3D界面色,可根据实际调整) pDC->SetBkColor(GetSysColor(COLOR_3DFACE)); pDC->PatBlt(m_lastPos.x, clientRect.top, 1, clientRect.bottom, PATCOPY); // 创建红色画刷并绘制新线条 CBrush redBrush(RGB(255, 0, 0)); pDC->SelectObject(&redBrush); m_lastPos.x = NewPos.x; pDC->PatBlt(m_lastPos.x, clientRect.top, 1, clientRect.bottom, PATCOPY); } else { // 垂直标尺逻辑 // 用背景色擦除旧线条 pDC->SetBkColor(GetSysColor(COLOR_3DFACE)); pDC->PatBlt(clientRect.left, m_lastPos.y, clientRect.right, 1, PATCOPY); // 绘制红色新线条 CBrush redBrush(RGB(255, 0, 0)); pDC->SelectObject(&redBrush); m_lastPos.y = NewPos.y; pDC->PatBlt(clientRect.left, m_lastPos.y, clientRect.right, 1, PATCOPY); } // 恢复原有GDI对象状态 pDC->SelectObject(pOldBrush); pDC->SetBkColor(oldBkColor); pDC->SetMapMode(oldMapMode); ReleaseDC(pDC); }
关键改动说明
- 替换
DSTINVERT为PATCOPY:这个模式会直接用当前选中的画刷颜色填充区域,能精准控制线条颜色。 - 擦除旧线条:用标尺的背景色(这里用系统默认的3D界面色
COLOR_3DFACE,你可以根据实际界面背景调整)覆盖旧线条位置,避免残留痕迹。 - 使用红色画刷:创建
RGB(255,0,0)的红色画刷,选中后绘制新的光标线条,实现类似Paint的红色标记效果。 - 恢复GDI对象:操作完后记得把DC的画笔、背景色恢复成原来的状态,避免影响其他绘制逻辑。
内容的提问来源于stack exchange,提问作者user9444860
相关产品推荐
相关产品推荐

