[英]Correct method for redrawing a layered window
我有一個使用WS_EX_LAYERED
窗口樣式創建的窗口。 目前,我正在使用GDI +繪制內存位圖,並使用UpdateLayeredWindow
更新分層窗口的圖形內容。 我打算將此窗口用作應用程序的主窗口,這將要求它經常重繪。
看到分層窗口沒有收到WM_PAINT
窗口消息[?] ,我需要提出一種適當的方法來重新繪制窗口。 優化不是必不可少的 ,但是吃蛋糕也總是很高興。 因此,我正在尋找要使用的“正確”方法。
到目前為止,這是我的想法:
我想這是在BitBlt
或類似方法之前渲染到屏幕外位圖的好主意。
每秒渲染60幀應該足夠(超過?)(但這與其他應用程序的幀率相比如何?)。
可能的解決方案:
之所以有用,是因為通過指定超時值,我可以每秒實現所需的幀數,而無需測量渲染“幀”所需要的持續時間。
由於消息的頻率和速度,可能會導致輸入或其他延遲。
僅在發生特定事件(例如窗口調整大小)時才渲染幀。
需要我找出所有需要重畫的事件。
將大大減少呈現的不必要幀的數量。
通過檢查PeekMessage
,在消息隊列中沒有消息時渲染幀。
這可能會減慢窗口消息的處理。
這將導致較高的CPU使用率,因為正在處理的幀超出了必要。
創建一個新線程以執行渲染循環。
分層的窗口不會接收WM_PAINT
消息,否則該消息會在窗口可見性更改后生成,但完全不會阻止它們接收此消息。
您可以繼續使用InvalidateRect
更改窗口更新區域,在窗口過程中等待WM_PAINT
, UpdateLayeredWindow
圖中繪制內容,然后調用UpdateLayeredWindow
更改窗口內容。 您可以使用此方法在窗口內容更改時(例如,當按下按鈕或調整窗口大小(或激活/停用)時)請求重繪。
它不應該那么復雜,這是消息循環的偽代碼:
while (true)
{
// GetMessages
while (PeekMessage(&msg, hWnd, 0, 0, PM_NOREMOVE))
{
if (!GetMessage(&msg, hWnd, 0, 0 ))
{
// Need to handle WM_QUIT
...
break;
}
TranslateMessage( &msg );
DispatchMessage( &msg );
}
// Check if we need to draw
if (TimeForANewFrameHasCome() ||
IfWeNeedToDrawAfterInputOrInvalidate() ||
AnyOtherCaseThatCausesAnUpdate())
{
// Render
UpdateMemoryDCOrBitmap(...);
// Display it
UpdateLayeredWindow(...);
}
// May sleep a while
// Either Sleep(20); or better MsgWaitForMultipleObjects, that makes it possible
// to wake up upon an Event too...
MsgWaitForMultipleObjects(...);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.