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