Поделиться через


Обработка средств сохранения экрана

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.