• GetDC()
• ReleaseDC()
Функция GetDC() предоставляет в ваше распоряжение DC (контекст устройства, Device Context), через который можно осуществлять вывод на поверхность стандартными функциями Win32. Например, передавая его функции Win32 TextOut(), можно вывести на поверхность текст. Функция ReleaseDC() должна быть вызвана сразу же после завершения работы с DC.
Как и в случае с Lock() и Unlock(), функцию ReleaseDC() необходимо вызывать после GetDC() как можно быстрее. Это связано с тем, что внутри функции GetDC() вызывается Lock(), а внутри ReleaseDC() - Unlock().
Функции PageLock() и PageUnlock()
Перейдем к двум функциям, внешне похожим на Lock() и Unlock():
• PageLock()
• PageUnlock()
Вероятно, имена этих функций были выбраны неудачно, потому что они предназначены совсем для других целей. С помощью PageLock() и PageUnlock() можно управлять тем, как Windows обходится с поверхностями в системной памяти. Для работы с ними используется интерфейс DirectDrawSurface2, в DirectDrawSurface они отсутствуют.
Обычно система Windows переносит содержимое памяти на диск, когда по ее мнению другое приложение или процесс в данный момент смогут лучше распорядиться памятью. Это относится ко всей системной памяти, поэтому поверхности DirectDraw, хранящиеся в ней, также могут переноситься на диск. Когда в такой поверхности возникнет необходимость, получение данных с диска будет сопровождаться ощутимой паузой.
Функция PageLock() сообщает Windows о том, что данную поверхность нельзя переносить на диск. В этом случае поверхность всегда остается доступной и не требует долгих обращений к жесткому диску. Функция PageUnlock() разрешает Windows переносить поверхность на диск.
Следует помнить, что частое использование PageLock() приведет к замедлению работы Windows из-за сокращения общего объема переносимой памяти. Когда именно это произойдет, зависит от объема памяти, для которой запрещен перенос на диск, и общего объема системной памяти.
Функции PageLock() и PageUnlock() используются в первую очередь самой библиотекой DirectDraw, а не приложениями. Например, DirectDraw автоматически вызывает PageLock() и PageUnlock(), чтобы поверхности, находящиеся в системной памяти, не переносились на диск в ходе блиттинга.
Функцию PageLock() можно вызывать для одной поверхности многократно. DirectDraw следит за количеством вызовов PageLock(), используя механизм подсчета ссылок, поэтому для отмены многократных вызовов PageLock() потребуется несколько вызовов PageUnlock().
Функции PageLock() и PageUnlock() не влияют на поверхности, находящиеся в видеопамяти.
Функции IsLost() и Restore()
Две следующие функции предназначены для работы с поверхностями в видеопамяти:
• IsLost()
• Restore()
Рассмотрим следующую ситуацию: ваше приложение начинает работу. Вы размещаете как можно больше поверхностей в видеопамяти, а все остальные — в системной памяти. В течение некоторого времени приложение работает, но затем пользователь запускает другое приложение или переключается на него. Другое приложение может быть чем угодно — скажем, стандартной Windows-программой (например, Windows Explorer или Notepad). Оно также может оказаться другим приложением, которое тоже работает с DirectDraw и стремится разместить как можно больше поверхностей в видеопамяти. Если DirectDraw откажется выделить новому приложению видеопамять, оно будет работать плохо (а то и вообще не будет). Возможна и обратная ситуация — видеопамять окажется недоступной для вашего приложения.
По этой причине DirectDraw может забрать у неактивного приложения видеопамять, занятую некоторыми (или всеми) поверхностями. Такие поверхности называются потерянными (lost). Вообще говоря, такие поверхности остаются у вашей программы, но они перестают быть связанными с какой-либо областью памяти. Любая попытка использовать потерянную поверхность приводит к ошибке DDERR_SURFACELOST. Функция IsLost() позволяет узнать, была ли потеряна память данной поверхности.
Потерянную поверхность можно восстановить функцией Restore(), но только после повторной активизации вашего приложения. Тем самым предотвращается восстановление поверхностей для приложений, находящихся в свернутом виде на панели задач.
При этом существует одна загвоздка. Функция Restore() восстанавливает лишь память, закрепленную за поверхностью, но не ее содержимое. Следовательно, после восстановления поверхности ваше приложение само должно восстановить ее содержимое.
Обратите внимание: сказанное не относится к поверхностям, находящимся в системной памяти. Если память, занятая такими поверхностями, потребуется для других целей, Windows перенесет их на диск. Все эти действия Windows выполняет автоматически, включая восстановление содержимого поверхностей.
Функция GetDDInterface()
Функция GetDDInterface() возвращает указатель на интерфейс DirectDraw, использованный для создания заданной поверхности. Эта функция используется очень редко, поскольку ваши программы, вероятно, будут обходиться одним экземпляром интерфейса DirectDraw. Тем не менее в одном приложении разрешено иметь несколько интерфейсов DirectDraw. В этом случае функция GetDDInterface() может оказаться полезной.
Функции присоединения поверхностей
Интерфейс DirectDrawSurface содержит четыре функции для управления взаимосвязанными поверхностями:
• AddAttachedSurface()
• DeleteAttachedSurface()
• EnumAttachedSurface()
• GetAttachedSurface()
В DirectDraw возможно несколько ситуаций, при которых поверхности могут присоединяться к другим поверхностям. Самая распространенная из них — переключение страниц. Чтобы переключение страниц стало возможным, необходимо циклически соединить две или несколько поверхностей. При каждом вызове Flip() на экране будет отображаться следующая поверхность из цепочки. Перечисленные выше функции используются для создания, просмотра и уничтожения связей между поверхностями, однако в программах они встречаются довольно редко. Обычно DirectDraw создает за вас нужные поверхности вместе с взаимными связями. Например, при создании первичной переключаемой поверхности вы указываете количество присоединенных к ней вторичных буферов. DirectDraw создает все необходимые поверхности и должным образом присоединяет их друг к другу.
Оверлейные функции
Поддержка оверлеев в DirectDrawSurface представлена следующими функциями:
• AddOverlayDirtyRect()
• EnumOverlayZOrder()
• GetOverlayPosition()
• SetOverlayPosition()
• UpdateOverlay()
• UpdateOverlayDisplay()
• UpdateOverlayZOrder()
Функции GetOverlayPosition() и SetOverlayPosition() управляют положением оверлеев. Функция UpdateOverlay() изменяет параметры оверлея; в частности, она определяет, должен ли оверлей отображаться на экране и следует ли применять для него альфа-наложение или копирование с цветовым ключом.
Функция UpdateOverlayDisplay() обновляет изображение с учетом новых значений параметров. Данная функция может обновить все изображение оверлея или ограничиться его прямоугольными областями, заданными функцией AddOverlayDirtyRect(). Наконец, функция EnumOverlayZOrders() используется для перебора оверлеев в порядке их Z-координаты (Z-координата определяет, какие оверлеи выводятся поверх других). Возможен перебор как в прямом порядке (от передних оверлеев к задним), так и в обратном (от задних — к передним).
Функции для работы с объектами отсечения
DirectDraw позволяет присоединить к поверхности экземпляр интерфейса DirectDrawClipper (который мы еще не рассматривали). После того как такое присоединение состоится, операция блиттинга на данную поверхность будет регулироваться объектом отсечения. Для работы с объектами отсечения в интерфейсе DirectDrawSurface имеются две функции:
• GetClipper()
• SetClipper()
Функция SetClipper() присоединяет объект отсечения к поверхности. Функция GetClipper() возвращает указатель на присоединенный ранее объект отсечения. С помощью функции SetClipper() можно разорвать связь между поверхностью и объектом отсечения, для этого в качестве указателя на интерфейс DirectDrawClipper следует задать NULL.
Функции палитры
Палитры, как и объекты отсечения, можно присоединять к поверхностям. Для этой цели в интерфейсе DirectDrawSurface предусмотрены две функции:
• GetPalette()
• SetPalette()
Функция SetPalette() присоединяет к поверхности экземпляр интерфейса DirectDrawPalette (о нем речь пойдет ниже). Функция GetPalette() применяется для получения указателя на палитру, присоединенную ранее.