我有一个使用WS_EX_LAYERED
窗口样式创建的窗口。我目前正在使用GDI +绘制内存位图,并使用UpdateLayeredWindow
更新我的分层窗口的图形内容。我打算使用这个窗口作为我的应用程序的主窗口,这需要它经常重绘。
看到分层窗口没有收到WM_PAINT
窗口消息[?],我需要想出一个适当的方法来重新绘制窗口。优化不是必需,但是总是很好吃蛋糕并吃它。因此,我正在寻找使用的“正确”方法。
到目前为止,我的想法是:
我猜想在BitBlt
或类似之前渲染到屏幕外的位图是个好主意。
每秒渲染60帧应该(大于?)足够(但这与其他应用程序的帧速率相比如何?)。
可能的解决方案:
很有用,因为通过指定超时值,我可以达到每秒所需的帧数,而不需要测量“帧”渲染的持续时间。
由于信息的频率和速度,可能会导致输入或其他滞后。
仅在发生特定事件时渲染帧,例如调整窗口大小。
需要我弄清楚所有需要重绘的事件。
会大大减少呈现的不必要帧的数量。
通过选中PeekMessage
,在消息队列中没有消息时呈现帧。
此可能会减慢窗口消息的处理速度。
这会导致CPU使用率过高,因为正在处理的帧数超出必要范围。
创建一个新线程来执行渲染循环。
答案 0 :(得分:1)
分层窗口不会收到WM_PAINT
消息,否则会在窗口可见性发生变化后生成这些消息,但它不会阻止它们接收此消息。
您可以继续使用InvalidateRect
更改窗口更新区域,在窗口过程中等待WM_PAINT
,在位图中绘制内容并调用UpdateLayeredWindow
以更改窗口内容。当窗口内容发生变化时,您可以使用此方法请求重绘,例如,按下按钮,或者窗口已调整大小(或激活/取消激活)。
答案 1 :(得分:0)
它应该不是那么复杂,这是你的消息循环的伪代码:
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(...);
}