Мерцающие дочерние окна с альфа-каналами

При рисовании дочерних элементов управления, содержащих растровые изображения с альфа-каналами на пиксель, мы получаем довольно много мерцаний, когда их нужно перерисовать. Фактическое смешивание работает правильно. Я нашел много информации об уменьшении мерцания (например, этот вопрос или этот сайт), но я не могу найти ничего, что относится именно к этой ситуации.

Например, у меня есть кнопка с несколькими различными растровыми изображениями, которые альфа-смешиваются и перетаскиваются в окно, в зависимости от состояния кнопки. Когда их состояние изменяется, и мне нужно нарисовать другое растровое изображение, мне нужно сначала перерисовать фон, иначе он смешивается с пикселями, оставшимися от растрового изображения предыдущего состояния. Это то место, где я начинаю мерцать, и иногда я получаю немного фона.

Проблема усложняется тем, что родительские окна верхнего уровня рисуют фоновый рисунок, а не сплошной цвет, а также возможность перекрытия дочерних элементов управления; просто умножение базового цвета на растровое изображение дочернего элемента исключено, так как WS_CLIPCHILDREN,

Поскольку окна имеют растровый фон, я возвращаюсь true на WM_ERASEBKGND, чтобы не рисовать цвет, который будет просто перезаписан.

Конечно, двойная буферизация могла бы решить все это, но я не смог заставить ее работать правильно. Я поставил WS_COMPOSITED для окон верхнего уровня и WS_TRANSPARENT для детских окон. Когда приходит время перерисовать дочернее окно с новым растровым изображением, у меня возникает несколько проблем (скорее всего, я не понимаю, как работает порядок рисования в этой ситуации):

  • Если я позвоню InvalidateRect() и передать дочерний дескриптор, дочернее окно действительно перерисовывается, но фон не перерисовывается, и поэтому пиксели накапливаются друг на друге, смешиваясь вместе.
  • Если я позвоню InvalidateRect() и передать родительский дескриптор с прямоугольником, состоящим из размеров дочернего окна, фон перерисовывается, а дочернее окно - нет.
  • Если я сделаю оба из вышеперечисленного, то фон перерисовывается так же, как и дочернее окно, и оно выглядит точно так, как я хотел бы - за исключением того, что, благодаря этому, мне удалось снова заставить его мерцать (что не это действительно удивительно, так как кажется, что звонить ужасно InvalidateRect() в два раза больше, так как я предполагаю, что каждый вызов, вероятно, приводит к переворачиванию буферов, что побеждает цель).

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

2 ответа

Вы используете многослойные окна? Если нет, может быть, попробовать это.

Также для двойной буферизации рассмотрим эту технику.

Это может быть совсем не так - мои дни были давным-давно...

Но не могли бы вы просто рассчитать смеси для разных штатов? Я предполагаю, что ваша кнопка может быть включена / отключена и вверх / вниз, так что это только 4 комбинации. Почему бы не рассчитать комбинированные растровые изображения?

Или это проблема взаимодействия уже комбинированных растровых изображений с существующим состоянием?

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