Обработка средств сохранения экрана
API Microsoft Win32 поддерживает приложения, называемые специальные экранные заставки. Заставки включаются, когда мышь и клавиатура неактивны в течение указанного периода времени. Они используются по двум причинам:
- Защита экрана от ожогов люминофора, вызванных статическими изображениями.
- Чтобы скрыть конфиденциальную информацию, оставшуюся на экране.
Этот раздел разделен на следующие разделы.
Сведения о средствах сохранения экрана
Приложение Рабочий стол в панели управления Windows позволяет пользователям выбирать из списка экранных заставок, указывать, сколько времени должно пройти до запуска экранной заставки, настраивать экранные заставки и просматривать их предварительно. Средства сохранения экрана загружаются автоматически при запуске Windows или при активации средства сохранения экрана с помощью панели управления.
После выбора средства сохранения экрана Windows отслеживает нажатия клавиш и движения мыши, а затем запускает средство сохранения экрана после периода бездействия. Однако Windows не запускает средство сохранения экрана, если существуют какие-либо из следующих условий:
- Активное приложение не является приложением на основе Windows.
- Присутствует окно обучения на основе компьютера (CBT).
- Активное приложение получает сообщение WM_SYSCOMMAND, при этом параметр wParam установлен в значение SC_SCREENSAVE, но оно не передает сообщение функции DefWindowProc.
Контекст безопасности экранной заставки
Контекст безопасности средства сохранения экрана зависит от того, вошел ли пользователь в систему в интерактивном режиме. Если пользователь вошел в систему в интерактивном режиме при вызове средства сохранения экрана, средство сохранения экрана запускается в контексте безопасности интерактивного пользователя. Если пользователь не вошел в систему, контекст безопасности средства сохранения экрана зависит от используемой версии Windows.
- Windows XP и Windows 2000 — средство сохранения экрана выполняется в контексте LocalSystem с ограниченными учетными записями.
- Windows 2003 — заставка выполняется в контексте LocalService без всех привилегий, с отключённой группой администраторов.
- Не применяется к Windows NT4.
Контекст безопасности определяет уровень привилегированных операций, которые можно выполнить с помощью средства сохранения экрана.
Windows Vista и более поздних версий: Если защита паролей включена политикой, средство сохранения экрана запускается независимо от того, что приложение делает с уведомлением SC_SCREENSAVE.
Заставки экрана содержат определенные экспортируемые функции, определения ресурсов и объявления переменных. Библиотека с сохранением экрана содержит функцию основной и другой код запуска, необходимый для сохранения экрана. При запуске средства сохранения экрана код запуска в библиотеке с сохранением экрана создает полноэкранное окно. Класс окна для этого окна объявлен следующим образом:
WNDCLASS cls;
cls.hCursor = NULL;
cls.hIcon = LoadIcon(hInst, MAKEINTATOM(ID_APP));
cls.lpszMenuName = NULL;
cls.lpszClassName = "WindowsScreenSaverClass";
cls.hbrBackground = GetStockObject(BLACK_BRUSH);
cls.hInstance = hInst;
cls.style = CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS | CS_DBLCLKS;
cls.lpfnWndProc = (WNDPROC) ScreenSaverProc;
cls.cbWndExtra = 0;
cls.cbClsExtra = 0;
Чтобы создать средство сохранения экрана, большинство разработчиков создают модуль исходного кода, содержащий три обязательных функции, и связывает их с библиотекой с сохранением экрана. Модуль сохранения экрана отвечает только за настройку себя и предоставление визуальных эффектов.
Одним из трех обязательных функций в модуле с сохранением экрана является ScreenSaverProc. Эта функция обрабатывает определенные сообщения и передает все необработанные сообщения обратно в библиотеку с сохранением экрана. Ниже приведены некоторые типичные сообщения, обработанные ScreenSaverProc.
Сообщение | Значение |
---|---|
WM_CREATE | Извлеките все данные инициализации из файла Regedit.ini. Задайте таймер окна для окна сохранения экрана. Выполните любую другую требуемую инициализацию. |
WM_ERASEBKGND | Удалите окно сохранения экрана и подготовьтесь к последующим операциям рисования. |
WM_TIMER | Выполнение операций рисования. |
WM_DESTROY | Уничтожьте таймеры, созданные, когда приложение обработало сообщение WM_CREATE. Выполните дополнительную требуемую очистку. |
ScreenSaverProc передает необработанные сообщения в библиотеку сохранения экрана путем вызова функции DefScreenSaverProc. В следующей таблице описывается, как эта функция обрабатывает различные сообщения.
Сообщение | Действие |
---|---|
WM_SETCURSOR | Присвойте курсору значение NULL, удалив его с экрана. |
WM_PAINT | Нарисуйте фон экрана. |
WM_LBUTTONDOWN | Завершите сохранение экрана. |
WM_MBUTTONDOWN | Завершите сохранение экрана. |
WM_RBUTTONDOWN | Отключите экранную заставку. |
WM_KEYDOWN | Отключите экранную заставку. |
WM_MOUSEMOVE | Завершите сохранение экрана. |
WM_ACTIVATE | Завершите сохранение экрана, если параметр wParam имеет значение FALSE. |
Вторая необходимая функция в модуле средства сохранения экрана — ScreenSaverConfigureDialog. Эта функция отображает диалоговое окно, позволяющее пользователю настроить экранный заставку (приложение должно предоставить соответствующий шаблон диалогового окна). Windows отображает диалоговое окно конфигурации, когда пользователь выбирает кнопку "Настройка" в диалоговом окне экранной заставки в панели управления.
Третья требуемая функция в модуле с сохранением экрана — RegisterDialogClasses. Эта функция должна вызываться всеми приложениями с сохранением экрана. Однако приложения, которые не требуют специальных окон или пользовательских элементов управления в диалоговом окне конфигурации, могут просто возвращать TRUE. Приложения, требующие специальных окон или пользовательских элементов управления, должны использовать эту функцию для регистрации соответствующих классов окон.
Помимо создания модуля, который поддерживает три функции, которые только что описаны, в заставке экрана должен быть значок. Этот значок отображается только в том случае, если средство сохранения экрана запускается как автономное приложение. (Чтобы средство сохранения экрана запускалось через панель управления, файловое имя должно иметь расширение .scr; чтобы запускаться как автономное приложение, оно должно иметь расширение .exe.) Значок должен быть определен в файле ресурсов средства сохранения экрана с помощью константы ID_APP, которая определена в заголовочном файле Scrnsave.h.
Одним из последних требований является строка описания средства сохранения экрана. Файл ресурсов для средства сохранения экрана должен содержать строку, отображаемую панелью управления в качестве имени средства сохранения экрана. Строка описания должна быть первой строкой в строковой таблице файла ресурса (идентифицируемой порядковым значением 1). Однако строка описания игнорируется панелью управления, если в заставке экрана имеется длинное имя файла. В таком случае имя файла будет использоваться в качестве строки описания.
Использование функций с сохранением экрана
В этом разделе используется пример кода, взятого из приложения средства сохранения экрана, чтобы проиллюстрировать следующие задачи:
- создание экранной заставки
- установка новых средств сохранения экрана
- добавление справки в диалоговое окно конфигурации заставки
Создание средства сохранения экрана
В интервалах от 1 до 10 секунд приложение в этом примере переопределяет экран одним из четырех цветов: белый, светло-серый, темно-серый и черный. Приложение перерисовывает экран каждый раз, когда оно получает WM_TIMER сообщение. Пользователь может настроить интервал, с помощью которого отправляется это сообщение, выбрав диалоговое окно конфигурации приложения и настроив одну горизонтальную полосу прокрутки.
Библиотека с сохранением экрана
Функции статической заставки содержатся в библиотеке заставок. Доступно две версии библиотеки Scrnsave.lib и Scrnsavw.lib. Необходимо связать проект с одним из них. Scrnsave.lib используется для хранителей экрана, которые используют символы ANSI, а Scrnsavw.lib используется для хранителей экрана, которые используют символы Юникода. Средство сохранения экрана, связанное с Scrnsavw.lib, будет запускаться только на платформах Windows, поддерживающих Юникод, а средство сохранения экрана, связанное с Scrnsave.lib, будет работать на любой платформе Windows.
Диалоговое окно для поддержки конфигурации
Большинство средств сохранения экрана предоставляют диалоговое окно конфигурации, чтобы разрешить пользователю указывать такие данные настройки, как уникальные цвета, скорость рисования, толщина линии, шрифты и т. д. Для поддержки диалогового окна конфигурации приложение должно предоставить шаблон диалогового окна и также поддерживать функцию ScreenSaverConfigureDialog. Ниже приведен шаблон диалогового окна для примера приложения.
DLG_SCRNSAVECONFIGURE DIALOG 6, 18, 160, 63
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Sample Screen-Saver Setup"
FONT 8, "MS Shell Dlg"
BEGIN
GROUPBOX "Redraw Speed", 101, 0, 6, 98, 40
SCROLLBAR ID_SPEED, 5, 31, 89, 10
LTEXT "Fast", 103, 6, 21, 20, 8
LTEXT "Slow", 104, 75, 21, 20, 8
PUSHBUTTON "OK", ID_OK, 117, 10, 40, 14
PUSHBUTTON "Cancel", ID_CANCEL, 117, 32, 40, 14
END
Необходимо определить константу, используемую для идентификации шаблона диалогового окна, с помощью десятичного значения 2003, как показано в следующем примере:
#define DLG_SCRNSAVECONFIGURE 2003
В следующем примере показана функция ScreenSaverConfigureDialog, найденная в примере приложения.
#define MINVEL 1 // minimum redraw speed value
#define MAXVEL 10 // maximum redraw speed value
#define DEFVEL 5 // default redraw speed value
LONG lSpeed = DEFVEL; // redraw speed variable
extern HINSTANCE hMainInstance; // screen saver instance handle
CHAR szAppName[80]; // .ini section name
CHAR szTemp[20]; // temporary array of characters
CHAR szRedrawSpeed[ ] = "Redraw Speed"; // .ini speed entry
CHAR szIniFile[MAXFILELEN]; // .ini or registry file name
BOOL WINAPI ScreenSaverConfigureDialog(hDlg, message, wParam, lParam)
HWND hDlg;
UINT message;
DWORD wParam;
LONG lParam;
HRESULT hr;
{
static HWND hSpeed; // handle to speed scroll bar
static HWND hOK; // handle to OK push button
switch(message)
{
case WM_INITDIALOG:
// Retrieve the application name from the .rc file.
LoadString(hMainInstance, idsAppName, szAppName,
80 * sizeof(TCHAR));
// Retrieve the .ini (or registry) file name.
LoadString(hMainInstance, idsIniFile, szIniFile,
MAXFILELEN * sizeof(TCHAR));
// TODO: Add error checking to verify LoadString success
// for both calls.
// Retrieve any redraw speed data from the registry.
lSpeed = GetPrivateProfileInt(szAppName, szRedrawSpeed,
DEFVEL, szIniFile);
// If the initialization file does not contain an entry
// for this screen saver, use the default value.
if(lSpeed > MAXVEL || lSpeed < MINVEL)
lSpeed = DEFVEL;
// Initialize the redraw speed scroll bar control.
hSpeed = GetDlgItem(hDlg, ID_SPEED);
SetScrollRange(hSpeed, SB_CTL, MINVEL, MAXVEL, FALSE);
SetScrollPos(hSpeed, SB_CTL, lSpeed, TRUE);
// Retrieve a handle to the OK push button control.
hOK = GetDlgItem(hDlg, ID_OK);
return TRUE;
case WM_HSCROLL:
// Process scroll bar input, adjusting the lSpeed
// value as appropriate.
switch (LOWORD(wParam))
{
case SB_PAGEUP:
--lSpeed;
break;
case SB_LINEUP:
--lSpeed;
break;
case SB_PAGEDOWN:
++lSpeed;
break;
case SB_LINEDOWN:
++lSpeed;
break;
case SB_THUMBPOSITION:
lSpeed = HIWORD(wParam);
break;
case SB_BOTTOM:
lSpeed = MINVEL;
break;
case SB_TOP:
lSpeed = MAXVEL;
break;
case SB_THUMBTRACK:
case SB_ENDSCROLL:
return TRUE;
break;
}
if ((int) lSpeed <= MINVEL)
lSpeed = MINVEL;
if ((int) lSpeed >= MAXVEL)
lSpeed = MAXVEL;
SetScrollPos((HWND) lParam, SB_CTL, lSpeed, TRUE);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_OK:
// Write the current redraw speed variable to
// the .ini file.
hr = StringCchPrintf(szTemp, 20, "%ld", lSpeed);
if (SUCCEEDED(hr))
WritePrivateProfileString(szAppName, szRedrawSpeed,
szTemp, szIniFile);
case ID_CANCEL:
EndDialog(hDlg, LOWORD(wParam) == ID_OK);
return TRUE;
}
}
return FALSE;
}
Помимо предоставления шаблона диалогового окна и поддержки функции ScreenSaverConfigureDialog приложение также должно поддерживать функцию RegisterDialogClasses. Эта функция регистрирует все нестандартные классы окон, необходимые для сохранения экрана. Так как пример приложения использовал только стандартные классы окон в процедуре диалогового окна, эта функция просто возвращает TRUE, как показано в следующем примере:
BOOL WINAPI RegisterDialogClasses(hInst)
HANDLE hInst;
{
return TRUE;
}
Поддержка процедуры окна сохранения экрана
Каждый скринсейвер должен поддерживать процедуру окна с именем ScreenSaverProc. Как и большинство процедур окон, ScreenSaverProc обрабатывает набор определенных сообщений и передает все необработанные сообщения процедуре по умолчанию. Однако вместо передачи их в функцию DefWindowProcScreenSaverProc передает необработанные сообщения в функцию DefScreenSaverProc. Еще одно различие между ScreenSaverProc и обычной процедурой окна заключается в том, что дескриптор, переданный в ScreenSaverProc определяет весь рабочий стол, а не окно клиента. В следующем примере показана процедура окна ScreenSaverProc для примера экранной заставки.
LONG WINAPI ScreenSaverProc(hwnd, message, wParam, lParam)
HWND hwnd;
UINT message;
DWORD wParam;
LONG lParam;
{
static HDC hdc; // device-context handle
static RECT rc; // RECT structure
static UINT uTimer; // timer identifier
switch(message)
{
case WM_CREATE:
// Retrieve the application name from the .rc file.
LoadString(hMainInstance, idsAppName, szAppName, 80 * sizeof(TCHAR));
// Retrieve the .ini (or registry) file name.
LoadString(hMainInstance, idsIniFile, szIniFile, MAXFILELEN * sizeof(TCHAR));
// TODO: Add error checking to verify LoadString success
// for both calls.
// Retrieve any redraw speed data from the registry.
lSpeed = GetPrivateProfileInt(szAppName, szRedrawSpeed,
DEFVEL, szIniFile);
// Set a timer for the screen saver window using the
// redraw rate stored in Regedit.ini.
uTimer = SetTimer(hwnd, 1, lSpeed * 1000, NULL);
break;
case WM_ERASEBKGND:
// The WM_ERASEBKGND message is issued before the
// WM_TIMER message, allowing the screen saver to
// paint the background as appropriate.
hdc = GetDC(hwnd);
GetClientRect (hwnd, &rc);
FillRect (hdc, &rc, GetStockObject(BLACK_BRUSH));
ReleaseDC(hwnd,hdc);
break;
case WM_TIMER:
// The WM_TIMER message is issued at (lSpeed * 1000)
// intervals, where lSpeed == .001 seconds. This
// code repaints the entire desktop with a white,
// light gray, dark gray, or black brush each
// time a WM_TIMER message is issued.
hdc = GetDC(hwnd);
GetClientRect(hwnd, &rc);
if (i++ <= 4)
FillRect(hdc, &rc, GetStockObject(i));
else
(i = 0);
ReleaseDC(hwnd,hdc);
break;
case WM_DESTROY:
// When the WM_DESTROY message is issued, the screen saver
// must destroy any of the timers that were set at WM_CREATE
// time.
if (uTimer)
KillTimer(hwnd, uTimer);
break;
}
// DefScreenSaverProc processes any messages ignored by ScreenSaverProc.
return DefScreenSaverProc(hwnd, message, wParam, lParam);
}
Создание файла определения модуля
Функции ScreenSaverProc и ScreenSaverConfigureDialog необходимо экспортировать в файл определения модуля приложения; RegisterDialogClasses не следует экспортировать. В следующем примере показан файл определения модуля для примера приложения.
NAME SSTEST.SCR
DESCRIPTION 'SCRNSAVE : Test'
STUB 'WINSTUB.EXE'
EXETYPE WINDOWS
CODE MOVEABLE
DATA MOVEABLE MULTIPLE
HEAPSIZE 1024
STACKSIZE 4096
EXPORTS
ScreenSaverProc
ScreenSaverConfigureDialog
Установка новых средств сохранения экрана
При компиляции списка доступных средств сохранения экрана панель управления ищет каталог запуска Windows для файлов с расширением SCR. Так как средства сохранения экрана являются стандартными исполняемыми файлами Windows с расширениями .exe, их необходимо переименовать, чтобы они имели расширения SCR и копировать их в правильный каталог.
Добавление справки в диалоговое окно "Настройка средства сохранения экрана"
Диалоговое окно конфигурации для средства сохранения экрана обычно включает кнопку справки. Приложения средства сохранения экрана могут проверять идентификатор кнопки справки и вызывать функцию WinHelp таким же образом, как справка предоставляется в других приложениях под управлением Windows.