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