I wrote this sample program which I use to write small games (among other things) with Purebasic v5.73 in 64 bits.
You must check "Enable DPI aware executable (Windows)" in Compiler Options
This template allows you to write programs with a working OpenWindowedScreen screen:
1) Regardless of screen resolution
2) Regardless of magnification scale factor (DPI), 100, 125, 150, 170%, etc.
3) Define a margin around the Screen screen if you don't want it to take up the entire screen
4) To respect the proportions of the OpenWindowedScreen screen.
You can test by putting:
1) Any value for the Screen you want (lines 21 and 22)
2) Any screen resolution and scaling factor on your computer.
You can also change the margin around the OpenWindowedScreen screen, if you want to by changing the "Marge" value in line 111.
It works every time.
The problem I encountered is that it doesn't work properly on Purebasic V6.00.
Do you have the same problem with this program with version v6.00 of Purebasic?
I don't know how to tell the publisher of PureBasic.
Code: Select all
;= Ce modèle permet d'écrire des programmes avec un écran OpenWindowedScreen qui fonctione :
;= 1) Quelle que soit la résolution d'écran
;= 2) Quel que soit le facteur d'échelle d'agrandissement (DPI), 100, 125, 150, 170%, etc.
;= 3) De définir une marge autour de l'écran Screen si on souhaite que celui-ci ne prenne pas tout l'écran
;= 4) De respecter les proportions de l'écran OpenWindowedScreen
;----- Options
EnableExplicit ; Déclaration obligatoire des variables
;----- Initialisation de l'environement
InitSprite() ; Nécessaire pour utiliser une fenêtre Screen
InitKeyboard() ; Nécessaire pour utiliser le clavier dans la fenêtre Screen
;----- Déclaration des procédures
Declare AfficherJeu()
Declare CreationBoule()
Declare FaireApparaitreBarreDeTaches()
Declare FaireDisparaitreBarreDeTaches()
;----- Constantes
#LargeurJeu=1366 ; Largeur de l'espace du jeu
#HauteurJeu=768 ; Hauteur de l'espace du jeu
#ABM_SETSTATE = $A ; Valeur utilisée dans la routine fausant apparaître ou disparaître la barre de tâches Windows
#LargeurBoule=200 ; Largeur de la boule en pixels
#HauteurBoule=200 ; Hauteur de la boule en pixels
;----- Enumérations
Enumeration
#FenetreMere ; Id de la fenêtre Windows mère (couvrira tout l'écran et sera mise en couleur de fond noire)
#FenetreJeu ; Id de la fenêtre Windows qui contiendra l'écran Screen du jeu
#Police64B ; Police de taille 64 et en gras
#Boule ; Sprite dune boule
EndEnumeration
;----- Variables
Global LargeurBureau.w ; Largeur du bureau sans le facteur d'agrandissement
Global HauteurBureau.w ; Hauteur du bureau sans le facteur d'agrandissement
Global RatioJeu.f ; Rapport #LargeurJeu / #HauteurJeu
Global EchelleL.f ; Facteur d'échelle d'affichage en largeur
; Cocher la case "Activer le facteur d'échelle d'affichage DPI (Windows)" dans Options du Compilateur
Global EchelleH.f ; Facteur d'échelle d'affichage en Hauteur
Global Event.w ; Evènements sur les fenêtres
Global LargeurJeu.w ; Largeur de l'écran jeu après recalcul en fonction de l'écran sur lequel tourne le jeu
Global HauteurJeu.w ; Hauteur de l'écran jeu après recalcul en fonction de l'écran sur lequel tourne le jeu
Global Marge.w ; Marge éventuelle ajoutée autour de l'écran de jeu
Global XJeu.w ; Coordonnée X de la fenêtre Windows contenant l'écran du jeu
Global YJeu.w ; Coordonnée Y de la fenêtre Windows contenant l'écran du jeu
; Utilisée dans les routines pour faire disparaître ou apparaître la barre de tâche Windows (Auteur : RASHAD)
Global AppBarData
Global tbdata.AppBarData
Global TaskBar
Global Police64B.w
Global JeuTermine.b ; Si #True alors le jeu est terminé
;----- Initialisation début programme
ExamineDesktops()
; Chercher les valeurs absolues des dimensions du bureau en pixel
LargeurBureau=DesktopWidth(0) ; sa largeur en pixels
HauteurBureau=DesktopHeight(0); sa hauteur en pixels
; Calculer le rapport entre la largeur et la hauteur de l'écran de jeu
RatioJeu=#LargeurJeu/#HauteurJeu
; Chercher le facteur d'échelle d'affichage (DPI)
EchelleL=DesktopScaledX(100)/100
EchelleH=DesktopScaledY(100)/100
; Recalculer les dimensions du bureau en fonction du facteur d'échelle DPI
LargeurBureau / EchelleL
HauteurBureau / EchelleH
;----- Polices de caractères
; La taille des polices est recalculée en fonction du facteur d'échelle d'affichage
Police64B= LoadFont(#Police64B, "Calibri", 56/EchelleL,#PB_Font_Bold)
; Créer la fenêtre Windows mère
OpenWindow(#FenetreMere,0,0,LargeurBureau,HauteurBureau,"TEST",
#PB_Window_BorderLess | #PB_Window_Maximize) ; Maximize sinon petites lignes sur les bords del'écran
SetWindowColor(#FenetreMere, #Cyan) ; Fond de fenêtre (pour cacher l'arrière plan en dehors de l'écran du jeu)
;HideWindow(#FenetreMere,#True) ; si on ne souhaite pas cacher ce qui est en dehors de l'écran de jeu
; Créer la fenêtre Windows du jeu
OpenWindow(#FenetreJeu,0,0,100,100,"", #PB_Window_BorderLess) ; Coordonnées et dimensions provisoires
; Créer le fenêtre Screen du jeu
OpenWindowedScreen(WindowID(#FenetreJeu), 0 , 0,
#LargeurJeu, #HauteurJeu,
#True, 0, 0)
; Recalcul des dimensions de l'écran de jeu en tenant compte des dimensions de l'écran sur lequel tourne
; le programme et recalcul éventuel en respectant les proportions initiales de l'écran de jeu
LargeurJeu=#LargeurJeu
HauteurJeu=#HauteurJeu
HauteurJeu=HauteurBureau
LargeurJeu=HauteurBureau * RatioJeu
If LargeurJeu>LargeurBureau
LargeurJeu=LargeurBureau
HauteurJeu=LargeurJeu / RatioJeu
If HauteurJeu>HauteurBureau
HauteurJeu=HauteurBureau
LargeurJeu=HauteurJeu * RatioJeu
EndIf
EndIf
; Eventuellement, on peut réduire la fenêtre de jeu si on souhaite avoir des marges (noires) tout autour
; Bien sûr
Marge=200 ; Marge horizontale en nombre de pixels (Marge à gauche + marge à droite)
LargeurJeu-Marge ; La marge sera de Marge/2 pixels à gauche et de Marge/2 pixels à droite
Marge / RatioJeu ; La marge verticale est recalculée en fonction du rapport #LargeurJeu/#HauteurJeu
HauteurJeu-Marge ; La marge sera de Marge/2 pixels en haut et de Marge/2 pixels en bas
; Calcul des coordonnées dela fenêtre de jeu pour qu'elle soit centrée à l'écran
XJeu=(LargeurBureau-LargeurJeu)/2
YJeu=(HauteurBureau-HauteurJeu)/2
; Redimensionnement de la fenêtre de jeu qui contient l'écran Screen
ResizeWindow(#FenetreJeu,XJeu,YJeu,LargeurJeu,HauteurJeu)
StickyWindow(#FenetreJeu, #True) ; Fenêtre toujours au premier plan
; Cacher la barre de tâches Windows avant de commencer le jeu
FaireDisparaitreBarreDeTaches()
CreationBoule()
JeuTermine=#False
;----- Boucle principale
Repeat
Repeat
Event = WindowEvent()
Until Event = 0
SetActiveWindow(#FenetreJeu) ; Force la #FenetreJeu au premier plan car si clic sur la fenêtre mère
; le KeyboardPushed(#PB_Key_Escape) ne fonctionne pas
ClearScreen(#Yellow)
AfficherJeu()
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
While KeyboardPushed(#PB_Key_Escape)
ExamineKeyboard()
Wend
JeuTermine=#True
EndIf
FlipBuffers()
Until JeuTermine
; Faire réapparaître la barre de tâches Windows une fois le jeu terminé
FaireApparaitreBarreDeTaches()
End
; Affichage du jeu
Procedure AfficherJeu()
Protected Longueur.w, Hauteur.w, Libelle.s, vY.b=68
StartDrawing(ScreenOutput())
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(Police64B )
Libelle="Gauche haut"
Longueur=TextWidth(Libelle)
Hauteur=TextHeight(libelle)
DrawText(0,-18, Libelle, #Black)
DrawingFont(Police64B )
Libelle="Droit haut"
Longueur=TextWidth(Libelle)
Hauteur=TextHeight(libelle)
DrawText(#LargeurJeu-Longueur,0, Libelle, #Black)
DrawingFont(Police64B )
Libelle="Droit bas"
Longueur=TextWidth(Libelle)
Hauteur=TextHeight(libelle)
DrawText(#LargeurJeu-Longueur,#HauteurJeu-Hauteur, Libelle, #Black)
DrawText(0,vY,"Première ligne",#Black)
DrawText(0,vY*2,"Deuxième ligne",#Black)
DrawText(0,vY*3,"Troisième ligne",#Black)
DrawText(0,vY*4,"Quatrième ligne",#Black)
DrawText(0,vY*5,"0AZERTYUIOPQSDFGHJKLMWXCVBNAZERI9",#Black)
DrawText(0,vY*6,"Sixième ligne",#Black)
DrawText(0,vY*7,"Septième ligne",#Black)
DrawText(0,vY*8,"Huitième ligne",#Black)
DrawText(0,vY*9,"Neuvième ligne",#Black)
DrawText(0,vY*10,"Dixième ligne",#Black)
StopDrawing()
DisplayTransparentSprite(#Boule, (#LargeurJeu-#LargeurBoule)/2, #HauteurJeu-#HauteurBoule)
EndProcedure
; Création du sprite
Procedure CreationBoule()
CreateSprite(#Boule,#LargeurBoule,#HauteurBoule)
StartDrawing(SpriteOutput(#Boule))
DrawingMode(#PB_2DDrawing_Gradient)
BackColor(RGB(255,255,255))
FrontColor(RGB(0,0,255))
CircularGradient(100, 100, 100)
Circle(100, 100, 100)
CircularGradient(350, 100, 75)
Circle(300, 100, 100)
StopDrawing()
EndProcedure
; Faire apparaître la barre de tâche Windows (Auteur : RASHAD)
Procedure FaireApparaitreBarreDeTaches()
TaskBar = FindWindow_("Shell_TrayWnd",0)
tbdata\cbSize = SizeOf(tbdata)
tbdata\hwnd = TaskBar
tbdata\lParam = 0
SHAppBarMessage_(#ABM_SETSTATE,@tbdata)
EndProcedure
; Faire disparaître la barre de tâche Windows (Auteur : RASHAD)
Procedure FaireDisparaitreBarreDeTaches()
TaskBar = FindWindow_("Shell_TrayWnd",0)
tbdata\cbSize = SizeOf(tbdata)
tbdata\hwnd = TaskBar
tbdata\lParam = 1
SHAppBarMessage_(#ABM_SETSTATE,@tbdata)
EndProcedure