C++ GDI+ Рисование изображения в многослойном окне не работает

Итак, я нашел много примеров кода, руководств и ответов на SO о рисовании изображения в многоуровневом окне. Я пытался использовать чистый HBITMAPS и WIC любят рисовать, и теперь я нахожусь в GDI+ для рисования (что гораздо проще и, казалось бы, проще в использовании, и до сих пор оно решило множество ошибок, которые были вызваны ошибочным кодом WIC).

Я в настоящее время застрял на UpdateLayeredWindow, Что бы я ни пытался, я не могу заставить его работать. Прямо сейчас возвращается 87, или ERROR_INVALID_PARAMETER, Вопрос в том, какой из них неверен? Я в тупике! Приведенный ниже код является решением, отличным от того факта, что UpdateLayeredWindow отказывается работать.

Что я делаю неправильно?

Вот код, который устанавливает HDC/ растровую информацию / графический объект.

// Create DC
_oGrphInf.canvasHDC = GetDC(_hwndWindow);

// Create drawing 'canvas'
_oGrphInf.lpBits = NULL;
_oGrphInf.bmpCanvas = CreateDIBSection(_oGrphInf.canvasHDC,
            &_oGrphInf.bmpWinInformation, DIB_RGB_COLORS,
            &_oGrphInf.lpBits, NULL, 0);

// Create graphics object
_oGrphInf.graphics = new Gdiplus::Graphics(_oGrphInf.canvasHDC);

Выше работает нормально - я перехожу через него, и все указатели работают.

А вот метод, который рисует PNG.

void Splash::DrawPNG(PNG* lpPNG, int x, int y)
{
    LOGD("Drawing bitmap!");

    HDC hdcMem = CreateCompatibleDC(_oGrphInf.canvasHDC);

    // Select
    HBITMAP bmpOld = (HBITMAP)SelectObject(hdcMem, _oGrphInf.bmpCanvas);

    Gdiplus::Color trans(0, 0, 0, 0);
    _oGrphInf.graphics->Clear(trans);

    _oGrphInf.graphics->DrawImage(lpPNG->GetImage(), x, y);

    _oGrphInf.graphics->Flush();

    SIZE szSize = {_oGrphInf.bmpWinInformation.bmiHeader.biWidth,
                    _oGrphInf.bmpWinInformation.bmiHeader.biHeight};

    // Setup drawing location
    POINT ptLoc = {0, 0};
    POINT ptSrc = {0, 0};

    // Set up alpha blending
    BLENDFUNCTION blend = {0};
    blend.BlendOp = AC_SRC_OVER;
    blend.SourceConstantAlpha = 255;
    blend.AlphaFormat = AC_SRC_ALPHA;
    blend.BlendFlags = 0;

    // Update
    if(UpdateLayeredWindow(_hwndWindow, _oGrphInf.canvasHDC, &ptLoc,
                                &szSize, hdcMem, &ptSrc,
                                (COLORREF)RGB(0, 0, 0),
                                &blend, ULW_ALPHA) == FALSE)
        LOGE("Could not update layered window: %u", GetLastError());

    // Delete temp objects
    SelectObject(hdcMem, bmpOld);
    DeleteObject(hdcMem);
    DeleteDC(hdcMem);
}

Выдернуть мои волосы! Помогите?

РЕДАКТИРОВАТЬ: я просто решил переписать вызов UpdateLayeredWindow функция, которая решает проблему с неверным параметром. Вот что я придумал. Тем не менее, это все еще не работает. Что я делаю неправильно?

UpdateLayeredWindow(_hwndWindow, _oGrphInf.canvasHDC,
            NULL, NULL, hdcMem, &ptLoc,
            RGB(0, 0, 0), &blend, ULW_ALPHA)

1 ответ

Решение

Чтобы альфа-информация сохранялась в операциях рисования, вы должны сделать свой объект Graphics на основе объекта Bitmap с поддержкой памяти, а не HDC, и, конечно, ваше Bitmap должно быть в формате с альфа-каналом.

Вам нужно будет использовать этот конструктор растровых изображений: http://msdn.microsoft.com/en-us/library/ms536315%28v=vs.85%29.aspx

Просто дайте ему шаг 0, указатель на биты вашей DIB и PixelFormat32bppPARGB.

Затем используйте Graphics::FromImage для создания вашего объекта Graphics.

Я никогда не использовал UpdateLayeredWindow, поэтому я не могу убедиться, что эта сторона верна.

Другие вопросы по тегам