【问题标题】:How to repaint in CDC::OnDraw()?如何在 CDC::OnDraw() 中重绘?
【发布时间】:2013-10-05 22:57:56
【问题描述】:

我想更新窗口(删除之前的绘图)并使用 x2,y2 的新值重新绘制。我从相机中得到 x2 和 y2,它们是手坐标,我想根据手坐标的新值绘制椭圆。我该怎么做?

我尝试调用 Invalidate()、RedrawWindow() 和 UpdateWindow(),但它们似乎都不起作用。以下是我的一段代码。

     int x2,y2 // Global Variables (used to store coordinates of the hand)
     void GesturePipe()
      {
         x2=Hand.Coordinate.x;
         y2=Hand.Coordinate.y;

         // I get x2,y2 from a camera
      }


     void CLesson1View::OnDraw(CDC* pDC)
     {
    while(1)
      {
        GesturePipe();
        CLesson1Doc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
        if (!pDoc)
    return;
        COLORREF colorCircle= RGB(255,0,0); 
        pDC->Ellipse(0,0,(int) x2,(int) y2);
       //I intend to draw the skeleton of the hands so i would draw five lines,which  will get updated with each frame
        Invalidate(TRUE);
        UpdateWindow();

}

}

【问题讨论】:

  • 自从我进行 MFC GDI 绘图以来,它一直 永远,但我记得,OnDraw() 方法是使用适当准备的设备上下文调用的,以便您直接在其上渲染. IE。您的 Invalidate()UpdatedWindow() 是多余的。你在 here 的原因是一个区域已经失效并且需要更新(OnDraw() 方法应该处理)。简而言之,这是一种在圆形绘画信息中永久旋转的快速方法。 OnDraw() 应该简单地呈现 current 状态。
  • “不起作用” 不是一个充分的错误描述。除了通过从您的OnDraw 处理程序调用UpdateWindow() 可能引发无限递归之外,您的处理程序中有一个while(1) 循环。如果您决定永远停留在绘画循环中,您就不能希望您的应用程序能够处理用户输入。
  • 在 xMri 的回答后实现了.. 它现在正在工作。谢谢大家。
  • @Dexteroid CN:在这种情况下,如果给出答案,设置线程回答是一个很好的实践!

标签: winapi visual-c++ mfc gdi


【解决方案1】:
  1. 切勿将 UpdateWindow 放在 OnDraw 或 OnPaint 中。这会导致递归!
  2. 当您希望窗口反映新内容时,您必须在识别更改的函数中调用 Invalidate。 无效将导致调用新的 OnDraw 循环... 因此,当识别出新手势时,获取它,为您的 doc/view 调用 Invalidate 设置新值。
  3. Ondraw 上有一个无限循环。这样做可以防止额外的 Windows 消息从队列中抽出并执行。所以你的程序是块。

也许您应该先阅读一些标准教程,了解 Windows 输入和绘图的工作原理。

【讨论】:

    猜你喜欢
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    相关资源
    最近更新 更多