Если же интересно, как баги выглядят и как проявляются, то вот фотосессия.
Skype как раз был запущен.
Одно из характерных проявлений — штатный просмотрщик изображений не может показывать картинки вот с такой формулировкой:
При ресайзе этого окна происходит пересоздание битмапа (под новые габариты), и процентах в 10 это пересоздание оказывается успешным и картинка проявляется. То есть изображение то появляется, то исчезает с изменением размера окна хотя бы на 1 px.
Привычно открываю SnagIt — чтобы снять то, что выше (пришлось сфотографировать). SnagIt, естественно, не может снять скриншот, зато его окно (открывшееся на другом мониторе) просвечивает то, что оказалось под ним:
Словно
WM_ERASEBKGND не сработал. Именно так: дело точно не в том, что у окна такой причудливый clip region или что оно
слоёное. Весь этот графический мусор, оказавшийся внутри региона окна будет перемещаться вместе с окном при передвижении окна (как это штатно бывает — перетаскивание окна двигает растр).
Разворачиваю окно Скайпа: у него верхушка отрисовалась, а элемент со списком контактов — не отрисовался вообще, а поэтому просвечивает окно браузера и вьювера картинок.
Если водить мышкой над списком контактов, то конечно соответствующие элементы начинают рисоваться. То есть само по себе приложение, реагируя на
WM_MOUSEMOVE, какую-то свою оконную графику перерисовывать может. А вот самоотрисовка по
WM_PAINT и
WM_NCPAINT — хромает.
Например вот:
При проведении над «Echo / Sound Test Service» мышкой этот айтем перерисовался. Белый фон и прочие айтемы, естественно, нет.
Окно SnagIt'а, тем временем, заполняется фрагментами собственной графики и мусором, оставшимся от отрисовки поверх него окна Скайпа:
А окно Скайпа — фрагментами окна SnagIt'а, которые при прокрутке контакт-листа только оставляют за собой шлейф:
Тут следует напомнить, как обычно реализуются скроллируемые контейнеры: при получении
WM_MOUSEWHEEL код внутри WindowProc дёргает какую-то общую функцию, ответственную за скроллинг, ту же, которую дёргают обработчики сообщений от скроллбаров. Эта функция вызывает API-функцию
ScrollWindow, которая просто сдвигает растр (копированием, вероятно, с помощью
BitBlt), а затем —
InvalidateRect (или
InvalidateRgn), помечая участок, на месте которого должна появиться новая графика (ранее скрытая, но появляющаяся на новом месте в результате скроллинга). В результате вызова InvalidateRect в очередь сообщений прилетает сообщение
WM_PAINT, которое заставляет WindowProc окна перерисовать фрагментик, на месте которого должна появиться новая графика.
В нашем случае всё так, но
WM_PAINT не обрабатывается успешно. Так что картина вполне ожидаемая и объяснимая.
Баг с недообработкой WM_NCPAINT (когда у вновь появляющихся окон отсутствует синяя полоса заголовка) я поймать в этот раз не смог.