Page 1 sur 1

Un module pour écran de veille.

Publié : mer. 01/juil./2026 22:22
par plabouro472
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 :

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

Une fois compilé, remplacer .exe par .scr

J'espère avoir fait suffisamment simple pour le rendre accessible à tous.