Donc pCapsFlags contient la liste des possibilités utilisables parmi
VideoControlFlags.
Mais comment je peux "extraire" la liste des possibilités?
Par exemple, comment je dois faire pour savoir si pCapsFlags contient
VideoControlFlag_FlipHorizontal?
J'imagine que ça doit être tout con (à base de << je pense) mais j'y arrive
pas...
Question liée:
Il faudra que j'utilise une fonction SetMode
HRESULT SetMode (
IPin *pPin,
long Mode
);
et donner à Mode la liste des possibilités... Donc l'inverse de la première
question, comment créer un long Mode contenant par exemple
VideoControlFlag_FlipVertical et VideoControlFlag_Trigger?
Mais comment je peux "extraire" la liste des possibilités?
IPin* pin; une interface valide long capsFlags;
if (GetCaps(pin, &capsFlags) == S_OK){ if ((capsFlags & 1) == 1) { le flip horizontal est supporté } if ((capsFlags & 2) == 2) { le flip vertical est supporté } if ((capsFlags & 4) == 4) { le trigger externe est supporté } if ((capsFlags & 8) == 8) { le trigger est supporté } }
bcp de fonctions fonctionnent ainsi un renseignant un entier selon "une matrice de bits de configuration" ... c'est pas bien sorcier.
Sylvain.
Michael wrote on 01/11/2006 15:50:
HRESULT GetCaps (IPin *pPin, long *pCapsFlags);
pCapsFlags
[out] Pointer to a value representing a combination of the flags from the
VideoControlFlags enumeration.
Mais comment je peux "extraire" la liste des possibilités?
IPin* pin; une interface valide
long capsFlags;
if (GetCaps(pin, &capsFlags) == S_OK){
if ((capsFlags & 1) == 1) { le flip horizontal est supporté }
if ((capsFlags & 2) == 2) { le flip vertical est supporté }
if ((capsFlags & 4) == 4) { le trigger externe est supporté }
if ((capsFlags & 8) == 8) { le trigger est supporté }
}
bcp de fonctions fonctionnent ainsi un renseignant un entier selon "une
matrice de bits de configuration" ... c'est pas bien sorcier.
Mais comment je peux "extraire" la liste des possibilités?
IPin* pin; une interface valide long capsFlags;
if (GetCaps(pin, &capsFlags) == S_OK){ if ((capsFlags & 1) == 1) { le flip horizontal est supporté } if ((capsFlags & 2) == 2) { le flip vertical est supporté } if ((capsFlags & 4) == 4) { le trigger externe est supporté } if ((capsFlags & 8) == 8) { le trigger est supporté } }
bcp de fonctions fonctionnent ainsi un renseignant un entier selon "une matrice de bits de configuration" ... c'est pas bien sorcier.
Sylvain.
Michael
if (GetCaps(pin, &capsFlags) == S_OK){ if ((capsFlags & 1) == 1) { le flip horizontal est supporté } if ((capsFlags & 2) == 2) { le flip vertical est supporté } if ((capsFlags & 4) == 4) { le trigger externe est supporté } if ((capsFlags & 8) == 8) { le trigger est supporté } }
bcp de fonctions fonctionnent ainsi un renseignant un entier selon "une matrice de bits de configuration" ... c'est pas bien sorcier.
Pas bien sorcier effectivement, mais je savais pas comment faire :)
Merci
if (GetCaps(pin, &capsFlags) == S_OK){
if ((capsFlags & 1) == 1) { le flip horizontal est supporté }
if ((capsFlags & 2) == 2) { le flip vertical est supporté }
if ((capsFlags & 4) == 4) { le trigger externe est supporté }
if ((capsFlags & 8) == 8) { le trigger est supporté }
}
bcp de fonctions fonctionnent ainsi un renseignant un entier selon "une
matrice de bits de configuration" ... c'est pas bien sorcier.
Pas bien sorcier effectivement, mais je savais pas comment faire :)
if (GetCaps(pin, &capsFlags) == S_OK){ if ((capsFlags & 1) == 1) { le flip horizontal est supporté } if ((capsFlags & 2) == 2) { le flip vertical est supporté } if ((capsFlags & 4) == 4) { le trigger externe est supporté } if ((capsFlags & 8) == 8) { le trigger est supporté } }
bcp de fonctions fonctionnent ainsi un renseignant un entier selon "une matrice de bits de configuration" ... c'est pas bien sorcier.
Pas bien sorcier effectivement, mais je savais pas comment faire :)
Merci
Sylvain
Michael wrote on 01/11/2006 16:31:
Pas bien sorcier effectivement, mais je savais pas comment faire :)
y'a pas de mal à apprendre ;)
<mode débutant (et ce n'est pas péjoratif)>
si de tels opérations au niveau bit (positionnement, test positionné ou effacé) ne te sont pas familières, je t'encourage vivement à jouer avec car c'est assez souvent utile.
note également que j'ai fourni une forme verbieuse des tests; en C/C++ toute expression non nulle (différente de zéro) est évaluée comme vrai donc: if ((capsFlags & 1) == 1) {} et if (capsFlags & 1) {}
sont équivalents, dans les 2 cas on applique un "et binaire" à la variable et on évalue le résultat qui est donc 'vrai' si le bit 1 (numéroté de 1 à n, de droite (LSB: less significant bit) à gauche (MSB: more sig. bit)) de capsFlags est positionné (à 1), 'false' s'il est effacé (à 0).
tu peux, bien sur, tester plusieurs bits à la fois:
if (capsFlags & 3) { au moins un flip est supporté } ou if ((capsFlags & 7) == 4) { un trigger externe mais aucun flip }
enfin, pour la lecture de ton code, il vaut mieux, bien sur, utiliser des constantes nommées, ie:
if (capsFlags & VideoControlFlag_Trigger){ // le trigger est dispo, le traiter }
</mode>
Sylvain.
Michael wrote on 01/11/2006 16:31:
Pas bien sorcier effectivement, mais je savais pas comment faire :)
y'a pas de mal à apprendre ;)
<mode débutant (et ce n'est pas péjoratif)>
si de tels opérations au niveau bit (positionnement, test positionné ou
effacé) ne te sont pas familières, je t'encourage vivement à jouer avec
car c'est assez souvent utile.
note également que j'ai fourni une forme verbieuse des tests; en C/C++
toute expression non nulle (différente de zéro) est évaluée comme vrai donc:
if ((capsFlags & 1) == 1) {}
et
if (capsFlags & 1) {}
sont équivalents, dans les 2 cas on applique un "et binaire" à la
variable et on évalue le résultat qui est donc 'vrai' si le bit 1
(numéroté de 1 à n, de droite (LSB: less significant bit) à gauche (MSB:
more sig. bit)) de capsFlags est positionné (à 1), 'false' s'il est
effacé (à 0).
tu peux, bien sur, tester plusieurs bits à la fois:
if (capsFlags & 3) { au moins un flip est supporté }
ou
if ((capsFlags & 7) == 4) { un trigger externe mais aucun flip }
enfin, pour la lecture de ton code, il vaut mieux, bien sur, utiliser
des constantes nommées, ie:
if (capsFlags & VideoControlFlag_Trigger){
// le trigger est dispo, le traiter
}
Pas bien sorcier effectivement, mais je savais pas comment faire :)
y'a pas de mal à apprendre ;)
<mode débutant (et ce n'est pas péjoratif)>
si de tels opérations au niveau bit (positionnement, test positionné ou effacé) ne te sont pas familières, je t'encourage vivement à jouer avec car c'est assez souvent utile.
note également que j'ai fourni une forme verbieuse des tests; en C/C++ toute expression non nulle (différente de zéro) est évaluée comme vrai donc: if ((capsFlags & 1) == 1) {} et if (capsFlags & 1) {}
sont équivalents, dans les 2 cas on applique un "et binaire" à la variable et on évalue le résultat qui est donc 'vrai' si le bit 1 (numéroté de 1 à n, de droite (LSB: less significant bit) à gauche (MSB: more sig. bit)) de capsFlags est positionné (à 1), 'false' s'il est effacé (à 0).
tu peux, bien sur, tester plusieurs bits à la fois:
if (capsFlags & 3) { au moins un flip est supporté } ou if ((capsFlags & 7) == 4) { un trigger externe mais aucun flip }
enfin, pour la lecture de ton code, il vaut mieux, bien sur, utiliser des constantes nommées, ie:
if (capsFlags & VideoControlFlag_Trigger){ // le trigger est dispo, le traiter }
</mode>
Sylvain.
Michael
Merci pour tes éclaircissementss...
J'ai cependant une question:
je voudrais faire une fonction qui ajoute un enlève un bit selon qu'il soit placé ou non...
Exemple simple:
enum t { i = 0x0001, j = 0x0002, k = 0x0004, l = 0x0008 };
long f(long l) { //1 n'est pas positionné, on l'ajoute if ((x & 1) != 1) x |= 1; else //On l'enlève }
Comment faire pour n'enlever que cette valeur?
Merci :)
Merci pour tes éclaircissementss...
J'ai cependant une question:
je voudrais faire une fonction qui ajoute un enlève un bit selon qu'il soit
placé ou non...
Exemple simple:
enum t {
i = 0x0001,
j = 0x0002,
k = 0x0004,
l = 0x0008 };
long f(long l)
{
//1 n'est pas positionné, on l'ajoute
if ((x & 1) != 1)
x |= 1;
else
//On l'enlève
}
je voudrais faire une fonction qui ajoute un enlève un bit selon qu'il soit placé ou non...
Exemple simple:
enum t { i = 0x0001, j = 0x0002, k = 0x0004, l = 0x0008 };
long f(long l) { //1 n'est pas positionné, on l'ajoute if ((x & 1) != 1) x |= 1; else //On l'enlève }
Comment faire pour n'enlever que cette valeur?
Merci :)
Sylvain
Michael wrote on 01/11/2006 19:22:
long f(long l) { //1 n'est pas positionné, on l'ajoute if ((x & 1) != 1) x |= 1; else //On l'enlève }
Comment faire pour n'enlever que cette valeur?
pour enlever une valeur seule, on fait un "et binaire" avec un mask où ce bit est à 0 (pour l'effacer) et tous les autres à 1 (pour conserver leurs valeurs courantes qlq soit k in (0,1), (k & 1) == k).
on obtient un tel mask via un "non binaire" sur ce bit.
soit: x &= ~1;
"1" est 000...001, not(1) ou ~1 donne 111...110
Sylvain.
Michael wrote on 01/11/2006 19:22:
long f(long l)
{
//1 n'est pas positionné, on l'ajoute
if ((x & 1) != 1)
x |= 1;
else
//On l'enlève
}
Comment faire pour n'enlever que cette valeur?
pour enlever une valeur seule, on fait un "et binaire" avec un mask où
ce bit est à 0 (pour l'effacer) et tous les autres à 1 (pour conserver
leurs valeurs courantes qlq soit k in (0,1), (k & 1) == k).
on obtient un tel mask via un "non binaire" sur ce bit.
long f(long l) { //1 n'est pas positionné, on l'ajoute if ((x & 1) != 1) x |= 1; else //On l'enlève }
Comment faire pour n'enlever que cette valeur?
pour enlever une valeur seule, on fait un "et binaire" avec un mask où ce bit est à 0 (pour l'effacer) et tous les autres à 1 (pour conserver leurs valeurs courantes qlq soit k in (0,1), (k & 1) == k).
on obtient un tel mask via un "non binaire" sur ce bit.
soit: x &= ~1;
"1" est 000...001, not(1) ou ~1 donne 111...110
Sylvain.
Loïc Joly
Merci pour tes éclaircissementss...
J'ai cependant une question:
je voudrais faire une fonction qui ajoute un enlève un bit selon qu'il soit placé ou non...
Exemple simple:
enum t { i = 0x0001, j = 0x0002, k = 0x0004, l = 0x0008 };
long f(long l) { //1 n'est pas positionné, on l'ajoute if ((x & 1) != 1) x |= 1; else //On l'enlève }
Pour inverser un bit directement, tu peux faire un ou exclusif avec la valeur 1.
void f(long &x, long mask) { x ^= mask; }
Ici, tous les bits de x dont le bit correspondant dans mask était à 1 on inversé leur valeur.
Merci pour tes éclaircissementss...
J'ai cependant une question:
je voudrais faire une fonction qui ajoute un enlève un bit selon qu'il soit
placé ou non...
Exemple simple:
enum t {
i = 0x0001,
j = 0x0002,
k = 0x0004,
l = 0x0008 };
long f(long l)
{
//1 n'est pas positionné, on l'ajoute
if ((x & 1) != 1)
x |= 1;
else
//On l'enlève
}
Pour inverser un bit directement, tu peux faire un ou exclusif avec la
valeur 1.
void f(long &x, long mask)
{
x ^= mask;
}
Ici, tous les bits de x dont le bit correspondant dans mask était à 1 on
inversé leur valeur.
je voudrais faire une fonction qui ajoute un enlève un bit selon qu'il soit placé ou non...
Exemple simple:
enum t { i = 0x0001, j = 0x0002, k = 0x0004, l = 0x0008 };
long f(long l) { //1 n'est pas positionné, on l'ajoute if ((x & 1) != 1) x |= 1; else //On l'enlève }
Pour inverser un bit directement, tu peux faire un ou exclusif avec la valeur 1.
void f(long &x, long mask) { x ^= mask; }
Ici, tous les bits de x dont le bit correspondant dans mask était à 1 on inversé leur valeur.
James Kanze
Michael wrote:
Merci pour tes éclaircissementss...
J'ai cependant une question:
je voudrais faire une fonction qui ajoute un enlève un bit selon qu'il soit placé ou non...
Exemple simple:
enum t { i = 0x0001, j = 0x0002, k = 0x0004, l = 0x0008 };
long f(long l) { //1 n'est pas positionné, on l'ajoute if ((x & 1) != 1) x |= 1; else //On l'enlève }
Plusieurs commentaires :
-- Sylvain s'est sans doute servi des valeurs numériques à titre pédagogique, pour que tu vois exactement ce qui se passe, mais dans la pratique, on utilise de préférence les valeurs symboliques, c-à-d : if ( (x & i) != 0 ) ... De même, on utilise prèsque toujours une comparaison avec zéro, pour ne pas être dépendant de la valeur numérique (et pour ne pas avoir à répéter le symbole). Dans les cas où il s'agit en fait des valeurs booléenes (à un bit), je trouve que : if ( x & i ) ... est aussi acceptable, même si je ne m'en sers pas moi-même.
-- Une petite sommaire des opérations disponibles :
if ( x & i ) : test le bit, vrai s'il est à 1 x |= i ; le met à un x &= ~i ; le rémet à zéro x ^= i ; complémente le bit
Plus généralement, quand il s'agit des champs non booléens, on aurait quelque chose du genre :
switch ( x & condMask ) { case condA : case condB : // ... }
Et pour le mettre à une valeur prédéterminée :
x = (x & ~condMask) | nouvelleValeur ;
Tout ça à condition que x soit une variable de type entier, et non de type enum.
(Mais comme a dit Sylvain, il serait préférable que tu apprends la représentation binaire et ses opérateurs, plutôt que d'appliquer des formules à l'aveugle.)
-- Quand la définition de l'enum se trouve dans le C++ (ton premier exemple suggérait du C), il n'est pas rare de surcharger les opérateurs, pour pouvoir se servir des opérations directement sur des variables de type enum. Donc, on aurait :
t operator|( t lhs, t rhs ) { return (t)( (unsigned)lhs | (unsigned)rhs ) ; }
et ainsi de suite, ce qui permet d'écrire :
t x = i | k ; x |= j ;
Moi-même, j'ai pris l'habitude de surcharger également les opérateurs + (même sémantique que |), - (a - b vaut a & ~b) et * (&). Je ne sais pas si c'est une bonne idée ; ça frôle vraiment l'abus du surcharge. Mais les opérateurs +, - et * ont la bonne priorité, à l'encontre de | et &, et le - est bien commode.
J'ai même un petit programme à ma site qui génère automatiquement ces opérateurs (selon les options : il génère aussi automatiquement un mapping vers texte, et pour les enum classiques, les opérateurs d'incrémentation et de decrémentation). Voir http://kanze.james.neuf.fr/doc/man/man1/enumgen.man.html et la description des « bitwise operators », et plus généralement http://kanze.james.neuf.fr/code-fr.html pour information sur le code en général.
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Michael wrote:
Merci pour tes éclaircissementss...
J'ai cependant une question:
je voudrais faire une fonction qui ajoute un enlève un bit
selon qu'il soit placé ou non...
Exemple simple:
enum t {
i = 0x0001,
j = 0x0002,
k = 0x0004,
l = 0x0008 };
long f(long l)
{
//1 n'est pas positionné, on l'ajoute
if ((x & 1) != 1)
x |= 1;
else
//On l'enlève
}
Plusieurs commentaires :
-- Sylvain s'est sans doute servi des valeurs numériques à
titre pédagogique, pour que tu vois exactement ce qui se
passe, mais dans la pratique, on utilise de préférence les
valeurs symboliques, c-à-d :
if ( (x & i) != 0 ) ...
De même, on utilise prèsque toujours une comparaison avec
zéro, pour ne pas être dépendant de la valeur numérique (et
pour ne pas avoir à répéter le symbole). Dans les cas où il
s'agit en fait des valeurs booléenes (à un bit), je trouve
que :
if ( x & i ) ...
est aussi acceptable, même si je ne m'en sers pas moi-même.
-- Une petite sommaire des opérations disponibles :
if ( x & i ) : test le bit, vrai s'il est à 1
x |= i ; le met à un
x &= ~i ; le rémet à zéro
x ^= i ; complémente le bit
Plus généralement, quand il s'agit des champs non booléens,
on aurait quelque chose du genre :
switch ( x & condMask ) {
case condA :
case condB :
// ...
}
Et pour le mettre à une valeur prédéterminée :
x = (x & ~condMask) | nouvelleValeur ;
Tout ça à condition que x soit une variable de type entier,
et non de type enum.
(Mais comme a dit Sylvain, il serait préférable que tu
apprends la représentation binaire et ses opérateurs, plutôt
que d'appliquer des formules à l'aveugle.)
-- Quand la définition de l'enum se trouve dans le C++ (ton
premier exemple suggérait du C), il n'est pas rare de
surcharger les opérateurs, pour pouvoir se servir des
opérations directement sur des variables de type enum. Donc,
on aurait :
t
operator|( t lhs, t rhs )
{
return (t)( (unsigned)lhs | (unsigned)rhs ) ;
}
et ainsi de suite, ce qui permet d'écrire :
t x = i | k ;
x |= j ;
Moi-même, j'ai pris l'habitude de surcharger également les
opérateurs + (même sémantique que |), - (a - b vaut a & ~b)
et * (&). Je ne sais pas si c'est une bonne idée ; ça frôle
vraiment l'abus du surcharge. Mais les opérateurs +, - et *
ont la bonne priorité, à l'encontre de | et &, et le - est
bien commode.
J'ai même un petit programme à ma site qui génère
automatiquement ces opérateurs (selon les options : il
génère aussi automatiquement un mapping vers texte, et pour
les enum classiques, les opérateurs d'incrémentation et de
decrémentation). Voir
http://kanze.james.neuf.fr/doc/man/man1/enumgen.man.html et
la description des « bitwise operators », et plus
généralement http://kanze.james.neuf.fr/code-fr.html pour
information sur le code en général.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
je voudrais faire une fonction qui ajoute un enlève un bit selon qu'il soit placé ou non...
Exemple simple:
enum t { i = 0x0001, j = 0x0002, k = 0x0004, l = 0x0008 };
long f(long l) { //1 n'est pas positionné, on l'ajoute if ((x & 1) != 1) x |= 1; else //On l'enlève }
Plusieurs commentaires :
-- Sylvain s'est sans doute servi des valeurs numériques à titre pédagogique, pour que tu vois exactement ce qui se passe, mais dans la pratique, on utilise de préférence les valeurs symboliques, c-à-d : if ( (x & i) != 0 ) ... De même, on utilise prèsque toujours une comparaison avec zéro, pour ne pas être dépendant de la valeur numérique (et pour ne pas avoir à répéter le symbole). Dans les cas où il s'agit en fait des valeurs booléenes (à un bit), je trouve que : if ( x & i ) ... est aussi acceptable, même si je ne m'en sers pas moi-même.
-- Une petite sommaire des opérations disponibles :
if ( x & i ) : test le bit, vrai s'il est à 1 x |= i ; le met à un x &= ~i ; le rémet à zéro x ^= i ; complémente le bit
Plus généralement, quand il s'agit des champs non booléens, on aurait quelque chose du genre :
switch ( x & condMask ) { case condA : case condB : // ... }
Et pour le mettre à une valeur prédéterminée :
x = (x & ~condMask) | nouvelleValeur ;
Tout ça à condition que x soit une variable de type entier, et non de type enum.
(Mais comme a dit Sylvain, il serait préférable que tu apprends la représentation binaire et ses opérateurs, plutôt que d'appliquer des formules à l'aveugle.)
-- Quand la définition de l'enum se trouve dans le C++ (ton premier exemple suggérait du C), il n'est pas rare de surcharger les opérateurs, pour pouvoir se servir des opérations directement sur des variables de type enum. Donc, on aurait :
t operator|( t lhs, t rhs ) { return (t)( (unsigned)lhs | (unsigned)rhs ) ; }
et ainsi de suite, ce qui permet d'écrire :
t x = i | k ; x |= j ;
Moi-même, j'ai pris l'habitude de surcharger également les opérateurs + (même sémantique que |), - (a - b vaut a & ~b) et * (&). Je ne sais pas si c'est une bonne idée ; ça frôle vraiment l'abus du surcharge. Mais les opérateurs +, - et * ont la bonne priorité, à l'encontre de | et &, et le - est bien commode.
J'ai même un petit programme à ma site qui génère automatiquement ces opérateurs (selon les options : il génère aussi automatiquement un mapping vers texte, et pour les enum classiques, les opérateurs d'incrémentation et de decrémentation). Voir http://kanze.james.neuf.fr/doc/man/man1/enumgen.man.html et la description des « bitwise operators », et plus généralement http://kanze.james.neuf.fr/code-fr.html pour information sur le code en général.
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34