BitBlt + UpdateLayeredWindow и CreateDIBSection с глубиной цвета 16-битного рабочего стола - PullRequest
2 голосов
/ 24 июля 2010

У меня есть приложение с прозрачным фоном в клиентской области, которое нарисовано черным, потому что окно не слоистое. В каждом из его сообщений WM_PAINT я делаю BitBlt для DC памяти, после чего я использую DC памяти с UpdateLayeredWindow для многослойного окна холста.

настройка памяти-DC:

HDC hdcMemory = CreateCompatibleDC(NULL);
HBITMAP bmpMemory = CreateDIBSection(hdcMemory, (BITMAPINFO*)&m_BitmapInfoHeader,
DIB_RGB_COLORS, (void **)&m_pDIBSectionBits, NULL, (DWORD)0);
SelectObject(hdcMemory, bmpMemory);

В WM_PAINT я использую функцию BitBlt, чтобы скопировать информацию DC о клиентской области приложений в память DC. После этого я делаю UpdateLayeredWindow с DC памяти для многоуровневого DC окна холста (это CWnd). Так что это в режиме реального времени, и результат: у меня есть нормальное окно приложения и многоуровневое окно, кроме того, с неправильной формой и прозрачностью на пиксель.

Все отлично работает с глубиной цвета 32-битного рабочего стола! Если я переключаюсь на 16-битный режим, окно многослойного холста портится Чертеж выглядит плохо, и все окно работает по клику.

Кажется, это из-за отсутствия информации об альфа-канале.

Так что я так много гуглил для решения. Я обнаружил, что в этой ситуации я должен создать память DC с

HDC hdcMemory = CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);

вместо CreateCompatibleDC (NULL). Потому что совместимый DC даст мне 16-битный DC.

Рисовать лучше с CreateDC. Но все окно по-прежнему можно нажимать, и прозрачность в многослойном окне отображается черным цветом.

Так что я думаю, что проблема в BitBlt или BitmapInfoHeader для CreateDIBSection.

  1. Я не знаю, использовать ли BitmapInfoHeader.biBitCount = 32 или BitmapInfoHeader.biBitCount = 16 бит. Думаю, это 32. А как насчет biCompression -> BI_RGB или BI_BITFIELDS?

  2. Как добавить информацию об альфа-канале в DC-память после BitBlt (..., SRCCOPY) 16-битного DC в DC-память, чтобы он работал с UpdateLayeredWindow? (возможно: предварительно умножить каналы rgb на альфа-канал?) Не знаю, как это сделать.


Я немного ближе к проблеме глубины цвета 16-битного рабочего стола.

HDC hdcMemory = CreateCompatibleDC(NULL);

Сказанное выше работает. Но результат, который дает моя функция UpdateLayeredWindow, выглядит беспорядочно.

Итак, потому что черный цвет отсутствует! Каждый пиксель, который был полностью черным, становится прозрачным. Вы можете увидеть и нажать, хотя. Все остальные пиксели теряют свою черную часть и получают только щелчок.

Я сделал тест: я открыл Windows Paint.exe, сделал поверхность шириной и высотой окон и закрасил ее черным цветом.

Затем я поместил его под свое многослойное окно (с отсутствующим черным цветом), снова взял многослойное окно в качестве подделанного окна, и да, мое многослойное окно выглядит нормально в сочетании со светящимися черными пикселями Paint.exe.

Итак, у меня истек срок действия BitBlt и его параметра растра. Но не повезло.

Как смешать черный цвет с BitBlt с моим DC до рисования с помощью UpdateLayeredWindow?

1 Ответ

0 голосов
/ 11 августа 2010

посмотрите здесь: http://msdn.microsoft.com/en-us/library/aa453651.aspx Я убежден, что это проблема с растровой операцией.

...