OVH Cloud OVH Cloud

Utilisation d'un masque binaire

7 réponses
Avatar
Guy Lafrenière
Bonjour Collègues,

J'ai créé un serveur DLL pour remplacer la fonction intégrée MsgBox. Mon
serveur offre une plus grande flexibilité que la fonction MsgBox.

Quand on transmet à la fonction MsgBox les boutons à afficher, on le fait
avec quelque chose qui ressemble à ceci: vbOkCancel + vbCritical +
vbSystemModal. Le résultat retourné est donc un nombre qui représente la
somme des valeurs saisies et qui constitue un 'masque binaire' ou quelque
chose du genre. Comment fait-on pour décortiquer ce résultat de façon à
retrouver chaque valeur pour chaque catégorie de boutons?

Merci!

7 réponses

Avatar
Zoury
Salut Guy ! :O)

Quand on transmet à la fonction MsgBox les boutons à afficher, on le fait
avec quelque chose qui ressemble à ceci: vbOkCancel + vbCritical +
vbSystemModal.



En fait, il faut employer l'opérateur binaire Or et non le plus +.

Car :
1 + 3 = 4
et
1 Or 3 = 3

Le résultat retourné est donc un nombre qui représente la
somme des valeurs saisies et qui constitue un 'masque binaire' ou quelque
chose du genre.



Yep.

Comment fait-on pour décortiquer ce résultat de façon à
retrouver chaque valeur pour chaque catégorie de boutons?



On emploi Or pour bâtir le masque et And pour le décortiquer (non testé) :
'***
Dim masque As Long

masque = vbOkCancel Or vbCritical Or vbSystemModal

If ((masque And vbCritical) = vbCritical) Then
' vbCritical est actif
End If
'***

Voici un vieux post à ce sujet qui pourrait (ou non) t'intéresser :
http://groups.google.com/groups?selm=%23HK7g711CHA.1616%40TK2MSFTNGP11.phx.gbl

--
Cordialement
Yanick
MVP pour Visual Basic
Avatar
jean-marc
"Zoury" <yanick_lefebvre at hotmail dot com> wrote in message
news:#
Salut Guy ! :O)

> Quand on transmet à la fonction MsgBox les boutons à afficher, on le


fait
> avec quelque chose qui ressemble à ceci: vbOkCancel + vbCritical +
> vbSystemModal.

En fait, il faut employer l'opérateur binaire Or et non le plus +.

Car :
1 + 3 = 4
et
1 Or 3 = 3

> Le résultat retourné est donc un nombre qui représente la
> somme des valeurs saisies et qui constitue un 'masque binaire' ou


quelque
> chose du genre.

Yep.

> Comment fait-on pour décortiquer ce résultat de façon à
> retrouver chaque valeur pour chaque catégorie de boutons?

On emploi Or pour bâtir le masque et And pour le décortiquer (non testé) :
'***
Dim masque As Long

masque = vbOkCancel Or vbCritical Or vbSystemModal

If ((masque And vbCritical) = vbCritical) Then
' vbCritical est actif
End If
'***

Voici un vieux post à ce sujet qui pourrait (ou non) t'intéresser :



http://groups.google.com/groups?selm=%23HK7g711CHA.1616%40TK2MSFTNGP11.phx.g
bl




Hello,

quelques explications en plus:
tout ceci fonctionne car les valeurs individuelles des flags à positionner
est à chaque fois une puissance de 2:
1, 2, 4, 8 16, 32, etc.

en effet, la représentation binaire de tels nombres est telle que un seul
bit est à 1 à la fois, comme ceci:

1 0001
2 0010
4 0100
8 1000
etc.

Ainsi, si A=1, B=2 et C=4,
si on veut exprimer: R = A + C ça donne
R = 00001 + 0100 = 0101

Pour "décortiquer" R, on masque avec un ET logique de la valeur rechechée:

C est il dans R ? 0101 AND 0100 = 0100 ; C'est égal à C, donc C est dans
R
B est il dans R? 0101 AND 0010 = 0000 ; C'est égal à 0, donc C n'est
PAS dans R

Tout ceci étant basé sur les propriétés de OR:
0 OR 0 = 0
0 OR 1 = 1
1 OR 0 =1
1 OR 1 = 1

et de AND
0 AND 0 = 0
0 AND 1 = 0
1 AND 0 =0
1 AND 1 = 1

--
Jean-marc
Avatar
Zoury
> Ainsi, si A=1, B=2 et C=4,
si on veut exprimer: R = A + C ça donne
R = 00001 + 0100 = 0101



mais il faut remplacer + par Or. ;O)

--
Cordialement
Yanick
MVP pour Visual Basic
Avatar
Patrice Henrio
Jean Marc a parfaitement raison et Yannick aussi, d'ailleurs j'avais
commencé ce midi à répondre comme le fait jean-marc puis j'ai eu la
curiosité de regarder les constantes utilisées pour les réponses du msgbox
et là ça va plus du tout.
petit retour en arrière

