c ++ gdi绘制椭圆问题

时间:2010-08-09 22:55:24

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

好吧我可以绘制椭圆问题就是这个,我试图绘制一个椭圆但是将其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);
}

我认为无效的rect会清除所有已绘制的内容并重新绘制但不起作用

3 个答案:

答案 0 :(得分:0)

您不应该尝试一次性绘制多个动画帧。

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

Invalidate会再次触发OnPaint()

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

答案 1 :(得分:0)

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

使用InvalidateRect作为生成WM_PAINT的方法似乎有点过头了,它会做得更多。相反,您可以直接在OnTimer调用中绘制,因为它位于WM_PAINT之外,您需要使用GetDC获取设备上下文。

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

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

答案 2 :(得分:-1)

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

您的onPaint功能仅绘制,不会删除。由于你的循环永远不会退出,因此消息泵永远不会运行。

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