Les flags (drapeaux, en français) sont largement utilisés par les fonctions de PureBASIC, par exemple avec OpenWindow() pour centrer une fenêtre et en même temps la mettre en plein écran. Ils permettent donc de spécifier certaines propriétés en n'utilisant qu'une seule variable.
Mais comment cela fonctionne-t-il ?
- Un flag peut avoir pour valeur 0 ou 1.
- Un entier long (.l) est codé sur 4 octets, soit 32 bits
Pour arriver à cela, il va cependant falloir respecter quelques règles.
- La valeur de nos constantes doit être codée sur un seul bit des 32 bits.
- Il faudra veiller à ne pas écraser la valeur de la variable, on ne pourra donc pas utiliser l'affectation =
Nous pensons en base 2. On démarre du bit de poids faible 0 jusqu'au bit de poids fort 31. En décimal cela donne :
Code : Tout sélectionner
#Flag_0 = 1 ; = %1 en binaire (bit 0 fixé)
#Flag_1 = 2 ; = %10 (bit 1)
#Flag_2 = 4 ; = %100 (bit 2)
#Flag_3 = 8 ; = %1000 (bit 3)
#Flag_4 = 16 ; = %10000 (bit 4)
#Flag_5 = 32 ; = %100000 (bit 5)
#Flag_6 = 64 ; = %1000000 (bit 6)
#Flag_7 = 128 ; = %10000000 (bit 7)
#Flag_8 = 256 ; = %100000000 (bit 8)
; Etc...
Code : Tout sélectionner
#Flag_0 = $0001 (bit 0 fixé)
#Flag_1 = $0002 (bit 1)
#Flag_2 = $0004 (bit 2)
#Flag_3 = $0008 (bit 3)
#Flag_4 = $0010 (bit 4)
#Flag_5 = $0020 (bit 5)
#Flag_6 = $0040 (bit 6)
#Flag_7 = $0080 (bit 7)
#Flag_8 = $0100 (bit 8)
; etc...
Code : Tout sélectionner
EnumerationBinary
#Flags1 ; égale à 1
#Flags2 ; égale à 2
#Flags3 ; égale à 4
#Flags4 ; égale à 8
#Flags5 ; égale à 16
EndEnumeration
Code : Tout sélectionner
mesFlags = #Flag_0 | #Flag_6 ;(= %01000001 en binaire ou $0041 en hexa ou 65 en décimal)
Exemple avec 2 valeurs :
Code : Tout sélectionner
A B SORTIE
0 | 0 -> 0
0 | 1 -> 1
1 | 0 -> 1
1 | 1 -> 1
3) Lire un flag, c'est à dire lire la valeur d'un bit spécifique.
Pour ce faire nous allons utiliser le ET logique (AND), opérateur "&" en PB. Voici sa table de vérité :
Code : Tout sélectionner
A B SORTIE
0 & 0 -> 0
0 & 1 -> 0
1 & 0 -> 0
1 & 1 -> 1
Exemple :
Code : Tout sélectionner
mesFlags = #Flag_0 | #Flag_6
If mesFlags & #Flag_6
Debug "Le bit 6 est à 1"
EndIf
If mesFlags & #Flag_3
Debug "Le bit 3 est à 1"
Else
Debug "Le bit 3 est à 0"
EndIf
Pour cela nous allons utiliser l'opérateur AND (&) ainsi que l'opérateur NOT (~) comme ceci
Code : Tout sélectionner
mesFlags =mesFlags &~#Flags3
Code : Tout sélectionner
0000 0000 0010 0000 ; #Flag5 (32 en décimal)
1111 1111 1101 1111 ;devient après le NOT
Exemple complet:
Code : Tout sélectionner
EnumerationBinary
#Flags0 ; égale à 1
#Flags1 ; égale à 2
#Flags2 ; égale à 4
#Flags3 ; égale à 8
#Flags4 ; égale à 16
#Flags5 ; égale à .32
#Flags6 ;égale à 64
#Flags7 ;égale à 128
EndEnumeration
Global mesFlags .l
Procedure Lit()
For i=0 To 7
p.l=Pow(2,i)
If(mesFlags &p)
Debug "Le flags "+Str(i)+" est à 1"
Else
Debug "Le flags "+Str(i)+" est à 0"
EndIf
Next
EndProcedure
; Ici j'active le Flag 1,3 et 5
mesFlags =#Flags1|#Flags3|#Flags5
; Lecture des flags pour voir le résultat
Lit()
; ici je vai placer le flag 3 à 0
mesFlags =mesFlags &~#Flags3
; Lecture des flags pour voir le résultat
Lit()
Merci à majikeyric et djes pour leurs remarques et corrections