Un module pour écran de veille.
Publié : mer. 01/juil./2026 22:22
Un module pour écran de veille.
PB : 6.40
Os : Windows 11
Contient des API
J'ai cherché sur le forum des exemples d'écran de veille.
Ceux que j'ai trouvé était codé dans des versions ancienne de PB, ou me semblait trop compliqué.
Alors, j'ai trié et testé jusqu'a ce que j'arrive à comprendre comment cela fonctionne.
J'avoue que l'écran de prévisualisation m'a donné du fil à retordre, mais cette fois tout y est.
"Module ScreenSaver.pb" et là pour simplifier le codage.
ScreenSaver::CheckStatus ( )
************************************************************************************
* En mode économiseur d'écran, recherchez toute action de l'utilisateur
* Return-Value: 1 si quelque chose a bougé depuis la dernière boucle
************************************************************************************
ScreenSaver::Start ( saverName.s )
************************************************************************************
* Garantit qu'une seule instance du programme sera lancée
* Parameters: Nom de l'économiseur (utilisé pour nommer le mutex)
************************************************************************************
ScreenSaver::Stop ( )
************************************************************************************
* Libérer le mutex pour permettre le lancement d'une autre instance
************************************************************************************
ScreenSaver::GetWinSaver ( )
************************************************************************************
* Passe en mode Ecran de veille et en informe Windows
* Return-Value: Identifiant de la fenêtre créée en mode plein écran
************************************************************************************
ScreenSaver::GetWinPreview ( )
************************************************************************************
* Passe en mode prévisualisation et crée une fenêtre fille
* Return-Value: Identifiant de la fenêtre créée en mode prévisualisation
************************************************************************************
ScreenSaver::IsScreenSaverMode ( )
************************************************************************************
* Teste si l'on se trouve en mode Ecran de veille
* Return-Value: 1 si oui, 0 si non
************************************************************************************
ScreenSaver::GetParameter ( )
***************************************************************
* Pour prévisualiser l'écran de veille Windows lance l'application
* en lui passant -P, /P ou P en premier paramètre.
* Le second paramètre est le Handle de la fenêtre dans laquelle doit s'afficher l'écran de veille.
*
* Pour la configuration, le paramètre est -> /C
* Les paramètres peuvent commencer par un - ou un /
*
* Pour l'écran de veille, le paramètre est -> /S
***************************************************************
ScreenSaver::GetRatioX ( )
ScreenSaver::GetRatioY ( )
************************************************************************************
* Calcule le facteur d'échelle
* Un GetWinSaver() ou GetWinPreview() doit être appelé.
* Return-Value: Le rapport de la fenêtre retournée par rapport au plein écran
************************************************************************************
Le module :
Un exemple d'écran de veille avec :
Fenêtre de configuration.
Sauvegarde de la configuration dans un fichier INI.
Chargement de la configuration depuis un fichier INI.
Gestion des paramètres passés à l'application : /c , /s , /p:55312.
Récupération de la fenêtres.
Affichage dans celle-ci en tenant compte du facteur d'échelle.
Une fois compilé, remplacer .exe par .scr
J'espère avoir fait suffisamment simple pour le rendre accessible à tous.
PB : 6.40
Os : Windows 11
Contient des API
J'ai cherché sur le forum des exemples d'écran de veille.
Ceux que j'ai trouvé était codé dans des versions ancienne de PB, ou me semblait trop compliqué.
Alors, j'ai trié et testé jusqu'a ce que j'arrive à comprendre comment cela fonctionne.
J'avoue que l'écran de prévisualisation m'a donné du fil à retordre, mais cette fois tout y est.
"Module ScreenSaver.pb" et là pour simplifier le codage.
ScreenSaver::CheckStatus ( )
************************************************************************************
* En mode économiseur d'écran, recherchez toute action de l'utilisateur
* Return-Value: 1 si quelque chose a bougé depuis la dernière boucle
************************************************************************************
ScreenSaver::Start ( saverName.s )
************************************************************************************
* Garantit qu'une seule instance du programme sera lancée
* Parameters: Nom de l'économiseur (utilisé pour nommer le mutex)
************************************************************************************
ScreenSaver::Stop ( )
************************************************************************************
* Libérer le mutex pour permettre le lancement d'une autre instance
************************************************************************************
ScreenSaver::GetWinSaver ( )
************************************************************************************
* Passe en mode Ecran de veille et en informe Windows
* Return-Value: Identifiant de la fenêtre créée en mode plein écran
************************************************************************************
ScreenSaver::GetWinPreview ( )
************************************************************************************
* Passe en mode prévisualisation et crée une fenêtre fille
* Return-Value: Identifiant de la fenêtre créée en mode prévisualisation
************************************************************************************
ScreenSaver::IsScreenSaverMode ( )
************************************************************************************
* Teste si l'on se trouve en mode Ecran de veille
* Return-Value: 1 si oui, 0 si non
************************************************************************************
ScreenSaver::GetParameter ( )
***************************************************************
* Pour prévisualiser l'écran de veille Windows lance l'application
* en lui passant -P, /P ou P en premier paramètre.
* Le second paramètre est le Handle de la fenêtre dans laquelle doit s'afficher l'écran de veille.
*
* Pour la configuration, le paramètre est -> /C
* Les paramètres peuvent commencer par un - ou un /
*
* Pour l'écran de veille, le paramètre est -> /S
***************************************************************
ScreenSaver::GetRatioX ( )
ScreenSaver::GetRatioY ( )
************************************************************************************
* Calcule le facteur d'échelle
* Un GetWinSaver() ou GetWinPreview() doit être appelé.
* Return-Value: Le rapport de la fenêtre retournée par rapport au plein écran
************************************************************************************
Le module :
Code : Tout sélectionner
; Version = "Module ScreenSaver-20260628"
DeclareModule ScreenSaver
; ******** Constantes et variables Publiques ***************
; ******** Declaration des procedures Publiques ***************
Declare .a CheckStatus ( )
Declare Start ( saverName.s )
Declare Stop ( )
Declare .i GetWinSaver ( )
Declare .i GetWinPreview ( )
Declare .a IsScreenSaverMode ( )
Declare .s GetParameter ( )
Declare .f GetRatioX ( )
Declare .f GetRatioY ( )
EndDeclareModule
Module ScreenSaver
; ******** Constantes et variables privées ***************
Enumeration
#ScreenSaverMode
#PreviewMode
EndEnumeration
Global width .l
Global height .l
Global RatioX .f
Global RatioY .f
Global SaverMode .b
Global previewWndHandleStr$ = ""
; ******** Procedures Privées ***************
; ******** Procedures Publiques ************
;************************************************************************************
; Garantit qu'une seule instance du programme sera lancée
; Parameters: Nom de l'économiseur (utilisé pour nommer le mutex)
;************************************************************************************
Procedure Start(saverName.s)
Shared OnlyOneStartMutex.l
Protected OnlyOneStartError.l
*MutexName = @saverName
OnlyOneStartMutex = CreateMutex_(0, 1, *MutexName)
OnlyOneStartError = GetLastError_()
If OnlyOneStartMutex <> 0 And OnlyOneStartError = 0
ProcedureReturn 1
Else
CloseHandle_(OnlyOneStartMutex)
End
EndIf
EndProcedure
;************************************************************************************
; Libérer le mutex pour permettre le lancement d'une autre instance
;************************************************************************************
Procedure Stop()
SystemParametersInfo_ ( #SPI_SCREENSAVERRUNNING , 0 , @oldval , 0 ) ; Indiquez au système que l'économiseur d'écran n'est plus en fonction
CloseHandle_(OnlyOneStartMutex)
EndProcedure
;************************************************************************************
; En mode économiseur d'écran, recherchez toute action de l'utilisateur
; Return-Value: 1 si quelque chose a bougé depuis la dernière boucle
;************************************************************************************
Procedure .a CheckStatus ( )
If saverMode = #ScreenSaverMode
ExamineKeyboard() : ExamineMouse()
If MouseDeltaX() Or MouseDeltaY() Or KeyboardPushed(#PB_Key_All) Or MouseButton(#PB_MouseButton_Left) Or MouseButton(#PB_MouseButton_Right)
ProcedureReturn 1
EndIf
If GetActiveWindow() = ScreenID()
ProcedureReturn 1
EndIf
EndIf
ProcedureReturn 0
EndProcedure
;************************************************************************************
; Passe en mode Ecran de veille et en informe Windows
; Return-Value: Identifiant de la fenêtre créée en mode plein écran
;************************************************************************************
Procedure .i GetWinSaver ( )
saverMode = #ScreensaverMode
SystemParametersInfo_ ( #SPI_SCREENSAVERRUNNING , 1 , @oldval , 0 )
ExamineDesktops ( )
RatioX = 1.0
RatioY = 1.0
ProcedureReturn OpenWindow ( #PB_Any , 0 , 0 , DesktopWidth( 0 ) , DesktopHeight( 0 ) , "" , #PB_Window_BorderLess )
EndProcedure
;************************************************************************************
; Passe en mode previsualisation et crée une fenêtre fille
; Return-Value: Identifiant de la fenêtre créée en mode previsualisation
;************************************************************************************
Procedure .i GetWinPreview ( )
saverMode = #PreviewMode
DisplayHwnd = Val ( previewWndHandleStr$ )
GetClientRect_ ( DisplayHwnd , @PSize.RECT )
width = PSize\right
height = PSize\bottom
ExamineDesktops ( )
RatioX = width / DesktopWidth ( 0 )
RatioY = height / DesktopHeight ( 0 )
ProcedureReturn OpenWindow ( #PB_Any , 0 , 0 , width , height , "" , #WS_CHILD , DisplayHwnd )
EndProcedure
;************************************************************************************
; Teste si l'on se trouve en mode Ecran de veille
; Return-Value: 1 si oui, 0 si non
;************************************************************************************
Procedure .a IsScreenSaverMode ( )
ProcedureReturn Bool( SaverMode = #ScreenSaverMode )
EndProcedure
; ***************************************************************
; Pour prévisualiser l'écran de veille Windows lance l'application
; en lui passant -P, /P ou P en premier paramètre.
; Le second paramètre est le Handle de la fenêtre dans laquelle doit s'afficher l'écran de veille.
;
; Pour la configuration, les paramètres sont par exemple -> /C
;
; Les paramètres peuvent commencer par un - ou un /
; Entre le premier et le deuxième paramètre il peut y avoir un deux-points ou un espace.
; S'ils sont connectés par deux points, PB ne le reconnaît pas comme deux paramètres, et enregistre les deux dans Parametre1
; ***************************************************************
Procedure .s GetParameter ( )
Protected .s Parameter$ = ProgramParameter( 0 )
If Len( Parameter$ ) > 2 ; Deux paramètres en un "/C:3606164"
previewWndHandleStr$ = RemoveString ( Parameter$ , Left( Parameter$ , 3 ) , 1 )
Parameter$ = RemoveString ( Parameter$ , Left( Parameter$ , 1 ) , 1 )
Parameter$ = Left ( Parameter$ , 1 )
Else ; Deux paramètres séparé -> /p /12345
If Len( Parameter$ ) > 1
Parameter$ = RemoveString ( Parameter$ , Left( Parameter$ , 1 ) , 1 )
EndIf
previewWndHandleStr$ = ProgramParameter( 1 )
If FindString ( previewWndHandleStr$ , "-" , 0 ) <> 0 : previewWndHandleStr$ = RemoveString ( previewWndHandleStr$ , "-" , 1 ) : EndIf
If FindString ( previewWndHandleStr$ , "/" , 0 ) <> 0 : previewWndHandleStr$ = RemoveString ( previewWndHandleStr$ , "/" , 1 ) : EndIf
EndIf
ProcedureReturn Parameter$
EndProcedure
;************************************************************************************
; Calcule le facteur d'échelle
; Un GetWinSaver() ou GetWinPreview() doit être appelé.
; Return-Value: Le rapport de la fenêtre retournée par rapport au plein écran
;************************************************************************************
Procedure .f GetRatioX ( )
ProcedureReturn RatioX
EndProcedure
Procedure .f GetRatioY ( )
ProcedureReturn RatioY
EndProcedure
; ******* Initialisation *******
InitKeyboard ( )
InitMouse ( )
EndModule
Un exemple d'écran de veille avec :
Fenêtre de configuration.
Sauvegarde de la configuration dans un fichier INI.
Chargement de la configuration depuis un fichier INI.
Gestion des paramètres passés à l'application : /c , /s , /p:55312.
Récupération de la fenêtres.
Affichage dans celle-ci en tenant compte du facteur d'échelle.
Code : Tout sélectionner
Global .f RectWidth
Global .f RectHeight
Global .l RectColor
Global .s Parameter
XIncludeFile "Module ScreenSaver.pb"
Procedure SaveParametre()
OpenPreferences ( "Rectangle.ini" )
PreferenceGroup ( "Rectangle" )
WritePreferenceLong ( "Width" , RectWidth )
WritePreferenceLong ( "Height" , RectHeight )
WritePreferenceLong ( "Color" , RectColor )
ClosePreferences()
EndProcedure
Procedure LoadParametre()
OpenPreferences("Rectangle.ini")
PreferenceGroup("Rectangle")
RectWidth = ReadPreferenceLong( "Width" , 20 )
RectHeight = ReadPreferenceLong( "Height" , 20 )
RectColor = ReadPreferenceLong( "Color" , #Green )
ClosePreferences()
EndProcedure
Procedure ShowConfig()
Protected .u Y = 20
Protected FenetreParametre .i = OpenWindow ( #PB_Any , 0 , 0 , 350 , 180 , "Configuration" , #PB_Window_SystemMenu | #PB_Window_ScreenCentered )
Protected TextLargeure .i = TextGadget ( #PB_Any , 20 , Y , 80 , 20 , "Largeur" )
Protected StringLargeur .i = StringGadget ( #PB_Any , 120 , y , 80 , 20 , Str( RectWidth ) , #PB_String_Numeric )
y + 30
Protected TextHauteur .i = TextGadget ( #PB_Any , 20 , y , 80 , 20 , "Hauteur" )
Protected StringHauteur .i = StringGadget ( #PB_Any , 120 , y , 80 , 20 , Str( RectHeight ) , #PB_String_Numeric )
y + 30
Protected ImageCouleur .i = CreateImage ( #PB_Any , 80 , 20 , 24 , RectColor )
Protected TextCouleur .i = TextGadget ( #PB_Any , 20 , y , 80 , 20 , "Couleur" )
Protected ButtonCouleur .i = ButtonImageGadget ( #PB_Any , 120 , y , 80 , 20 , ImageID( ImageCouleur ) )
y + 30
Protected ButtonOk .i = ButtonGadget ( #PB_Any , 40 , y , 100 , 30 , "OK" )
Protected ButtonAnnuler .i = ButtonGadget ( #PB_Any , 180 , y , 100 , 30 , "Annuler" )
SetGadgetText( StringLargeur , Str( RectWidth ) )
SetGadgetText( StringHauteur , Str( RectHeight ) )
Protected .a Fini = #False
Repeat
Event = WindowEvent( )
If Event
Select EventWindow()
Case FenetreParametre
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case ButtonOk
RectWidth = Val( GetGadgetText( StringLargeur ) )
RectHeight = Val( GetGadgetText( StringHauteur ) )
SaveParametre()
Fini = #True
;CaseEnd
Case ButtonAnnuler
Fini = #True
;CaseEnd
Case ButtonCouleur
RectColor = ColorRequester()
StartDrawing( ImageOutput( ImageCouleur ) )
FrontColor( RectColor )
Box(0, 0, 80, 20)
StopDrawing()
SetGadgetState ( ButtonCouleur, ImageID( ImageCouleur ) )
;CaseEnd
EndSelect
;CaseEnd
EndSelect
;CaseEnd
EndSelect
Else
Delay( 10 )
EndIf
Until Fini
CloseWindow( FenetreParametre )
EndProcedure
Parameter = ScreenSaver::GetParameter()
LoadParametre()
Select UCase( Parameter )
Case "C" ;"C" => écran de configuration.
ShowConfig( )
End
;CaseEnd
Case "P" ; Mode Aperçu. Ce paramètre est suivi d'un autre, le handle de la fenêtre d'aperçu : '-p -123456' ou '/p /12345'
Win_0 = ScreenSaver::GetWinPreview( )
;CaseEnd
Case "S" , "" ; Mode Ecran de veille
Win_0 = ScreenSaver::GetWinSaver()
;CaseEnd
Default
End
;DefaultEnd
EndSelect
;========================================================
; Rectangle rebondissant
; PureBasic 6.40
;========================================================
ScreenSaver::Start("Rectangle rebondissant") ; Autoriser une seule instance de ce programme "Rectangle rebondissant"
; -----------------------------
; Paramètres
; -----------------------------
Global BackColor = #Black
Global .f SpeedX = 5
Global .f SpeedY = 4
Global .f PosX = 0
Global .f PosY = 0
Global .f ScreenW = WindowWidth ( Win_0 )
Global .f ScreenH = WindowHeight ( Win_0 )
; -----------------------------
; Calcule le rapport d'échelle : Fenêtre_Previsu / Fenêtre_Bureau
; -----------------------------
ExamineDesktops()
Global .f DesktopW = DesktopWidth(0)
Global .f DesktopH = DesktopHeight(0)
Global .f EchelleX = ScreenSaver::GetRatioX()
Global .f EchelleY = ScreenSaver::GetRatioY()
InitSprite()
OpenWindowedScreen ( WindowID( Win_0 ) , 0 , 0 , ScreenW , ScreenH , #True , 0 , 0 , #PB_Screen_WaitSynchronization )
Repeat
Repeat
Until WindowEvent() = 0
; ---------------------------------------
; Déplacement ( les coordonnées sont calculées pour la Fenêtre_Bureau )
; ---------------------------------------
PosX + SpeedX
PosY + SpeedY
If PosX <= 0
PosX = 0
SpeedX = -SpeedX
EndIf
If PosY <= 0
PosY = 0
SpeedY = -SpeedY
EndIf
If PosX + RectWidth >= DesktopW
PosX = DesktopW - RectWidth
SpeedX = -SpeedX
EndIf
If PosY + RectHeight >= DesktopH
PosY = DesktopH - RectHeight
SpeedY = -SpeedY
EndIf
; ---------------------------------------
; Dessin ( Tenir compte du rapport d'échelle pour l'affichage, Tailles et positions )
; Les dimensions de la fenêtre dépendent du mode : Aperçu 'P' ou Ecran de veille 'S'
; ---------------------------------------
ClearScreen( BackColor )
If StartDrawing(ScreenOutput() )
Box( PosX * EchelleX , PosY * EchelleY , RectWidth * EchelleX , RectHeight * EchelleY , RectColor )
StopDrawing()
EndIf
FlipBuffers()
; ---------------------------------------
Delay(10)
If ScreenSaver::IsScreenSaverMode() ; Si en mode écran de veille
If ScreenSaver::CheckStatus() ; Si une touche est pressée
ScreenSaver::Stop() ; Indiquez au système que l'économiseur d'écran n'est plus en fonction
Break ; On quitte
EndIf
EndIf
ForEver
J'espère avoir fait suffisamment simple pour le rendre accessible à tous.