Cow Nation
Cow Nation

Reputation: 91

DX9 Desktop Window Manager High CPU

Desktop Window Manager Uses A Ton Of CPU When Drawing DX9 Window. I'm Not Sure Why It Is Using So Much CPU https://i.sstatic.net/Xa71K.jpg

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;

}

ref class CMAIN { public: void 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);
}

}

Upvotes: 1

Views: 380

Answers (1)

Varrak
Varrak

Reputation: 768

It would be useful to get some more information around what you're trying to do, and it's also hard to see exactly what could be going on with the WM_PAINT handler in your code (since you call a function called Render but don't provide that code). But at first glance I think there's at least one thing that's going to force high CPU usage, and that's your message loop. You're basically spinning in that loop due to calling PeekMessage, with a call to Sleep(12) which will basically give you a ~80fps update on that window; since you're using the DWM composition code (DwmExtendFrameIntoClient) my guess is that you're triggering a 80Hz update in DWM because of that. If you're rendering something in realtime in that loop, then that's all to be expected and not avoidable (unless you put your rendering loop on a separate thread). But if you're just responding to WM_PAINT messages then you'd be better served using a message pump that's using GetMessage rather than PeekMessage, since GetMessage will suspend the thread when the Windows message queue is empty, and you'll only trigger CPU work when something needs to be updated.

Upvotes: 0

Related Questions