Partager via


Gestion des filtres d’écran

L’API Microsoft Win32 prend en charge des applications spéciales appelées « écrans de capture d’écran ». Les filtres d’écran démarrent lorsque la souris et le clavier sont inactifs pendant une période spécifiée. Ils sont utilisés pour ces deux raisons :

  • Pour protéger un écran contre les brûlures au phosphore causées par des images statiques.
  • Pour masquer les informations sensibles laissées sur un écran.

Cette rubrique est divisée en sections suivantes.

À propos des filtres d’écran

L’application de bureau dans Windows Panneau de configuration permet aux utilisateurs de sélectionner dans une liste d’économiseurs d’écran, de spécifier le temps qui doit s’écouler avant le démarrage de l’économiseur d’écran, de configurer les économiseurs d’écran et d’afficher un aperçu des économiseurs d’écran. Les économiseurs d’écran sont chargés automatiquement au démarrage de Windows ou lorsqu’un utilisateur active l’économiseur d’écran via le Panneau de configuration.

Une fois qu’un économiseur d’écran est choisi, Windows surveille les séquences de touches et les mouvements de la souris, puis démarre l’économiseur d’écran après une période d’inactivité. Toutefois, Windows ne démarre pas l’économiseur d’écran si l’une des conditions suivantes existe :

  • L’application active n’est pas une application Windows.
  • Une fenêtre d’entraînement basé sur l’ordinateur (CBT) est présente.
  • L’application active reçoit le message WM_SYSCOMMAND avec le paramètre wParam défini sur la valeur SC_SCREENSAVE, mais elle ne transmet pas le message à la fonction DefWindowProc .

Contexte de sécurité de l’économiseur d’écran

Le contexte de sécurité de l’économiseur d’écran dépend de la connexion interactive d’un utilisateur. Si un utilisateur est connecté de manière interactive lors de l’appel de l’économiseur d’écran, l’économiseur d’écran s’exécute dans le contexte de sécurité de l’utilisateur interactif. Si aucun utilisateur n’est connecté, le contexte de sécurité de l’économiseur d’écran dépend de la version de Windows utilisée.

  • Windows XP et Windows 2000 : l’économiseur d’écran s’exécute dans le contexte de LocalSystem avec des comptes restreints.
  • Windows 2003 : l’économiseur d’écran s’exécute dans le contexte de LocalService avec tous les privilèges supprimés et le groupe Administrateurs désactivé.
  • Ne s’applique pas à Windows NT4.

Le contexte de sécurité détermine le niveau d’opérations privilégiées qui peuvent être effectuées à partir d’un économiseur d’écran.

Windows Vista et versions ultérieures : Si la protection par mot de passe est activée par la stratégie, l’économiseur d’écran est démarré indépendamment de ce qu’une application fait avec la notification SC_SCREENSAVE.

Les filtres d’écran contiennent des fonctions exportées, des définitions de ressources et des déclarations de variables spécifiques. La bibliothèque d’économiseur d’écran contient la fonction main et un autre code de démarrage requis pour un économiseur d’écran. Lorsqu’un économiseur d’écran démarre, le code de démarrage dans la bibliothèque d’économiseur d’écran crée une fenêtre plein écran. La classe de fenêtre pour cette fenêtre est déclarée comme suit :

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;

Pour créer un économiseur d’écran, la plupart des développeurs créent un module de code source contenant trois fonctions requises et les lient à la bibliothèque d’économiseur d’écran. Un module d’économiseur d’écran est uniquement responsable de sa configuration et de la fourniture d’effets visuels.

L’une des trois fonctions requises dans un module d’économiseur d’écran est ScreenSaverProc. Cette fonction traite des messages spécifiques et transmet tous les messages non traités à la bibliothèque d’économiseur d’écran. Voici quelques-uns des messages typiques traités par ScreenSaverProc.

Message Signification
WM_CREATE Récupérez les données d’initialisation du fichier Regedit.ini. Définissez un minuteur de fenêtre pour la fenêtre d’économiseur d’écran. Effectuer toute autre initialisation requise.
WM_ERASEBKGND Effacez la fenêtre d’économiseur d’écran et préparez les opérations de dessin suivantes.
WM_TIMER Effectuer des opérations de dessin.
WM_DESTROY Détruisez les minuteurs créés lorsque l’application a traité le message WM_CREATE . Effectuez tout nettoyage supplémentaire requis.

 

