Ballers
Ballers

Reputation: 13

Win32 Window Doesn't Draw After minute or so

I am in a sticky situation.

I'm messing around with Bitmaps and windows.

I followed this tutorial: https://learn.microsoft.com/en-us/windows/win32/gdi/capturing-an-image

I am basically taking multiple pictures of my desktop and displaying them into a window.

It works great as intended but after like a minute or 2 the window won't update and I can't find the error or why this is occurring.

Here is the code:

 LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
    case WM_DESTROY: {
        PostQuitMessage(0); // Exit the program if the window gets closed.
    } break;
    case WM_SIZE: {
    } break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam); // Handle any messages the switch statement didn't
}

HWND SpawnWindow() {
    WNDCLASSEX WindowClass;
    SecureZeroMemory(&WindowClass, sizeof(WNDCLASSEX));
    WindowClass.cbClsExtra = NULL;
    WindowClass.cbWndExtra = NULL;
    WindowClass.cbSize = sizeof(WNDCLASSEX);
    WindowClass.style = CS_HREDRAW | CS_VREDRAW;
    WindowClass.lpfnWndProc = WinProc;
    WindowClass.hInstance = NULL;
    WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WindowClass.hIcon = LoadIcon(0, IDI_APPLICATION);
    WindowClass.hIconSm = LoadIcon(0, IDI_APPLICATION);
    WindowClass.hbrBackground = NULL;
    WindowClass.lpszClassName = L"Class NAme";
    WindowClass.lpszMenuName = L"Menu Name";

    RegisterClassEx(&WindowClass);

    return CreateWindowEx(NULL, L"Class Name", L"Window Title", WS_VISIBLE | WS_TILEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
}

void DoMessages() {
    MSG msg = {};
    while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    std::cout << msg.message << "\n";
}

int main() {
    HWND WindowToGetPic = SpawnWindow();

    HDC DesktopDC = GetDC(0);
    HDC WindowDC = GetDC(WindowToGetPic);

    if (!DesktopDC)
        std::cout << "DC NULL!\n";

    HDC TempDC = CreateCompatibleDC(DesktopDC);
    HDC TempDCWindow = CreateCompatibleDC(WindowDC);

    if (!TempDC)
        std::cout << "TempDC NULL!\n";

    while (true) {
        /*

            after calling CreateCompatibleDC you mus then call CreateCompatiableBitmap with the DC recieved
            then call SelectObject

        */
        HBITMAP hBitmap = CreateCompatibleBitmap(TempDC, 1920, 1080);/* screen res */

        SelectObject(TempDC, hBitmap);

        SetStretchBltMode(TempDC, HALFTONE);

        RECT WindowDimensions;
        GetClientRect(WindowToGetPic, &WindowDimensions);

        if (!BitBlt(WindowDC, 0, 0, WindowDimensions.right - WindowDimensions.left, WindowDimensions.bottom - WindowDimensions.top, DesktopDC, 0, 0, SRCCOPY))
            std::cout << "BitBlt ERROR\n";

        DoMessages();
        InvalidateRect(WindowHwnd, NULL, TRUE);
    }
    std::cin.ignore();

    return 0;
}

If anyone could test this, or spot why the window doesn't update after a minute or two I would really appreciate it.

Thank you in advance!

Upvotes: 0

Views: 215

Answers (2)

catnip
catnip

Reputation: 25388

You have several resource leaks:

  • when you are done with an HDC returned by GetDC, call ReleaseDC

  • when you are done with an HDC returned by CreateCompatibleDC, call DeleteDC

  • when you are done with hBitmap, select the original bitmap back into the DC and call DeleteObject. The original bitmap is returned by SelectObject.

This is all covered in the documentation (Google will find it).

Upvotes: 1

Evgeny
Evgeny

Reputation: 1072

I think you have spent all resources. For example,

You create bitmap every cycle and don't release it.

You call SelectObject and don't return selected object to original state.

Upvotes: 2

Related Questions