Конфиденциальные сведения о Windows.Дело о пропавшем курсоре

Рэймонд Чен (Raymond Chen)

Читатели могли заметить, что при нажатии клавиши PrtSc для снятия снимка экрана, курсор ненадолго мигает. Хотите верьте, хотите нет, но это происходит по той же причине, по которой при отключении Windows XP прозрачные окна не становятся тусклыми и черно-белыми.

Эти прозрачные окна, известные как многослойные окна, обычно не учитываются при чтении пикселей с экрана функцией BitBlt. Чтобы добраться до них, необходимо передать флажок CAPTUREBLT. При этом можно также заметить, что курсор мыши мигает. Так почему это так?

Давным-давно единственным графическим объектом, плававшим «над» остальными объектами на экране, был курсор мыши. Сначала система поддерживала только одноцветные курсоры мыши. Эти курсоры поддерживались программно или, если кому-то удавалось заполучить потрясающую видеокарту, на уровне оборудования.

При использовании курсора, поддерживаемого видеокартой, GDI передает видеокарте растровое изображение и маску, а затем говорит: «ОК, это курсор мыши. Наложи это на экран по указанным мною координатам». Когда пользователь двигает мышь, GDI отправляет видеокарте обновленные координаты, и видеокарта выполняет сложную работу перемещения пикселей по экрану.

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

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

И наоборот, если используется программный курсор, то GDI должен удалить с экрана курсор мыши перед выполнением BitBlt с экрана, если копируемая область накладывается на курсор мыши.

Для анимированных курсоров аппаратная поддержка курсоров не очень подходит, поскольку аппаратные курсоры не анимируются. В результате чего анимированные курсоры реализуются программно.

ОК, хорошо. Но какая здесь связь с CAPTUREBLT? Сейчас я дойду и до этого.

В Windows 2000 механизм компоновки, который использовался для реализации программных курсоров, обобщили так, чтобы его можно было применять и для приложений. В конце концов эти псевдо-курсоры стали известны как многослойные окна. Подобно программным курсорам, аппаратные окна не появляются при выполнении BitBlt с экрана, поскольку в обычном смысле они не существуют. Пиксели курсора и многослойные окна совмещаются с экраном в последний момент.

Но что делать, если нужно записать пиксели многослойного окна при помощи функции BitBlt? Здесь-то и вступает в дело новый флажок CAPTUREBLT. Он записывает пиксели после того, как механизм компоновки сделал свое дело. Поскольку код, который затемняет экран при отключении Windows XP, не передает CAPTUREBLT, то многослойные окна не появляются.

Однако может показаться, что это не объясняет мигание курсора. А зря. Курсор мыши – это просто еще один объект компоновки, следовательно, для его записи нужно передавать флажок CAPTUREBLT. Чтобы не дать этому произойти, в ходе записи экрана механизм компоновки должен скрыть курсор, выполнить CAPTUREBLT, а затем показать курсор снова.

Предоставив механизм компоновки Windows 2000 приложениям, курсоры утратили свой особый статус. Круг замкнулся. Теперь все как в старые добрые дни, когда у нас был лишь буфер кадра и программный курсор.

**Рэймонд Чен (Raymond Chen)**на своем веб-сайте The Old New Thing (Хорошо забытое старое) и в одноименной книге (издательство Addison-Wesley, 2007 г.) рассказывает об истории развития Windows, программирования в среде Win32 и неправильном истолковании газетных заголовков.