О том, что такое скринсэйвер (хранитель экрана), знает каждый школьник. Но не каждый представляет его себе настолько хорошо, чтобы написать свой. Я предлагаю вам создать собственный скринсэйвер на Дельфи. Почему на Дельфи? Во-первых, опыт работы с ним у меня намного богаче, чем с другими языками программирования, а во-вторых, он не предоставляет никаких дополнительных модулей, облегчающих создание скринсэйвера. То есть, нам предстоит написать скринсэйвер от начала и до конца.
Чтобы упростить скринсэйвер и сделать его код понятным даже новичкам в программировании, я постараюсь использовать минимум API-функций. Таким образом, основную часть скринсэйвера мы будем делать на VCL. Несколько слов о том, что такое скринсэйвер. Это обыкновенный программный файл с расширением .scr, который запускается в разных режимах в зависимости от параметров командной строки. Какие же параметры предстоит нам обрабатывать? Пусть наш скринсэйвер запускается в основном, полноэкранном режиме при наличии командной строки без параметров. При параметре С запускается окно настроек, при P окно предварительного просмотра, а с параметром A устанавливается функция указания пароля заставки. Не знаю почему, но возможность установки пароля заставки оставили за разработчиками скринсэйверов. Для нашего скринсэйвера потребуется две формы (в моем примере они называются frmMain и frmSet), одна для заставки, другая для настроек. Параметры будем обрабатывать непосредственно в главном файле проекта. Для этого создадим функцию ExecSS:
Теперь о том, как же должен выглядеть сам файл. Замечу, что надо исключать запуск двух копий хранителя, что и делают третья и четвертая строчки проекта:
Теперь хорошо подумайте, что должен делать ваш скринсэйвер. Я не буду приводить здесь пример его графического исполнения. Я только замечу, что если вы хотите создать несложный скринсэйвер, используйте графические функции GDI, то есть рисуйте средствами TCanvas. Если же вы желаете графику посолидней, используйте OpenGL. Не советую использовать в этих целях DirectDraw или Direct3D. Стандарт DirectX слишком часто обновляется, и нет гарантии, что он установлен на том компьютере, где вы хотите установить заставку. Итак, для начала сделаем из основной формы форму скринсэйвера. Установим ее следующие параметры:
Если вы создаете GDI`евский скринсэйвер, установите цвет окна, желательно черный, и создайте дополнительную канву, то есть объект класса TCanvas. В ней мы и будем рисовать скринсэйвер окно превью скринсэйвера. Так что назовите ее соответствующим образом (у меня она называется ssCanvas). Если вам потребуется таймер, поместите его на форму. Теперь обработаем события формы: OnKeyDown, OnMouseDown, OnMouseMove. Как вы понимаете, при всех этих событиях скринсэйвер должен закрываться. Это мы сделаем так:
Замечу, что при перемещении мыши мы должны закрывать хранитель, только если курсор переместился на 2-4 пикселя. То есть, для обработки события OnMouseMove мы сначала должны сохранить позицию курсора при старте, а затем сравнить с текущей.
Здесь mPos переменная типа TPoint, в которой сохранены координаты курсора. Теперь инициализируем скринсэйвер при событии OnCreate. Первое, что нам предстоит сделать, это узнать, находится ли хранитель в режиме превью или в основном. Проверка параметров будет осуществляться в функции IsPreview, приведенной ниже.
Результат желательно сохранить в какой-то переменной. Если это режим предварительного просмотра, мы также должны получить дескриптор окна просмотра он передается в качестве второго параметра, после -P.
Для вывода графики GDI в основном режиме используйте канву формы или рисуйте в той же канве, что и для окна просмотра, перед этим сделав так:
Замечу, что прорисовка окна через другую канву требует чуть больше ресурсов. Для инициализации графики в режиме preview вам потребуется размер контекста воспроизведения. Его можно получить с помощью функции GetClientRect, ее первый параметр дескриптор окна вывода (в нашем случае Strtoint(ParamStr(2))), а второй структура типа TRect, в которую заносится результат. В ее полях Right и Bottom содержится размер окна по вертикали и горизонтали. Вот, с инициализацией закончили. Теперь рассмотрим событие OnShow:
Наша заставка запустилась и должна нормально работать как в основном режиме, так и предварительного просмотра. Теперь перейдем к окну настроек, для которого мы создали вторую форму. Если вам необходимо задать какие-то настройки для хранителя, поставьте задающие их компоненты на форму. Также снабдите окно стандартными кнопками Ok, Cancel и Set Default. При нажатии на Ok все настройки, указанные пользователем, мы должны будем записать в реестр или в файл инициализации. Для этого можно воспользоваться классами TRegistry, TRegIniFile и TIniFile, перед этим добавив в список Uses модуль Registry. В моем примере это выглядит так:
В событии OnCreate основной формы нам предстоит считать эти настройки из реестра или ini-файла. Не забудьте: окно настроек нам тоже необходимо скрыть, убрать с панели задач. Теперь вернемся к пропущенным мною функциям CheckPassword и SetPassword. Если вы хотите добавить в хранитель проверку и установку пароля, просто перепишите эти функции. Первую пишем в модуль основной формы, а вторую в модуль проекта. Вот они:
Замечу, что использовать SystemParametersInfo(SPI_SCREENSAVERRUNNING,1,NIL,0) можно и в других целях, когда нужно заблокировать доступ к функциональным клавишам. Отключить это можно, указав второй параметр равным нулю.
Вот и все, что требуется для скринсэйвера. Остается только в файл проекта добавить директиву {$E scr}, чтобы он сразу же создавался с расширением .scr. А затем скопировать получившийся скринсэйвер в каталог Windows\System. Теперь он будет отображаться в списке заставок Windows и называться по имени scr-файла Как видите, код получился несложный, единственный его недостаток размер. Все программы, написанные с использованием VCL, занимают довольно много места. Если вы будете писать скринсэйвер только на API, вы вполне можете достичь уменьшения его размера до 20-40 Кб, мой же хранитель занимает около 500 Кб. Но неужели вам жалко каких-нибудь 500 Кб :-)?