Если вы указываете стиль класса
CS_SAVEBITS
, то оконный менеджер будет стараться сохранять биты, закрытые окном. Но настоящий вопрос здесь - почему. Т.к. ответ на этот вопрос позволит вам использовать эту силу для добра, а не зла.Когда окно, чей класс содержит стиль
CS_SAVEBITS
, показывается, оконный менеджер делает снимок пикселей экрана, где будет показано окно. Сначала он просит видео-карту сохранять пиксели во внеэкранной видеопамяти (быстро). Если таковой памяти нет или недостаточно, то пиксели сохраняются в системной памяти RAM (медленнее). Если в промежутке сохранённые пиксели не были выброшены (см. ниже), то когда окно скрывается, сохранённые пиксели копируются назад на экран. Другими словами, не генерируются сообщения WM_PAINT
.Что может отменить сохранённые пиксели? Что угодно, что может привести к их рассинхронизации с тем, что должно быть на экране, когда окно уйдёт. Вот несколько примеров:
- Если окно перемещается, то пиксели выбрасываются. Поскольку их восстановление на экран поместило бы их в неверную позицию.
- Если нижележащее окно обновляет себя (обычно через
InvalidateRect
), то сохранённые пиксели также отбрасываются, потому что нижележащее окно указало, что оно хочет обновить свои пиксели. - Если любое окно под данным меняет свой Z-порядок, то сохранённые пиксели также отбрасываются.
- Если под данным окном создаются или уничтожаются окна.
- Если кто-то вызывает
GetDC
для нижележащего окна и начинает рисовать.
Так как вам использовать эту силу ради добра?
Первый момент для рассмотрения - регион окна должен быть невелик, потому что чем больше сохраняемое изображение, тем меньше шансов, что оно влезет во внеэкранную видеопамять, что означает большую вероятность для переноса данных из видеопамяти в системную память - кошмарный "vid-sys blt", с которым хорошо знакомы производители игр. В общей схеме копирования данных между видео- и системной памятью, "vid-vid" - быстрейший (поскольку видеокарты очень хороши в этой задаче), "sys-sys" - следующий наилучший (хотя это будет стоить вам места в кэше процессора), "sys-vid" на третьем месте, а "vid-sys" - наихудший: программы намного более часто пишут в видеопамять, чем читают из неё. Вот почему связь между видеокартой и системной памятью оптимизирована в сторону записи в видеопамять, а не чтения из неё.
Но основной момент здесь - убедиться, что оконный менеджер не будет заниматься всей этой работой только для того, чтобы выбросить в итоге эти пиксели. Поэтому окно, которое является хорошим кандидатом для стиля
CS_SAVEBITS
, не двигается, занимает относительно немного места на экране и видимо только короткий промежуток времени. То, что окно не должно двигаться, очевидно: если окно смещается, то пиксели выбрасываются. Второе и третье правила пытаются минимизировать шанс отмены пикселей. Соответственно, лучшими кандидатами для
CS_SAVEBITS
являются меню, подсказки, небольшие диалоги - поскольку все они малы, обычно не двигаются по экрану и быстро пропадают.(Некоторые люди ошибочно считают, что
CS_SAVEBITS
сохраняет биты самого окна. Я не знаю, откуда пошёл этот миф, поскольку простейший эксперимент показывает несостоятельность этой версии. Модель рисования в Windows следует принципу Не сохраняй ничего, что ты можешь пересчитать.)
И как тогда вытащить эти сохраненные данные под окном?
ОтветитьУдалитьЭэээ.... зачем?
ОтветитьУдалить