2010-08-09 85 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