ScreenSaverProc transmet les messages non traités à la bibliothèque d’économiseur d’écran en appelant la fonction DefScreenSaverProc . Le tableau suivant décrit comment cette fonction traite différents messages.

Message Action
WM_SETCURSOR Définissez le curseur sur le curseur Null, en le supprimant de l’écran.
WM_PAINT Peindre l’arrière-plan de l’écran.
WM_LBUTTONDOWN Terminez l’économiseur d’écran.
WM_MBUTTONDOWN Terminez l’économiseur d’écran.
WM_RBUTTONDOWN Terminez l’économiseur d’écran.
WM_KEYDOWN Terminez l’économiseur d’écran.
WM_MOUSEMOVE Terminez l’économiseur d’écran.
WM_ACTIVATE Arrêtez l’économiseur d’écran si le paramètre wParam a la valeur FALSE.

 

La deuxième fonction requise dans un module d’économiseur d’écran est ScreenSaverConfigureDialog. Cette fonction affiche une boîte de dialogue qui permet à l’utilisateur de configurer l’économiseur d’écran (une application doit fournir un modèle de boîte de dialogue correspondant). Windows affiche la boîte de dialogue de configuration lorsque l’utilisateur sélectionne le bouton Configurer dans la boîte de dialogue Économiseur d’écran du Panneau de configuration.

La troisième fonction requise dans un module d’économiseur d’écran est RegisterDialogClasses. Cette fonction doit être appelée par toutes les applications d’économiseur d’écran. Toutefois, les applications qui ne nécessitent pas de fenêtres spéciales ou de contrôles personnalisés dans la boîte de dialogue de configuration peuvent simplement retourner TRUE. Les applications nécessitant des fenêtres spéciales ou des contrôles personnalisés doivent utiliser cette fonction pour inscrire les classes de fenêtre correspondantes.

En plus de créer un module qui prend en charge les trois fonctions décrites précédemment, un économiseur d’écran doit fournir une icône. Cette icône est visible uniquement lorsque l’économiseur d’écran est exécuté en tant qu’application autonome. (Pour être exécuté par le Panneau de configuration, un économiseur d’écran doit avoir l’extension de nom de fichier .scr ; pour être exécuté en tant qu’application autonome, il doit avoir l’extension de nom de fichier .exe.) L’icône doit être identifiée dans le fichier de ressources de l’économiseur d’écran par la constante ID_APP, qui est définie dans le fichier d’en-tête Scrnsave.h.

Une dernière exigence est une chaîne de description de l’économiseur d’écran. Le fichier de ressources d’un économiseur d’écran doit contenir une chaîne que le Panneau de configuration affiche comme nom de l’économiseur d’écran. La chaîne de description doit être la première chaîne de la table de chaînes du fichier de ressources (identifiée par la valeur ordinale 1). Toutefois, la chaîne de description est ignorée par le Panneau de configuration si l’économiseur d’écran a un nom de fichier long. Dans ce cas, le nom de fichier est utilisé comme chaîne de description.

Utilisation des fonctions d’économiseur d’écran

Cette section utilise un exemple de code extrait d’une application d’économiseur d’écran pour illustrer les tâches suivantes :

Création d’un économiseur d’écran

À intervalles compris entre 1 et 10 secondes, l’application de cet exemple repeint l’écran avec l’une des quatre couleurs suivantes : blanc, gris clair, gris foncé et noir. L’application peint l’écran chaque fois qu’elle reçoit un message WM_TIMER . L’utilisateur peut ajuster l’intervalle d’envoi de ce message en sélectionnant la boîte de dialogue de configuration de l’application et en ajustant une seule barre de défilement horizontale.

Bibliothèque d’économiseur d’écran

Les fonctions d’économiseur d’écran statiques sont contenues dans la bibliothèque d’économiseur d’écran. Deux versions de la bibliothèque sont disponibles : Scrnsave.lib et Scrnsavw.lib. Vous devez lier votre projet à l’un d’entre eux. Scrnsave.lib est utilisé pour les épargnants d’écran qui utilisent des caractères ANSI, et Scrnsavw.lib est utilisé pour les épargnants d’écran qui utilisent des caractères Unicode. Un économiseur d’écran lié à Scrnsavw.lib s’exécute uniquement sur les plateformes Windows qui prennent en charge Unicode, tandis qu’un économiseur d’écran lié à Scrnsave.lib s’exécute sur n’importe quelle plateforme Windows.

