【问题标题】:Redraw shapes in MFC在 MFC 中重绘形状
【发布时间】:2020-06-13 14:36:38
【问题描述】:

我正在尝试使用 MFC 和 C++ 开发一个画家应用程序。

所以我设置了一个视图,在其中进行实际绘画。但是,当我打开颜色按钮时,我会在画布视图上看到菜单的“剩菜”。我不知道如何删除它们。我尝试使用 SaveDCRestoreDC 将其恢复到以前的状态,但是那里没有运气。据我了解,它旨在恢复设备上下文的属性,例如笔和画笔,但它对我没有用......

我也需要这个功能,所以当我放置一个矩形时,我可以为它呈现预览,但“预览”再次像剩菜一样呈现。

我的观点OnEraseBkgbd;

BOOL CanvasView::OnEraseBkgnd(CDC* pDC)
{
    if (!isBackgroundInit)
    {
        CRect rect;
        GetClientRect(&rect);
        CBrush myBrush(RGB(255, 255, 255)); // dialog background color
        CBrush* pOld = pDC->SelectObject(&myBrush);
        BOOL bRes = pDC->PatBlt(0, 0, rect.Width(), rect.Height(), PATCOPY);
        pDC->SelectObject(pOld); // restore old brush
        isBackgroundInit = true;
        return bRes;
    }

    return 0;
}

我的 OnPaint:

void CanvasView::OnPaint()
{
    CDialogEx::OnPaint();
    //UpdateData(true);
    CRect rect;
    GetClientRect(&rect);
    if (dc == nullptr)
    {
        dc = new CClientDC(this);
        //dc->CreateCompatibleDC(dc);
        HDC hdc = CreateCompatibleDC(*dc);
        this->hdc = &hdc;
    } else 
    {

        BitBlt(*dc, 0, 0, (int)rect.Width(), (int)rect.Height(), *hdc, 0, 0, SRCCOPY);
    }
}

最初的样子:

打开颜色按钮时的样子:

关闭颜色按钮菜单后的样子(红色箭头标记的剩菜):

当试图建立一个矩形时:

知道如何解决这个问题并真正恢复绘图吗?

【问题讨论】:

  • 看起来您没有正确处理视图的 OnEraseBkgnd() 调用/覆盖。
  • @AdrianMole 抱歉,添加了我的OnEraseBkgnd 以供我查看
  • @AdrianMole 我不会每次都重置我的背景,因为我不希望画完的画也被擦除。有没有办法克服这个问题?
  • 是的。您需要将图像存储在位图/内存-DC 中,然后将 BitBlt 存储到 OnDraw() 覆盖中的视图 DC。 (退出颜色选择弹出窗口时调用RedrawWindow()。)
  • 查看微软提供的文档,例如Walkthrough: Updating the MFC Scribble Application (Part 1)。附带完整源代码。

标签: c++ visual-c++ mfc


【解决方案1】:

我不确定我是否理解您要执行的操作。 CView 有一个名为 OnDraw 的虚拟方法。这是您必须重写的方法:

void CMyView::OnDraw(CDC* pDC)
{
  CMyDoc* pDoc = GetDocument();
  ASSERT_VALID(pDoc);
  if (!pDoc)
    return;

  // first erase the entire client rectangle
  CRect cr;
  GetClientRect( &cr );
  pDC->FillSolidRect( cr, RGB( 255, 255, 255 ) );

  // your actual drawing goes here
  pDC->Rectangle( 0, 0, 100, 100 );
}

您还必须写OnEraseBkgnd

BOOL CMyView::OnEraseBkgnd( CDC* /*pDC*/ )
{
  return TRUE; // we fill the client rectangle in OnDraw
}

此外,您似乎正在尝试实施临时内存 DC。已经有一个了:CMemDC

【讨论】:

    猜你喜欢
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多