vbOKOnly 0 Affiche le bouton OK uniquement.
vbOKCancel 1 Affiche les boutons OK et Annuler.
vbAbortRetryIgnore 2 Affiche le bouton Abandonner, Réessayer et
Ignorer.
vbYesNoCancel 3 Affiche les boutons Oui, Non et Annuler.
vbYesNo 4 Affiche les boutons Oui et Non.
vbRetryCancel 5 Affiche les boutons Réessayer et Annuler.
vbCritical 16 Affiche l'icône Message critique.
vbQuestion 32 Affiche l'icône Requête d'avertissement.
vbExclamation 48 Affiche l'icône Message d'avertissement.
vbInformation 64 Affiche l'icône Message d'information.
vbDefaultButton1 0 Le premier bouton est le bouton par défaut.
vbDefaultButton2 256 Le deuxième bouton est le bouton par défaut.
vbDefaultButton3 512 Le troisième bouton est le bouton par défaut.
vbDefaultButton4 768 Le quatrième bouton est le bouton par défaut.
vbApplicationModal 0 Boîte de dialogue modale. L'utilisateur doit
répondre au message affiché dans la zone de message avant de pouvoir
continuer de travailler dans l'application en cours.
vbSystemModal 4096 Modal système. Toutes les applications sont
interrompues jusqu'à ce que l'utilisateur réponde au message affiché dans la
zone de message.
vbMsgBoxHelpButton 16384 Ajoute le bouton Aide à la zone de message.
VbMsgBoxSetForeground 65536 Indique la fenêtre de zone de message
comme fenêtre de premier plan.
vbMsgBoxRight 524288 Le teste est aligné à droite.
vbMsgBoxRtlReading 1048576 Indique que le texte doit apparaître de
droite à gauche sur les systèmes hébraïques et arabes.


Le premier groupe de valeurs (0 à 5) décrit le nombre et le type de boutons
affichés dans la boîte de dialogue. Le deuxième groupe (16, 32, 48 et 64)
décrit le style d'icône. Le troisième groupe (0, 256 et 512) définit le
bouton par défaut. Enfin, le quatrième groupe (0 et 4 096) détermine la
modalité de la zone de message. Au moment d'additionner ces nombres pour
obtenir la valeur finale de l'argument buttons, ne sélectionnez qu'un seul
nombre dans chaque groupe.



Valeurs renvoyées

Constante Valeur Description
vbOK 1 OK
vbCancel 2 Annuler
vbAbort 3 Abandonner
vbRetry 4 Réessayer
vbIgnore 5 Ignorer
vbYes 6 Oui
vbNo 7 Non



On voit très nettement que nous ne sommes plus dans le cadre des masques
binaires habituels.

Par contre on voit aussi que chaque groupe étant dans une plage de valeurs
différentes (en puissance de 2 bien sûr) l'addition marche exactement comme
le OU (ou OR).

0001 + 0100 = 0101
0001 OR 0100 = 0101

Par contre

0001 or 1111 = 1111 (soit 15)
0001 + 1111 = 10000 (soit 16)

"Zoury" <yanick_lefebvre at hotmail dot com> a écrit dans le message de
news:
Ainsi, si A=1, B=2 et C=4,
si on veut exprimer: R = A + C ça donne
R = 00001 + 0100 = 0101



mais il faut remplacer + par Or. ;O)

--
Cordialement
Yanick
MVP pour Visual Basic




Avatar
Zoury
Bonjour Messieurs ! :O)

On voit très nettement que nous ne sommes plus dans le cadre des masques
binaires habituels.



En effet, les constantes définie dans l'enum vbMsgBoxStyle ne respecte pas
les règles habituelles d'un bitmask. J'ai l'impression que le premier octet
de la valeur désigne un nombre standard (0 à 15) et que le reste est
considéré comme un bitmask. AMHA, cette pratique n'est pas courante. :O)

La question semblait portée plus sur l'emploi de masque binaire d'une
manière générale et non seulement de l'emploi des constantes définie par
vbMsgBoxStyle. Étant donnée que notre collègue Guy tente de créer sa propre
MsgBox, il peut facilement redéfinir ces valeurs comme bon lui semblera en
respectant les règles de l'art.

--
Cordialement
Yanick
MVP pour Visual Basic
Avatar
Vincent Guichard
Zoury a écrit :
Bonjour Messieurs ! :O)


On voit très nettement que nous ne sommes plus dans le cadre des masques
binaires habituels.




En effet, les constantes définie dans l'enum vbMsgBoxStyle ne respecte pas
les règles habituelles d'un bitmask. J'ai l'impression que le premier octet
de la valeur désigne un nombre standard (0 à 15) et que le reste est
considéré comme un bitmask. AMHA, cette pratique n'est pas courante. :O)

La question semblait portée plus sur l'emploi de masque binaire d'une
manière générale et non seulement de l'emploi des constantes définie par
vbMsgBoxStyle. Étant donnée que notre collègue Guy tente de créer sa propre
MsgBox, il peut facilement redéfinir ces valeurs comme bon lui semblera en
respectant les règles de l'art.