Prise en charge de la boîte de dialogue de configuration

La plupart des enregistreurs d’écran fournissent une boîte de dialogue de configuration pour permettre à l’utilisateur de spécifier des données de personnalisation telles que les couleurs uniques, les vitesses de dessin, l’épaisseur des lignes, les polices, etc. Pour prendre en charge la boîte de dialogue de configuration, l’application doit fournir un modèle de boîte de dialogue et doit également prendre en charge la fonction ScreenSaverConfigureDialog . Voici le modèle de boîte de dialogue de l’exemple d’application.

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

Vous devez définir la constante utilisée pour identifier le modèle de boîte de dialogue à l’aide de la valeur décimale 2003, comme dans l’exemple suivant :

#define  DLG_SCRNSAVECONFIGURE 2003

L’exemple suivant montre la fonction ScreenSaverConfigureDialog trouvée dans l’exemple d’application.

#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; 
}

En plus de fournir le modèle de boîte de dialogue et de prendre en charge la fonction ScreenSaverConfigureDialog , une application doit également prendre en charge la fonction RegisterDialogClasses . Cette fonction enregistre toutes les classes de fenêtre non standard requises par l’économiseur d’écran. Étant donné que l’exemple d’application utilisait uniquement des classes de fenêtre standard dans sa procédure de boîte de dialogue, cette fonction retourne simplement TRUE, comme dans l’exemple suivant :

BOOL WINAPI RegisterDialogClasses(hInst) 
HANDLE  hInst; 
{ 
    return TRUE; 
}

Prise en charge de la procédure de fenêtre d’économiseur d’écran

Chaque économiseur d’écran doit prendre en charge une procédure de fenêtre nommée ScreenSaverProc. Comme la plupart des procédures de fenêtre, ScreenSaverProc traite un ensemble de messages spécifiques et passe tous les messages non traités à une procédure par défaut. Toutefois, au lieu de les transmettre à la fonction DefWindowProc , ScreenSaverProc transmet les messages non traités à la fonction DefScreenSaverProc . Une autre différence entre ScreenSaverProc et une procédure de fenêtre normale est que le handle passé à ScreenSaverProc identifie l’ensemble du bureau plutôt qu’une fenêtre cliente. L’exemple suivant montre la procédure de fenêtre ScreenSaverProc pour l’exemple d’économiseur d’écran.

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); 
}

Création d’un fichier de définition de module

Les fonctions ScreenSaverProc et ScreenSaverConfigureDialog doivent être exportées dans le fichier de définition de module de l’application ; Toutefois, RegisterDialogClasses ne doit pas être exporté. L’exemple suivant montre le fichier de définition de module pour l’exemple d’application.

NAME    SSTEST.SCR 

DESCRIPTION 'SCRNSAVE : Test' 
 
STUB    'WINSTUB.EXE' 
EXETYPE WINDOWS 
 
CODE    MOVEABLE 
DATA    MOVEABLE MULTIPLE 
 
HEAPSIZE  1024 
STACKSIZE 4096 
 
EXPORTS 
        ScreenSaverProc 
        ScreenSaverConfigureDialog

Installation de nouveaux enregistreurs d’écran

Lors de la compilation de la liste des enregistreurs d’écran disponibles, le Panneau de configuration recherche les fichiers avec l’extension .scr dans le répertoire de démarrage de Windows. Étant donné que les enregistreurs d’écran sont des fichiers exécutables Windows standard avec des extensions .exe, vous devez les renommer afin qu’ils aient des extensions .scr et les copier dans le répertoire approprié.

Ajout d’aide à la boîte de dialogue Configuration de l’économiseur d’écran

La boîte de dialogue de configuration d’un économiseur d’écran comprend généralement un bouton Aide . Les applications d’économiseur d’écran peuvent case activée pour l’identificateur du bouton Aide et appeler la fonction WinHelp de la même façon que l’aide est fournie dans d’autres applications Windows.