2011-09-03 46 views
2

我仍然是使用C++ winapi32編程GUI的初學者,並且發現了一些奇怪的東西。 這裏是我的代碼的一部分:Sleep()在winapi32中不起作用?

 InvalidateRect(hwnd,&rect, true); 
     //Sleep(delay); 
     MessageBox(hwnd, "Blahblah!", "blahblah",MB_OK | MB_ICONINFORMATION); 
     InvalidateRect(hwnd,&rect, true); 
     //Sleep(delay); 
     MessageBox(hwnd, "Blahblah!", "blahblah",MB_OK | MB_ICONINFORMATION); 

我用Invalidaterect重繪我的窗戶的一部分,我想要做的是重新繪製窗口每1秒左右進行更改明顯用戶的眼睛。奇怪的部分是,睡眠似乎不會影響我的窗口,如果它沒有跟隨MessageBox命令,而實際上我不想有任何MessageBox命令爲每個重新繪製,因爲它太令人不安。

我已經嘗試了1000,2000甚至10000的延遲。 The windoes was sleeping with the sleep,but the repainting is only done 1x in the last Sleep command ...

此代碼是void A()的一部分。而void A()被void B()調用。

 //Message loop 
     if(turn == 0) 
     { 
     B(); 
     }   

有沒有其他辦法可以解決這個問題?

噢,我使用微軟的Visual C++ 2008年速成的方式

預先感謝對於這件事:)

+3

你嘗試過什麼'delay'值? – wallyk

+0

如果沒有MessageBox命令,1000,2000,甚至10000也不會產生任何效果......我的意思是'沒有效果'是:假設有3個重畫命令,後面跟着3個休眠命令,每個視窗只是凍結3倍的延遲,重繪只在最後一次完成1次....但如果我還爲每個睡眠命令添加MessageBox命令,顯然窗戶確實重新繪製了3次......有幫助嗎? – zia

+9

這在Windows GUI編程中非常重要。在泵送消息循環之前不會出現塗料。把鍵盤拿開並讀一本書。 –

回答

6

重要的事情是任何幫助,那InvalidateRect不畫任何東西。它僅調度要繪製的窗口內容(將WM_PAINT消息排入消息隊列)。直到您返回到消息循環並且實際上窗口才會處理消息,實際繪圖纔會發生。因此,在最後一次Sleep/MessageBox之後,您最終從函數返回以再次到達消息循環,並在消息循環中最終獲得代表實際繪製事件的WM_PAINT消息,並處理此消息以重繪窗口的內容。

+0

我明白了,但是當我在第一行WM_PAINT情況下放入Sleep時,爲什麼程序似乎表現相同?我的意思是,我只能看到最後的重繪,但它被稱爲無數次。預先感謝您:) – zia

+0

@zia'InvalidateRect'只調度要繪製的窗口(告訴Win32,這個窗口的內容是無效的)。事實上,當窗口應該做更重要的事情時,繪畫事件的優先級非常低,而不是垃圾郵件重繪事件。而且Win32足夠智能,只能將一個繪圖消息放入消息隊列中。所以當你調用InvalidateRect並且在消息隊列中已經有一個WM_PAINT時,Win32會將這個請求合併到前一個請求中(將rects合併成一個可能更大的包含兩者的rect),所以你總是隻有一個paint事件,直到你處理它。 –