Мерцающие дочерние окна с альфа-каналами
При рисовании дочерних элементов управления, содержащих растровые изображения с альфа-каналами на пиксель, мы получаем довольно много мерцаний, когда их нужно перерисовать. Фактическое смешивание работает правильно. Я нашел много информации об уменьшении мерцания (например, этот вопрос или этот сайт), но я не могу найти ничего, что относится именно к этой ситуации.
Например, у меня есть кнопка с несколькими различными растровыми изображениями, которые альфа-смешиваются и перетаскиваются в окно, в зависимости от состояния кнопки. Когда их состояние изменяется, и мне нужно нарисовать другое растровое изображение, мне нужно сначала перерисовать фон, иначе он смешивается с пикселями, оставшимися от растрового изображения предыдущего состояния. Это то место, где я начинаю мерцать, и иногда я получаю немного фона.
Проблема усложняется тем, что родительские окна верхнего уровня рисуют фоновый рисунок, а не сплошной цвет, а также возможность перекрытия дочерних элементов управления; просто умножение базового цвета на растровое изображение дочернего элемента исключено, так как WS_CLIPCHILDREN
,
Поскольку окна имеют растровый фон, я возвращаюсь true
на WM_ERASEBKGND
, чтобы не рисовать цвет, который будет просто перезаписан.
Конечно, двойная буферизация могла бы решить все это, но я не смог заставить ее работать правильно. Я поставил WS_COMPOSITED
для окон верхнего уровня и WS_TRANSPARENT
для детских окон. Когда приходит время перерисовать дочернее окно с новым растровым изображением, у меня возникает несколько проблем (скорее всего, я не понимаю, как работает порядок рисования в этой ситуации):
- Если я позвоню
InvalidateRect()
и передать дочерний дескриптор, дочернее окно действительно перерисовывается, но фон не перерисовывается, и поэтому пиксели накапливаются друг на друге, смешиваясь вместе. - Если я позвоню
InvalidateRect()
и передать родительский дескриптор с прямоугольником, состоящим из размеров дочернего окна, фон перерисовывается, а дочернее окно - нет. - Если я сделаю оба из вышеперечисленного, то фон перерисовывается так же, как и дочернее окно, и оно выглядит точно так, как я хотел бы - за исключением того, что, благодаря этому, мне удалось снова заставить его мерцать (что не это действительно удивительно, так как кажется, что звонить ужасно
InvalidateRect()
в два раза больше, так как я предполагаю, что каждый вызов, вероятно, приводит к переворачиванию буферов, что побеждает цель).
Я пришел к выводу, что я не совсем понимаю, как мне нужно изменить свою программу для обработки двойной буферизации, или если двойная буферизация даже поможет в этой ситуации. Я чувствую, что это определенно произойдет, но я не совсем понимаю, как мне нужно что-то изменить, чтобы все снова стало хорошо играть.
2 ответа
Вы используете многослойные окна? Если нет, может быть, попробовать это.
Также для двойной буферизации рассмотрим эту технику.
Это может быть совсем не так - мои дни были давным-давно...
Но не могли бы вы просто рассчитать смеси для разных штатов? Я предполагаю, что ваша кнопка может быть включена / отключена и вверх / вниз, так что это только 4 комбинации. Почему бы не рассчитать комбинированные растровые изображения?
Или это проблема взаимодействия уже комбинированных растровых изображений с существующим состоянием?