首页 > 解决方案 > 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://docs.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!

标签: c++winapibitmap

解决方案


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.


推荐阅读