【问题标题】:c++ gdi drawing ellipse problemc++ gdi画椭圆问题
【发布时间】:2011-03-27 13:34:38
【问题描述】:

好的,我可以画椭圆问题是这样的,我试图画一个椭圆,但将它的 x 值更改为不同的。像这样我画了一个椭圆,十秒后x值为1我希望x值为10但似乎我创建了x值为10的新椭圆。这是我的代码

while(sd==1)//sd equal 1 
{
    sf++;//sf equals 1
    onPaint(hdc);
    InvalidateRect(hWnd,0,true);
}
//on paint function
VOID onPaint(HDC hdc)
{
   Graphics graphics(hdc);
   Pen      pen(Color(255, 0, 0, 255));
   graphics.DrawEllipse(&pen,sf , 0, 50, 50);
}

我认为无效的矩形会清除所有已绘制的内容并重新绘制它,但它没有用

【问题讨论】:

    标签: c++ visual-c++ graphics gdi


    【解决方案1】:

    如果你想制作动画,最好设置一个计时器。

    使用 InvalidateRect 作为生成 WM_PAINT 的一种方式似乎有点过头了,它的作用远不止于此。相反,您可以直接在 OnTimer 调用中绘制,因为它在 WM_PAINT 之外,您需要使用 GetDC 获取设备上下文。

    例如,如果您可以使用函数 DrawFrame(HDC hDC)。 OnTimer 将更新当前位置并调用 DrawFrame,OnPaint 将调用 DrawFrame 但不会更新位置(这样,如果您想停止动画,您将获得最后一帧绘制)。

    DrawFrame 将清除背景(可能使用 FillRect),并在新位置绘制圆。如果你有一个大的区域,这会闪烁,为了避免它,正如 Tom 建议的那样,你可以使用内存 DC 和 HBITMAP 作为双缓冲区。

    【讨论】:

    • 好的,谢谢你的详细信息,但你能给我一个例子如何使用 getDC 以及我应该使用什么函数来更新
    • 这真的很容易HDC hDC = GetDC(hWnd)检查msdn.microsoft.com/en-us/library/dd144871(VS.85).aspx。您应该在触发 OnTimer 时进行更新,这样您将获得流畅的动画。
    【解决方案2】:

    您不应该尝试在一个镜头中绘制多个动画帧。

    将变量 sf 保存在某处,然后在 OnPaint() 中递增 sf,绘制一个椭圆,然后调用 Invalidate()

    Invalidate 将触发 OnPaint() 再次被调用。

    这应该可以,但会非常闪烁:) 您可以通过双缓冲来修复闪烁。

    【讨论】:

    • 它画的不止一个,sf 是 golabe varabile
    【解决方案3】:

    InvalidateRect 将窗口标记为“无效”,但这不会导致擦除和重绘立即发生。擦除和绘制仅在消息泵运行时发生(例如,GetMessageDispatchMessage 的循环)。当消息队列耗尽时,GetMessage 将为无效窗口合成WM_ERASEBKGNDWM_PAINT 消息。当这些消息被分派到窗口过程时,窗口就有机会绘制。

    您的onPaint 函数只会绘制,不会擦除。而且由于您的循环永远不会退出,因此消息泵永远不会运行。

    对于简单的动画,解决方法是SetTimer。在WM_TIMER 消息的处理程序中,更新单帧变量,调用InvalidateRect,然后返回(让消息泵继续运行)。擦除和绘画消息将发生,然后计时器将再次触发,您将获得下一帧。

    【讨论】:

    • 谁能解释为什么这篇文章被否决了?它解释了为什么 InvalidateRect 不能按提问者预期的方式工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多