Exemple Screen + Alt-Tab et Alt-Enter
Publié : sam. 03/janv./2026 18:46
Bonjour à tous,
J'ai remis au propre un code que j'avais fait il y a quelques années ...
Je le partage avec vous car ça peut servir, surtout pour les debutants.
Si certain on des propositions d'amélioration n'hesitez pas.
J'ai remis au propre un code que j'avais fait il y a quelques années ...
Je le partage avec vous car ça peut servir, surtout pour les debutants.
Si certain on des propositions d'amélioration n'hesitez pas.
Code : Tout sélectionner
EnableExplicit
; -----------------------------------------------------------------------------
; Structure contenant tous les paramètres et états liés à l'affichage
; -----------------------------------------------------------------------------
Structure screenStruct
isFullScreen.b ; 0 = fenêtré, 1 = plein écran
screenWidth.l ; largeur souhaitée
screenHeight.l ; hauteur souhaitée
screenDepth.l ; profondeur de couleur (bits)
screenFlags.l ; flags PB pour l'écran (sync, etc.)
screenTitle.s ; titre
spriteMouse.i ; ID du sprite utilisé comme curseur
mouseX.l ; position X de la souris
mouseY.l ; position Y de la souris
EndStructure
; Instance globale de la structure d'écran
Global Screen.screenStruct
; -----------------------------------------------------------------------------
; Initialisation des valeurs par défaut
; -----------------------------------------------------------------------------
Screen\isFullScreen = #False
Screen\screenWidth = 1280
Screen\screenHeight = 720
Screen\screenDepth = 32
Screen\screenFlags = #PB_Screen_SmartSynchronization
Screen\screenTitle = "Demo Alt-Tab / Alt-Enter"
; -----------------------------------------------------------------------------
; Création des assets (ici un sprite 16x16 pour simuler un curseur rouge)
; -----------------------------------------------------------------------------
Procedure InitAssets()
; Création du sprite + démarrage d'un contexte de dessin sur ce sprite
If CreateSprite(Screen\spriteMouse, 16, 16, #PB_Sprite_AlphaBlending) And StartDrawing(SpriteOutput(Screen\spriteMouse))
; Permet de dessiner avec gestion complète de l'alpha (canaux RGBA)
DrawingMode(#PB_2DDrawing_AllChannels)
; Dessine un cercle rouge centré (8,8) de rayon 8 (curseur simple)
Circle(8, 8, 8, RGBA(255, 0, 0, 255))
StopDrawing()
Else
Debug "Error Draw cursor"
EndIf
EndProcedure
; -----------------------------------------------------------------------------
; Initialisation de l'écran selon le mode : plein écran ou fenêtré
; Retourne #True si OK
; -----------------------------------------------------------------------------
Procedure.b InitScreen()
If Screen\isFullScreen
; En plein écran, on parcourt les modes disponibles pour trouver un mode
; au moins égal à la résolution demandée, avec un refresh à 60 Hz.
ExamineScreenModes()
While NextScreenMode()
If ScreenModeWidth() >= Screen\screenWidth And ScreenModeHeight() >= Screen\screenHeight And ScreenModeRefreshRate() = 60
Screen\screenWidth = ScreenModeWidth()
Screen\screenHeight = ScreenModeHeight()
Break
EndIf
Wend
; Ouverture de l'écran plein écran
If OpenScreen(Screen\screenWidth, Screen\screenHeight, Screen\screenDepth, Screen\screenTitle, #PB_Screen_WaitSynchronization)
ProcedureReturn #True
Else
MessageRequester("Erreur", "Impossible d'ouvrir l'écran")
End
EndIf
Else
; En fenêtré : création d'une fenêtre PB puis d'un "WindowedScreen" dedans.
; DesktopUnscaledX/Y évite certaines surprises avec le scaling Windows (DPI).
If OpenWindow(0, 0, 0, DesktopUnscaledX(Screen\screenWidth), DesktopUnscaledY(Screen\screenHeight),
Screen\screenTitle, #PB_Window_ScreenCentered) And
OpenWindowedScreen(WindowID(0), 0, 0, Screen\screenWidth, Screen\screenHeight, #False, 0, 0, #PB_Screen_WaitSynchronization)
ProcedureReturn #True
EndIf
EndIf
EndProcedure
; -----------------------------------------------------------------------------
; Gestion du ALT+TAB (perte de focus / écran inactif)
; Idée : si l'écran n'est plus actif, on ferme et on attend le retour d'activation.
; -----------------------------------------------------------------------------
Procedure CheckScreenFocus()
; IsScreenActive() = 0 => l'écran n'est plus actif (ex: Alt-Tab)
If IsScreenActive() = 0
; Libère les sprites
;TODO FreeAssets()
FreeSprite(Screen\spriteMouse)
; Crée une micro-fenêtre minimisée/borderless pour "garder un handle" Window
; pendant qu'on ferme l'écran. Le but est d'attendre un événement d'activation.
OpenWindow(0, 1, 1, 1, 1, Screen\screenTitle, #PB_Window_Minimize | #PB_Window_BorderLess)
; Ferme l'écran plein écran / windowed screen
CloseScreen()
Protected Event.l
Repeat
Event = WaitWindowEvent()
; Si l'utilisateur ferme la fenêtre, on quitte
If Event = #PB_Event_CloseWindow
End
Break
EndIf
; On attend que la fenêtre reçoive l'événement d'activation
Until Event = #PB_Event_ActivateWindow
; Une fois réactivé, on ferme la petite fenêtre
CloseWindow(0)
; On réinitialise écran + assets
InitScreen()
InitAssets()
EndIf
EndProcedure
; -----------------------------------------------------------------------------
; Bascule fenêtré <-> plein écran via ALT + Entrée
; -----------------------------------------------------------------------------
Procedure ToggleFullScreen()
; XOR logique : inverse 0/1
Screen\isFullScreen ! 1
; Si on passe en plein écran, il faut fermer la fenêtre fenêtrée aussi.
If Screen\isFullScreen = #True
CloseScreen()
CloseWindow(0)
Else
; Si on repasse en fenêtré, on ferme juste l'écran (la fenêtre sera recréée)
CloseScreen()
EndIf
; Ré-ouvre le bon mode + re-crée les assets (curseur)
InitScreen()
InitAssets()
EndProcedure
; -----------------------------------------------------------------------------
; Boucle principale
; -----------------------------------------------------------------------------
Procedure Main()
Protected Event.i
; Init des systèmes
InitSprite()
InitKeyboard()
InitMouse()
; Init affichage + assets
InitScreen()
InitAssets()
Repeat
; En mode fenêtré, on doit vider les événements Window pour éviter le "freeze"
If Screen\isFullScreen = #False
Repeat
Event = WindowEvent()
Until Event = 0
EndIf
; Efface l'écran
ClearScreen(RGB(0, 0, 32))
; Mise à jour clavier/souris
ExamineKeyboard()
ExamineMouse()
; Lecture position souris
Screen\mouseX = MouseX()
Screen\mouseY = MouseY()
; Affiche le sprite du curseur à la position souris
DisplayTransparentSprite(Screen\spriteMouse, Screen\mouseX, Screen\mouseY)
; Gestion ALT + Entrée => toggle plein écran
If KeyboardPushed(#PB_Key_LeftAlt) Or KeyboardPushed(#PB_Key_RightAlt)
If KeyboardReleased(#PB_Key_Return)
ToggleFullScreen()
EndIf
EndIf
; Affiche le Buffer (double buffering)
FlipBuffers()
; Gestion ALT+TAB / perte d'activation
CheckScreenFocus()
; Petite pause CPU (1ms) pour ne pas monopoliser inutilement
Delay(1)
Until KeyboardPushed(#PB_Key_Escape)
; Nettoyage
CloseScreen()
EndProcedure
Main()