En fait, ce type de structure correspond à un bitfield. C'est tout à
fait dans les rêgle de l'art. En C, la structure correspondante serait
quelque chose comme:

struct
{
unsigned char Buttons:4;
unsigned char Type:4;
...
} config;

(Je vais travailler seulement sur le premier octet)

Les types de fenetres crées par vbOkOnly, vbOkCancel,
vbAbordRetryIgnore, vbYesNoCancel, vbYesNo, vbRetryCancel sont
mutuellement exclusives. Elles vont donc correspondre à un champ de bit
(bitfield) unique dans le "mot" de configuration. VbOkOnly est le
défault, donc 0. Les suivantes sont incrémentées de 1. Il y 6 valeurs
possibles, donc de 0 à 5. 5 est codé en binaire par 101, donc 3 bits
sont nécessaires. Probablement pour des raisons d'alignement, et pour
réserver de la place pour des cas définis ultérieurements, les
ingénieurs de MS ont choisit de faire un champ de 4 bits.

Les types de fenetres crées par vbCritical, vbQuestion, vbExclamation et
vbInformation sont également exclusives, avec en plus la possibilité
d'être aucun de ces types (normale), ce qui est le cas par défaut. On a
donc ici 4+1 = 5 valeurs, de 0 à 4. 3 bits sont suffisants, mais pour
les mêmes raisons que ci-dessus, on a choisit d'en reserver 4.

En C, on pourrait utiliser(*) directement les bonnes valeurs en disant
config.Type = 3 pour vbExclamation, mais Visual Basic ne gère pas les
bitfields, donc il faut tenir compte de l'offset du bitfield dans le
champs et donc vbExclamation devient 3 * (10000b) = 48

En fait, un bitmask est simplement un bitfield ou tous les champs sont
de longeur 1.

Vincent Guichard

(*) pourrait, parce qu'en fait on va souvent initaliser les champs de la
même façon qu'en VB. Les bitfields ne sont pas souvent présentés à
l'utilisateur mais réservés à l'implémentations interne.
Avatar
Zoury
Salut Vincent !

Merci pour la belle explication. ;O)

--
Cordialement
Yanick
MVP pour Visual Basic
"Vincent Guichard" a écrit dans le message de
news:42ba983f$0$25031$
Zoury a écrit :
> Bonjour Messieurs ! :O)
>
>
>>On voit très nettement que nous ne sommes plus dans le cadre des masques
>>binaires habituels.
>
>
> En effet, les constantes définie dans l'enum vbMsgBoxStyle ne respecte


pas
> les règles habituelles d'un bitmask. J'ai l'impression que le premier


octet
> de la valeur désigne un nombre standard (0 à 15) et que le reste est
> considéré comme un bitmask. AMHA, cette pratique n'est pas courante. :O)
>
> La question semblait portée plus sur l'emploi de masque binaire d'une
> manière générale et non seulement de l'emploi des constantes définie par
> vbMsgBoxStyle. Étant donnée que notre collègue Guy tente de créer sa


propre
> MsgBox, il peut facilement redéfinir ces valeurs comme bon lui semblera


en
> respectant les règles de l'art.
>

En fait, ce type de structure correspond à un bitfield. C'est tout à
fait dans les rêgle de l'art. En C, la structure correspondante serait
quelque chose comme:

struct
{
unsigned char Buttons:4;
unsigned char Type:4;
...
} config;

(Je vais travailler seulement sur le premier octet)

Les types de fenetres crées par vbOkOnly, vbOkCancel,
vbAbordRetryIgnore, vbYesNoCancel, vbYesNo, vbRetryCancel sont
mutuellement exclusives. Elles vont donc correspondre à un champ de bit
(bitfield) unique dans le "mot" de configuration. VbOkOnly est le
défault, donc 0. Les suivantes sont incrémentées de 1. Il y 6 valeurs
possibles, donc de 0 à 5. 5 est codé en binaire par 101, donc 3 bits
sont nécessaires. Probablement pour des raisons d'alignement, et pour
réserver de la place pour des cas définis ultérieurements, les
ingénieurs de MS ont choisit de faire un champ de 4 bits.

Les types de fenetres crées par vbCritical, vbQuestion, vbExclamation et
vbInformation sont également exclusives, avec en plus la possibilité
d'être aucun de ces types (normale), ce qui est le cas par défaut. On a
donc ici 4+1 = 5 valeurs, de 0 à 4. 3 bits sont suffisants, mais pour
les mêmes raisons que ci-dessus, on a choisit d'en reserver 4.

En C, on pourrait utiliser(*) directement les bonnes valeurs en disant
config.Type = 3 pour vbExclamation, mais Visual Basic ne gère pas les
bitfields, donc il faut tenir compte de l'offset du bitfield dans le
champs et donc vbExclamation devient 3 * (10000b) = 48

En fait, un bitmask est simplement un bitfield ou tous les champs sont
de longeur 1.

Vincent Guichard

(*) pourrait, parce qu'en fait on va souvent initaliser les champs de la
même façon qu'en VB. Les bitfields ne sont pas souvent présentés à
l'utilisateur mais réservés à l'implémentations interne.