我打算创建一个有2个窗口的小应用程序,一个带控件的普通窗口和一个3D窗口,用DirectX渲染。对于3D窗口,建议使用PeekMessage()
,因为它不会在检查消息后等待,但对于普通窗口(没有3D渲染),使用GetMessage()
函数以避免处理器无谓的过度使用。因此,当3D窗口激活时(WM_ACTIVE
消息收到),我想使用PeekMessage()
,当正常窗口激活时,我想使用GetMessage()
。
主循环是这样的:
NormalWindowActive = false;
Window3DActive = false;
MSG msg;
while (TRUE) {
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (NormalWindowActive) {
if (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} else {
RenderWindow();
}
}
在这些窗口的消息处理程序,我有WM_ACTIVATE
消息:
HWND NormalWindow, Window3D; // These windows are global vars
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
// ...
case WM_ACTIVATE:
if (wParam!= WA_INACTIVE) {
if (hWnd == NormalWindow) {
NormalWindowActive = true;
Window3DActive = false;
} else {
Window3DActive = true;
NormalWindowActive = false;
}
}
break;
// ...
}
我对TaskManager的期望是当3D窗口处于活动状态时显示应用程序繁忙(~50%的处理器使用),而当正常窗口处于活动状态时显示应用程序不那么繁忙(~5%的处理器使用)。当两个窗口都失去焦点时,我只看到50%的处理器使用,但当其中任何一个窗口都处于活动状态时,我看到0-5%的处理器使用。我认为应该有所不同,所以我不确定这是否真的有效(甚至可能)。3D窗口被渲染,普通窗口也响应事件,但是处理器的使用让我感到困惑。我只是不希望这影响到3D窗口的FPS
与其检查正常窗口是否处于活动状态,不如检查3D窗口是否处于非活动状态。您也可以使用WaitMessage
代替GetMessage
,因为它可以避免重复代码。
if (Window3DActive)
RenderWindow();
else
WaitMessage();
您的问题似乎是,当正常窗口处于非活动状态时,即使3D窗口处于非活动状态,消息循环也不会等待。
如果您决定使用WaitMessage
,您也应该循环PeekMessage
,因为队列中可能有多个消息,并且WaitMessage
在有新消息到达之前不会返回。