Gestione degli screen saver
L'API Microsoft Win32 supporta applicazioni speciali denominate screen saver. Gli screen saver iniziano quando il mouse e la tastiera sono stati inattive per un periodo di tempo specificato. Vengono usati per questi due motivi:
- Per proteggere uno schermo dalla bruciatura di fosfori causati da immagini statiche.
- Per nascondere le informazioni riservate lasciate su una schermata.
Questo argomento è suddiviso nelle sezioni seguenti.
Informazioni sugli screen saver
L'applicazione Desktop in Windows Pannello di controllo consente agli utenti di selezionare da un elenco di screen saver, specificare la quantità di tempo trascorsa prima dell'avvio dello screen saver, la configurazione degli screen saver e gli screen saver di anteprima. Gli screen saver vengono caricati automaticamente all'avvio di Windows o quando un utente attiva lo screen saver tramite il Pannello di controllo.
Dopo aver scelto uno screen saver, Windows monitora le sequenze di tasti e i movimenti del mouse e quindi avvia lo screen saver dopo un periodo di inattività. Tuttavia, Windows non avvia lo screen saver se esiste una delle condizioni seguenti:
- L'applicazione attiva non è un'applicazione basata su Windows.
- È presente una finestra di training basata su computer (CBT).
- L'applicazione attiva riceve il messaggio WM_SYSCOMMAND con il parametro wParam impostato sul valore SC_SCREENSAVE, ma non passa il messaggio alla funzione DefWindowProc .
Contesto di sicurezza dello screen saver
Il contesto di sicurezza dello screen saver dipende dal fatto che un utente sia connesso in modo interattivo. Se un utente è connesso in modo interattivo quando viene richiamato lo screen saver, lo screen saver viene eseguito nel contesto di sicurezza dell'utente interattivo. Se nessun utente è connesso, il contesto di sicurezza dello screen saver dipende dalla versione di Windows in uso.
- Windows XP e Windows 2000 : lo screen saver viene eseguito nel contesto di LocalSystem con account limitati.
- Windows 2003 : lo screen saver viene eseguito nel contesto di LocalService con tutti i privilegi rimossi e i gruppi di amministratori disabilitati.
- Non si applica a Windows NT4.
Il contesto di sicurezza determina il livello di operazioni con privilegi che possono essere eseguite da uno screen saver.
Windows Vista e versioni successive: Se la protezione delle password è abilitata dai criteri, lo screen saver viene avviato indipendentemente dal funzionamento di un'applicazione con la notifica di SC_SCREENSAVE.
Gli screen saver contengono funzioni esportate specifiche, definizioni di risorse e dichiarazioni di variabili. La libreria screen saver contiene la funzione principale e altri codici di avvio necessari per uno screen saver. Quando viene avviato uno screen saver, il codice di avvio nella libreria screen saver crea una finestra a schermo intero. La classe di finestra per questa finestra viene dichiarata come segue:
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;
Per creare uno screen saver, la maggior parte degli sviluppatori crea un modulo di codice sorgente contenente tre funzioni necessarie e li collega alla libreria screen saver. Un modulo screen saver è responsabile solo della configurazione e dell'offerta di effetti visivi.
Una delle tre funzioni necessarie in un modulo screen saver è ScreenSaverProc. Questa funzione elabora messaggi specifici e passa tutti i messaggi non elaborati alla libreria di screen saver. Di seguito sono riportati alcuni dei messaggi tipici elaborati da ScreenSaverProc.
Messaggio | Significato |
---|---|
WM_CREATE | Recuperare tutti i dati di inizializzazione dal file di Regedit.ini. Impostare un timer di finestra per la finestra dello screen saver. Eseguire qualsiasi altra inizializzazione necessaria. |
WM_ERASEBKGND | Cancellare la finestra dello screen saver e preparare le operazioni di disegno successive. |
WM_TIMER | Eseguire operazioni di disegno. |
WM_DESTROY | Eliminare i timer creati quando l'applicazione ha elaborato il messaggio di WM_CREATE . Eseguire qualsiasi pulizia aggiuntiva necessaria. |
ScreenSaverProc passa messaggi non elaborati alla libreria screen saver chiamando la funzione DefScreenSaverProc . La tabella seguente descrive come questa funzione elabora vari messaggi.
Message | Azione |
---|---|
WM_SETCURSOR | Impostare il cursore sul cursore Null, rimuovendolo dalla schermata. |
WM_PAINT | Disegnare lo sfondo dello schermo. |
WM_LBUTTONDOWN | Terminare lo screen saver. |
WM_MBUTTONDOWN | Terminare lo screen saver. |
WM_RBUTTONDOWN | Terminare lo screen saver. |
WM_KEYDOWN | Terminare lo screen saver. |
WM_MOUSEMOVE | Terminare lo screen saver. |
WM_ACTIVATE | Terminare lo screen saver se il parametro wParam è impostato su FALSE. |
La seconda funzione necessaria in un modulo screen saver è ScreenSaverConfigureDialog. Questa funzione visualizza una finestra di dialogo che consente all'utente di configurare lo screen saver (un'applicazione deve fornire un modello di finestra di dialogo corrispondente). Windows visualizza la finestra di dialogo di configurazione quando l'utente seleziona il pulsante Setup nella finestra di dialogo Screen Saver della Pannello di controllo.
La terza funzione necessaria in un modulo screen saver è RegisterDialogClasses. Questa funzione deve essere chiamata da tutte le applicazioni screen saver. Tuttavia, le applicazioni che non richiedono finestre speciali o controlli personalizzati nella finestra di dialogo di configurazione possono semplicemente restituire TRUE. Le applicazioni che richiedono finestre speciali o controlli personalizzati devono usare questa funzione per registrare le classi di finestre corrispondenti.
Oltre alla creazione di un modulo che supporta le tre funzioni appena descritte, uno screen saver deve fornire un'icona. Questa icona è visibile solo quando lo screen saver viene eseguito come applicazione autonoma. (Per essere eseguito dal Pannello di controllo, uno screen saver deve avere l'estensione del nome file con estensione scr. Per essere eseguita come applicazione autonoma, deve avere l'estensione del nome file .exe. L'icona deve essere identificata nel file di risorse dello screen saver dalla costante ID_APP, definita nel file di intestazione Scrnsave.h.
Un requisito finale è una stringa di descrizione dello screen saver. Il file di risorsa per uno screen saver deve contenere una stringa visualizzata dall'Pannello di controllo come nome dello screen saver. La stringa di descrizione deve essere la prima stringa della tabella stringa del file di risorsa (identificata con il valore ordinale 1). Tuttavia, la stringa di descrizione viene ignorata dal Pannello di controllo se lo screen saver ha un nome file lungo. In tal caso, il nome file verrà usato come stringa di descrizione.
Uso delle funzioni screen saver
Questa sezione usa il codice di esempio tratto da un'applicazione screen saver per illustrare le attività seguenti:
- Creazione di uno screen saver
- Installazione di nuovi screen saver
- Aggiunta della Guida alla finestra di dialogo Configurazione screen saver
Creazione di uno screen saver
A intervalli che variano da 1 a 10 secondi, l'applicazione in questo esempio riinteziona lo schermo con uno dei quattro colori: bianco, grigio chiaro, grigio scuro e nero. L'applicazione disegna lo schermo ogni volta che riceve un messaggio di WM_TIMER . L'utente può modificare l'intervallo in cui viene inviato questo messaggio selezionando la finestra di dialogo di configurazione dell'applicazione e modificando una singola barra di scorrimento orizzontale.
Libreria di screen saver
Le funzioni dello screen saver statico sono contenute nella libreria screen saver. Sono disponibili due versioni della libreria, Scrnsave.lib e Scrnsavw.lib. È necessario collegare il progetto a uno di questi. Scrnsave.lib viene usato per gli screen saver che usano caratteri ANSI e Scrnsavw.lib viene usato per gli screen saver che usano caratteri Unicode. Uno screen saver collegato a Scrnsavw.lib verrà eseguito solo su piattaforme Windows che supportano Unicode, mentre uno screen saver collegato a Scrnsave.lib verrà eseguito in qualsiasi piattaforma Windows.
Supporto della finestra di dialogo di configurazione
La maggior parte degli screen saver fornisce una finestra di dialogo di configurazione per consentire all'utente di specificare i dati di personalizzazione, ad esempio colori univoci, velocità di disegno, spessore linea, tipi di carattere e così via. Per supportare la finestra di dialogo di configurazione, l'applicazione deve fornire un modello di finestra di dialogo e deve supportare anche la funzione ScreenSaverConfigureDialog . Di seguito è riportato il modello della finestra di dialogo per l'applicazione di esempio.
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
È necessario definire la costante utilizzata per identificare il modello di finestra di dialogo usando il valore decimale 2003, come nell'esempio seguente:
#define DLG_SCRNSAVECONFIGURE 2003
Nell'esempio seguente viene illustrata la funzione ScreenSaverConfigureDialog trovata nell'applicazione di esempio.
#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;
}
Oltre a fornire il modello di finestra di dialogo e il supporto della funzione ScreenSaverConfigureDialog , un'applicazione deve supportare anche la funzione RegisterDialogClasses . Questa funzione registra le classi di finestre non standard richieste dallo screen saver. Poiché l'applicazione di esempio usa solo classi di finestra standard nella relativa procedura di dialogo, questa funzione restituisce semplicemente TRUE, come nell'esempio seguente:
BOOL WINAPI RegisterDialogClasses(hInst)
HANDLE hInst;
{
return TRUE;
}
Supporto della procedura della finestra dello screen saver
Ogni screen saver deve supportare una procedura di finestra denominata ScreenSaverProc. Come la maggior parte delle procedure della finestra, ScreenSaverProc elabora un set di messaggi specifici e passa tutti i messaggi non elaborati a una routine predefinita. Tuttavia, invece di passarli alla funzione DefWindowProc , ScreenSaverProc passa messaggi non elaborati alla funzione DefScreenSaverProc . Un'altra differenza tra ScreenSaverProc e una normale procedura della finestra è che l'handle passato a ScreenSaverProc identifica l'intero desktop anziché una finestra client. Nell'esempio seguente viene illustrata la procedura della finestra ScreenSaverProc per lo screen saver di esempio.
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);
}
Creazione di un file di definizione del modulo
Le funzioni ScreenSaverProc e ScreenSaverConfigureDialog devono essere esportate nel file di definizione del modulo dell'applicazione;RegisterDialogClasses non deve tuttavia essere esportato. Nell'esempio seguente viene illustrato il file di definizione del modulo per l'applicazione di esempio.
NAME SSTEST.SCR
DESCRIPTION 'SCRNSAVE : Test'
STUB 'WINSTUB.EXE'
EXETYPE WINDOWS
CODE MOVEABLE
DATA MOVEABLE MULTIPLE
HEAPSIZE 1024
STACKSIZE 4096
EXPORTS
ScreenSaverProc
ScreenSaverConfigureDialog
Installazione di nuovi screen saver
Quando si compila l'elenco degli screen saver disponibili, il Pannello di controllo cerca la directory di avvio di Windows per i file con estensione scr. Poiché gli screen saver sono file eseguibili windows standard con estensioni .exe, è necessario rinominarli in modo che abbiano estensioni con estensione scr e copiarle nella directory corretta.
Aggiunta della Guida alla finestra di dialogo Configurazione screen saver
La finestra di dialogo di configurazione per uno screen saver include in genere un pulsante Della Guida . Le applicazioni screen saver possono controllare l'identificatore del pulsante della Guida e chiamare la funzione WinHelp nello stesso modo in cui viene fornita la Guida in altre applicazioni basate su Windows.