2010-08-09 173 views
0

好的我可以绘制椭圆问题是这样的,即时试图绘制一个椭圆,但将其x值更改为不同的。这样我画一个椭圆形和X值是1 10秒后,我想它的x值是10,但似乎创造IM X的值设定新的椭圆10.这里是我的代码C++ gdi绘制椭圆问题

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将清除所有已被绘制并重新绘制,但它不起作用

回答

0

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

使用InvalidateRect作为生成WM_PAINT的一种方法看起来过于夸张,它会做得更多。相反,您可以直接在OnTimer调用中绘图,因为它不在WM_PAINT中,您需要使用GetDC获取设备上下文。

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

DrawFrame将清除背景(可能带有FillRect),并在新位置绘制圆圈。如果面积很大,会闪烁,以避免它,因为汤姆建议您可以使用内存DC和HBITMAP作为双缓冲区。

+0

好的感谢细节,但你能给我一个例子如何使用getDC和我应该使用什么函数来更新 – Ramilol 2010-08-10 00:03:33

+0

这真的很容易'HDC hDC = GetDC (hWnd)'检查http://msdn.microsoft.com/en-us/library/dd144871(VS.85).aspx。你应该更新OnTimer的时候,你会有一个平滑的动画。 – Ismael 2010-08-10 21:07:59

0

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

保存您的变量sf的地方,并在OnPaint(),增加sf,绘制一个椭圆,并调用Invalidate()

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

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

+0

好吧,它吸引了更多的一个和sf是golabe varabile – Ramilol 2010-08-09 23:22:10

-1

InvalidateRect将该窗口标记为“无效”,但这不会导致擦除和重绘立即发生。只有当消息泵运行时(例如,与GetMessageDispatchMessage一起循环),擦除和绘画才会发生。当消息队列干运行时,GetMessage将合成无效窗口的WM_ERASEBKGNDWM_PAINT消息。当这些消息被发送到窗口过程时,窗口有机会绘制。

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

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

+0

任何人都可以解释为什么这篇文章downvoted?它解释了为什么InvalidateRect不能按提问者预期的方式工作。 – 2010-08-30 16:40:10