You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:23:26