【问题标题】:DX9 Desktop Window Manager High CPUDX9 桌面窗口管理器高 CPU
【发布时间】:2018-05-13 08:08:02
【问题描述】:

桌面窗口管理器在绘制 DX9 窗口时使用大量 CPU。 我不确定为什么它使用这么多 CPU https://imgur.com/a/Bz7AVro

LRESULT CALLBACK WinProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam){
Sleep(12);
switch (Message){   
case WM_PAINT:
    Render();
    break;

case WM_CREATE:
    DwmExtendFrameIntoClientArea(hWnd, &Margin);
    break;

case WM_DESTROY:
    PostQuitMessage(1);
    return 0;

default:
    return DefWindowProc(hWnd, Message, wParam, lParam);
    break;
}
return 0;

}

参考类 CMAIN { 上市: 无效 StartIt() { Main(); } };

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hSecInstance, LPSTR nCmdLine, INT nCmdShow){

Thread^ main;
CMAIN^ cMain = gcnew CMAIN();
main = gcnew Thread(gcnew ThreadStart(cMain, &CMAIN::StartIt));
main->Name = "main";
main->Start();

CreateThread(0, 0, (LPTHREAD_START_ROUTINE)SetWindowToTarget, 0, 0, 0);

WNDCLASSEX wClass;
wClass.cbClsExtra = NULL;
wClass.cbSize = sizeof(WNDCLASSEX);
wClass.cbWndExtra = NULL;
wClass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 0, 0));
wClass.hCursor = LoadCursor(0, IDC_ARROW);
wClass.hIcon = LoadIcon(0, IDI_APPLICATION);
wClass.hIconSm = LoadIcon(0, IDI_APPLICATION);
wClass.hInstance = hInstance;
wClass.lpfnWndProc = WinProc;
wClass.lpszClassName = lWindowName;
wClass.lpszMenuName = lWindowName;
wClass.style = CS_VREDRAW | CS_HREDRAW;

if(!RegisterClassEx(&wClass))
    exit(1);

tWnd = FindWindow(0, tWindowName);
if (tWnd){
    GetWindowRect(tWnd, &tSize);
    Width = tSize.right - tSize.left;
    Height = tSize.bottom - tSize.top;
    hWnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_TRANSPARENT | WS_EX_LAYERED, lWindowName, lWindowName,  WS_POPUP, 1, 1, Width, Height, 0, 0, 0, 0);
    SetLayeredWindowAttributes(hWnd, 0, 1.0f, LWA_ALPHA);
    SetLayeredWindowAttributes(hWnd, 0, RGB(0, 0, 0), LWA_COLORKEY);
    ShowWindow( hWnd, SW_SHOW);
}

DirectXInit(hWnd);

while (!directXExit){
    Sleep(12);
    if(PeekMessage(&Message, hWnd, 0, 0, PM_REMOVE)){
        DispatchMessage(&Message);
        TranslateMessage(&Message);
    }
}
return 0;

}

void SetWindowToTarget(){

while(true){

    tWnd = FindWindow(0, tWindowName);
    if (tWnd){

        GetWindowRect(tWnd, &tSize);
        Width = tSize.right - tSize.left;
        Height = tSize.bottom - tSize.top;
        DWORD dwStyle = GetWindowLong(tWnd, GWL_STYLE);
        if(dwStyle & WS_BORDER){
            tSize.top += 23;
            Height -= 23;
        }
        MoveWindow(hWnd, tSize.left, tSize.top, Width, Height, true);
    }
    Sleep(1500);
}

}

【问题讨论】:

    标签: c++ visual-studio directx directx-9


    【解决方案1】:

    获取更多关于您正在尝试做的事情的信息会很有用,而且很难确切地看到代码中的 WM_PAINT 处理程序会发生什么(因为您调用了一个名为 Render 的函数但不要提供该代码)。但乍一看,我认为至少有一件事会导致 CPU 使用率过高,那就是你的消息循环。由于调用PeekMessage,你基本上在那个循环中旋转,调用Sleep(12),这基本上会给你在那个窗口上大约80fps的更新;由于您使用的是 DWM 组合代码 (DwmExtendFrameIntoClient),因此我猜测您正在触发 DWM 中的 80Hz 更新。如果您在该循环中实时渲染某些内容,那么这一切都是可以预料的,并且是无法避免的(除非您将渲染循环放在单独的线程上)。但是,如果您只是响应WM_PAINT 消息,那么使用使用GetMessage 而不是PeekMessage 的消息泵会更好,因为GetMessage 将在Windows 消息队列为空时挂起线程,并且您只会在需要更新某些内容时触发 CPU 工作。

    【讨论】:

      猜你喜欢
      • 2010-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      相关资源
      最近更新 更多