WinAPI C++ GDI черный экран через некоторое время работы

230
21 ноября 2017, 23:58

Программа работает некоторое время корректно, но потом без видимых причин просто превращает кадр в черный квадрат. Грешил на переполнение стэка, но поиски не увенчались успехом

void Paint(PAINTSTRUCT &ps) // Отрисовка
{
    HDC hMemDC, hTempDC; // Теневой буффер
    HGDIOBJ hMemBmp, hSysBmp;
    hMemDC = CreateCompatibleDC(ps.hdc); // Создать конекст схожии с основным
    hMemBmp = CreateCompatibleBitmap(ps.hdc, sizeX, sizeY);
    hSysBmp = SelectObject(hMemDC, hMemBmp);
    SetViewportOrgEx(hMemDC, sizeX / 2, sizeY / 2, nullptr);
    // Отрисовка фона
    hTempDC = CreateCompatibleDC(ps.hdc);
    SelectObject(hTempDC, BGround);
    BitBlt(hMemDC, -sizeX / 2, -sizeY / 2, sizeX, sizeY, hTempDC, 0, 0, SRCCOPY);
    SelectObject(hTempDC, hSysBmp);
    DeleteDC(hTempDC);
    // Отрисовка наполнения
    for (UINT i = 0; i < PlanetOrigin.size(); i++)
        PlanetOrigin[i].Draw(hMemDC);
    SunOrigin->Draw(hMemDC);
    if (RESET)
        for (UINT i = 0; i < KometOrigin.size(); i++)
            KometOrigin[i].Draw(hMemDC);
    PaintButtons(hMemDC); // Отрисовка кнопок
    BitBlt(ps.hdc, 0, 0, sizeX, sizeY, hMemDC, -sizeX / 2, -sizeY / 2, SRCCOPY); // Отправка в основной контекст
    SelectObject(hMemDC, hSysBmp);
    DeleteObject(hMemBmp); // Удаление Битмапа
    DeleteDC(hMemDC); // Удаление контекстов
    if (GAME) // ИГра?
        Mathematic(); // Расчеты
}

Есть еще обработка колесика мышки, которая изменяет размеры bitmap в реальном времени

if (GET_WHEEL_DELTA_WPARAM(wParam) > 0) // Если движение вверх
            {
                if (SIZABLE >= 10) // Не превышает ли допустимого значения
                    break;
                SIZABLE++;
                for (UINT i = 0; i < PlanetOrigin.size(); i++) // Для планет
                {
                    PlanetOrigin[i].Resize(true);
                    PlanetOrigin[i].ResizeOrbit(true);
                }
                SunOrigin->Resize(true); // Для солнца
                for (UINT i = 0; i < KometOrigin.size(); i++) // Для комет
                {
                    KometOrigin[i].Resize(true);
                    KometOrigin[i].ResizeCoord(true);
                }
            }
void ObjectGalaxy::Resize(bool direction) // Изменение размеров (перерасчеты в основном)
{
    size = (direction ? size*sZoom : size / sZoom); // Новый размер
    gravity_rad = (direction ? gravity_rad*sZoom : gravity_rad / sZoom); // Новый радиус гравитации
    gravity_f = (direction ? gravity_f*sZoom : gravity_f / sZoom); // Новая сила гравитации
    DeleteObject(hBitmap);
    hBitmap = (HBITMAP)CopyImage(hOrigin, IMAGE_BITMAP, (int)size, (int)size, LR_COPYRETURNORG); // Из оригинального изображения делаем итоговое через сжатие
    GetObject(hBitmap, sizeof(BITMAP), &bitmap); // Для получения реальной информации о битмапе
}

Отрисовка для всех объектов, кроме фона:

void ObjectGalaxy::DrawObject(HDC hdc)
{
    if (this->GetDrawChance())
        return;
    HDC hMem = CreateCompatibleDC(hdc); // Соотнесение с полученным контекстом
    HGDIOBJ hOld = SelectObject(hMem, hBitmap); // Двойная буферизация
    TransparentBlt(hdc, (int)position.first - bitmap.bmWidth / 2, (int)position.second - bitmap.bmHeight / 2, bitmap.bmWidth, bitmap.bmHeight, hMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, RGB(0, 0, 0)); // Копирование с пропуском белого
    SelectObject(hMem, hOld);
    DeleteDC(hMem); // Удаление контекста
}

В итоге изображение заменяется на черный прямоугольник

Answer 1

Да, проблема, как заметил mega, оказалась в утечке GDI-объектов. Советую использовать программу типа GDIVIEW для отслеживания ресурсов (ведет она себя, конечно, странно, но серьезные утечки продемонстрирует сразу)

READ ALSO
Рисуем свою кнопку

Рисуем свою кнопку

Рисую свою кнопку так:

208
Помогите понять условие задания

Помогите понять условие задания

Создать иерархию классов представляющих простое наследованиеБазовый класс – строка символов (char *)

225
Проектирование контакт листа Qt

Проектирование контакт листа Qt

Нужно написать контакт лист для мессенджераДля этого пытаюсь правильно все спроектировать для удобной работы и простого расширения

233
Try to build app with qt ld errors, ljasper, lQt5PlatformSupport [требует правки]

Try to build app with qt ld errors, ljasper, lQt5PlatformSupport [требует правки]

I'm trying to compile a program, on windows with cmake, and get qt linker errors

241