Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Nom des périphériques MIDI

8 réponses
Avatar
Gilbert Dejardin
Bonjour tout le monde.

C'est la première fois que j'utilise les news group, j'espère que cela sera
fructueux.

J'ai une question très ciblée.

J'ai écrit un début de programme qui par la suite me permettra de gérer
certaine chose en midi, la première étape consiste à déterminer le nombre de
périphérique MIDI connecté à l'ordi. Pour ça, pas de soucis. Ensuite, il
faut récupérer les noms des différents périphériques pour que ce soit plus
compréhensible à l'utilisation. Et c'est là que le bas blesse. Quand je
récupère ces information là, je me retrouve avec du texte en chinois. Ca
ressemblerais apparemment à un problème d'unicode alors qu'on est en
ascii... Mais les différents texte affiché représente exactement les même
symbole pour chacun des périphériques, ce qui n'est pas très logique.

Je pense donc avoir plus d'un problème devant les yeux.

Est ce que quelqu'un peut m'aider s'il vous plait.

Je suis sur Windows 7 x64 avec Visual C++ Express 2010

Merci d'avance.

Gilbert.


La partie de code concernée :

Form1(void)
{
InitializeComponent();
//
//TODO: ajoutez ici le code du constructeur
//
numberOfMidiIn = midiInGetNumDevs();
numberOfMidiOut = midiOutGetNumDevs();
this->textBox1->Text = "" + numberOfMidiIn;
this->textBox2->Text = "" + numberOfMidiOut;
int i = numberOfMidiIn - 1;
UINT_PTR uip = (UINT_PTR)&i; // J'ai des doutes également sur mon
pointeur
while (i>=0)
{
MIDIINCAPS midiInCaps; // Est ce que cette initialisation est
correcte?
midiInGetDevCaps(uip,&midiInCaps,sizeof(midiInCaps));
String^ str = gcnew String(midiInCaps.szPname); // Est ce que ceci
est correcte
this->comboBox1->Items->Add(str);
i--;
}

i = (UINT)numberOfMidiOut - 1;
while (i>=0)
{
MIDIOUTCAPS midiOutCaps;
midiOutGetDevCaps(uip,&midiOutCaps,sizeof(midiOutCaps));
String^ str = gcnew String(midiOutCaps.szPname);
this->comboBox2->Items->Add(str);
i--;
}

}

8 réponses

Avatar
Olivier Miakinen
Bonjour,

Le 29/10/2010 11:21, Gilbert Dejardin a écrit :

C'est la première fois que j'utilise les news group, j'espère que cela sera
fructueux.

J'ai une question très ciblée.



Je ne suis pas sûr que ce soit une question spécifiquement de C++, et il
est probable que fr.comp.os.ms-windows.programmation soit un groupe plus
adapté, mais je vais essayer de répondre tout de même.

J'ai écrit un début de programme qui par la suite me permettra de gérer
certaine chose en midi, la première étape consiste à déterminer le nombre de
périphérique MIDI connecté à l'ordi. Pour ça, pas de soucis. Ensuite, il
faut récupérer les noms des différents périphériques pour que ce soit plus
compréhensible à l'utilisation. Et c'est là que le bas blesse. Quand je
récupère ces information là, je me retrouve avec du texte en chinois. Ca
ressemblerais apparemment à un problème d'unicode alors qu'on est en
ascii... Mais les différents texte affiché représente exactement les même
symbole pour chacun des périphériques, ce qui n'est pas très logique.



Ok.

La partie de code concernée :

Form1(void)
{
InitializeComponent();
//
//TODO: ajoutez ici le code du constructeur
//
numberOfMidiIn = midiInGetNumDevs();
numberOfMidiOut = midiOutGetNumDevs();



J'ai trouvé ceci :
http://msdn.microsoft.com/en-us/library/dd798456(v=VS.85).aspx
http://msdn.microsoft.com/en-us/library/dd798472(v=VS.85).aspx

Je suppose que numberOfMidiIn et numberOfMidiOut sont déclarés de type UINT.

int i = numberOfMidiIn - 1;
UINT_PTR uip = (UINT_PTR)&i; // J'ai des doutes également sur mon
pointeur



Ce serait mieux si i était de type UINT aussi, mais du coup ta boucle
décroissante (avec test i >= 0) ne fonctionnera plus :

while (i>=0)



Je propose :

UINT i;
for (i = 0; i < numberOfMidiIn; i++)

C'est à la fois plus simple, plus lisible et plus sûr, et en outre tu
obtiendras les noms dans l'ordre croissant des numéros plutôt que dans
l'ordre inverse.

{
MIDIINCAPS midiInCaps; // Est ce que cette initialisation est
correcte?



Il semble que oui :
<http://msdn.microsoft.com/en-us/library/dd798453(v=VS.85).aspx>

midiInGetDevCaps(uip,&midiInCaps,sizeof(midiInCaps));



MMRESULT res = midiInGetDevCaps(&i, &midiInCaps,
sizeof(midiInCaps));

... et ne pas oublier de tester le code de retour.

String^ str = gcnew String(midiInCaps.szPname); // Est ce que ceci
est correcte



Aucune idée : je ne connais pas cette syntaxe avec « ^ » et cette
fonction gcnew. J'ai trouvé ceci, mais ça me semble assez nébuleux :
http://msdn.microsoft.com/en-us/library/te3ecsc8(VS.80).aspx

Qui plus est, il faudrait s'assurer qu'un tableau de TCHAR peut se
transtyper sans problème en String (ou en String ^).
http://msdn.microsoft.com/en-us/library/dd798451(VS.85).aspx

this->comboBox1->Items->Add(str);



J'ai la flemme d'aller chercher la doc de cette fonction, mais j'imagine
qu'elle prend en paramètre un String et pas un String ^.
À vérifier là encore.

i--;



À supprimer, bien sûr, avec la construction for() au lieu de while().

}

[...]



Cordialement,
--
Olivier Miakinen
Avatar
Olivier Miakinen
Le 29/10/2010 18:22, je répondais à Gilbert Dejardin :

[...] je vais essayer de répondre tout de même.



À mon avis, le code suivant a quelques chances de fonctionner mieux que
le précédent, modulo mon absence de connaissance de ces fonctions, et
surtout de la conversion de TCHAR[] en String (¹).

Form1(void)
{
InitializeComponent();
//
//TODO: ajoutez ici le code du constructeur
//
UINT numberOfMidiIn = midiInGetNumDevs();
UINT numberOfMidiOut = midiOutGetNumDevs();
this->textBox1->Text = "" + numberOfMidiIn;
this->textBox2->Text = "" + numberOfMidiOut;
UINT i;

for (i = 0; i < numberOfMidiIn; i++)
{
MIDIINCAPS midiInCaps;
MMRESULT res;
res = midiInGetDevCaps(&i, &midiInCaps, sizeof(midiInCaps));
if (res == MMSYSERR_NOERROR) [
String str = (String) midiInCaps.szPname; (¹)
this->comboBox1->Items->Add(str);
}
}

for (i = 0; i < numberOfMidiOut; i++)
{
MIDIOUTCAPS midiOutCaps;
MMRESULT res;
res = midiOutGetDevCaps(&i, &midiOutCaps, sizeof(midiOutCaps));
if (res == MMSYSERR_NOERROR) [
String str = (String) midiOutCaps.szPname; (¹)
this->comboBox1->Items->Add(str);
}
}

}


(¹) Chercher dans <http://www.google.fr/search?q=TCHAR+String+msdn> ou
aller voir dans le groupe fr.comp.os.ms-windows.programmation !
Avatar
Gilbert Dejardin
Merci pour toutes tes infos, je vais aller voir ce que ça raconte, j'espère
que ces symbole chinois vont disparaitre.

A bientôt, peut être

Gilbert.

"Olivier Miakinen" a écrit dans le message de groupe de discussion :
4ccafce7$

Le 29/10/2010 18:22, je répondais à Gilbert Dejardin :

[...] je vais essayer de répondre tout de même.



À mon avis, le code suivant a quelques chances de fonctionner mieux que
le précédent, modulo mon absence de connaissance de ces fonctions, et
surtout de la conversion de TCHAR[] en String (¹).

Form1(void)
{
InitializeComponent();
//
//TODO: ajoutez ici le code du constructeur
//
UINT numberOfMidiIn = midiInGetNumDevs();
UINT numberOfMidiOut = midiOutGetNumDevs();
this->textBox1->Text = "" + numberOfMidiIn;
this->textBox2->Text = "" + numberOfMidiOut;
UINT i;

for (i = 0; i < numberOfMidiIn; i++)
{
MIDIINCAPS midiInCaps;
MMRESULT res;
res = midiInGetDevCaps(&i, &midiInCaps, sizeof(midiInCaps));
if (res == MMSYSERR_NOERROR) [
String str = (String) midiInCaps.szPname; (¹)
this->comboBox1->Items->Add(str);
}
}

for (i = 0; i < numberOfMidiOut; i++)
{
MIDIOUTCAPS midiOutCaps;
MMRESULT res;
res = midiOutGetDevCaps(&i, &midiOutCaps, sizeof(midiOutCaps));
if (res == MMSYSERR_NOERROR) [
String str = (String) midiOutCaps.szPname; (¹)
this->comboBox1->Items->Add(str);
}
}

}


(¹) Chercher dans <http://www.google.fr/search?q=TCHAR+String+msdn> ou
aller voir dans le groupe fr.comp.os.ms-windows.programmation !
Avatar
Gilbert Dejardin
Et bien voila!

J'ai changé ma boucle, pour économiser des variables

Mais les conversions ne sont toujours pas correcte.

Je vais aller voir du côté du groupe os win

Merci pour votre aide.


"Olivier Miakinen" a écrit dans le message de groupe de discussion :
4ccafce7$

Le 29/10/2010 18:22, je répondais à Gilbert Dejardin :

[...] je vais essayer de répondre tout de même.



À mon avis, le code suivant a quelques chances de fonctionner mieux que
le précédent, modulo mon absence de connaissance de ces fonctions, et
surtout de la conversion de TCHAR[] en String (¹).

Form1(void)
{
InitializeComponent();
//
//TODO: ajoutez ici le code du constructeur
//
UINT numberOfMidiIn = midiInGetNumDevs();
UINT numberOfMidiOut = midiOutGetNumDevs();
this->textBox1->Text = "" + numberOfMidiIn;
this->textBox2->Text = "" + numberOfMidiOut;
UINT i;

for (i = 0; i < numberOfMidiIn; i++)
{
MIDIINCAPS midiInCaps;
MMRESULT res;
res = midiInGetDevCaps(&i, &midiInCaps, sizeof(midiInCaps));
if (res == MMSYSERR_NOERROR) [
String str = (String) midiInCaps.szPname; (¹)
this->comboBox1->Items->Add(str);
}
}

for (i = 0; i < numberOfMidiOut; i++)
{
MIDIOUTCAPS midiOutCaps;
MMRESULT res;
res = midiOutGetDevCaps(&i, &midiOutCaps, sizeof(midiOutCaps));
if (res == MMSYSERR_NOERROR) [
String str = (String) midiOutCaps.szPname; (¹)
this->comboBox1->Items->Add(str);
}
}

}


(¹) Chercher dans <http://www.google.fr/search?q=TCHAR+String+msdn> ou
aller voir dans le groupe fr.comp.os.ms-windows.programmation !
Avatar
Gilbert Dejardin
Re bonjour;

Voila, j'ai trouvé d'où vient le soucis.

Ce que j'avais écrit n'était pas si mauvais que ça.

Le problème venait du fait que UINT_PTR n'est pas un pointeur comme son nom
pourrait le laisser supposer. C'est simplement un entier non signé comme
UINT qui représente un ID vers le périphérique audio.

J'ai donc retirer la référence '*' et ça fonctionne bien

PAr contre, j'ai quand même utilisé la boucle 'for' comme conseillé même si
je n'aime pas les boucles autre que 'while'.

Merci pour le coup de pouce, ça m'a permis de diriger mes recherches.

A bientôt

Gilbert.


PS : Je suis désolé de ne pas avoir réfléchit plus loin que le bout de mon
nez avant de poster. J'espère que ça pourra servir à d'autres que moi.


"Olivier Miakinen" a écrit dans le message de groupe de discussion :
4ccafce7$

Le 29/10/2010 18:22, je répondais à Gilbert Dejardin :

[...] je vais essayer de répondre tout de même.



À mon avis, le code suivant a quelques chances de fonctionner mieux que
le précédent, modulo mon absence de connaissance de ces fonctions, et
surtout de la conversion de TCHAR[] en String (¹).

Form1(void)
{
InitializeComponent();
//
//TODO: ajoutez ici le code du constructeur
//
UINT numberOfMidiIn = midiInGetNumDevs();
UINT numberOfMidiOut = midiOutGetNumDevs();
this->textBox1->Text = "" + numberOfMidiIn;
this->textBox2->Text = "" + numberOfMidiOut;
UINT i;

for (i = 0; i < numberOfMidiIn; i++)
{
MIDIINCAPS midiInCaps;
MMRESULT res;
res = midiInGetDevCaps(&i, &midiInCaps, sizeof(midiInCaps));
if (res == MMSYSERR_NOERROR) [
String str = (String) midiInCaps.szPname; (¹)
this->comboBox1->Items->Add(str);
}
}

for (i = 0; i < numberOfMidiOut; i++)
{
MIDIOUTCAPS midiOutCaps;
MMRESULT res;
res = midiOutGetDevCaps(&i, &midiOutCaps, sizeof(midiOutCaps));
if (res == MMSYSERR_NOERROR) [
String str = (String) midiOutCaps.szPname; (¹)
this->comboBox1->Items->Add(str);
}
}

}


(¹) Chercher dans <http://www.google.fr/search?q=TCHAR+String+msdn> ou
aller voir dans le groupe fr.comp.os.ms-windows.programmation !
Avatar
Olivier Miakinen
Bonjour,

Le 31/10/2010 13:15, Gilbert Dejardin a écrit :

Le problème venait du fait que UINT_PTR n'est pas un pointeur comme son nom
pourrait le laisser supposer. C'est simplement un entier non signé comme
UINT qui représente un ID vers le périphérique audio.



Quelle idée ! C'était donc vraiment un problème spécifiquement Windows,
sans rapport avec le C++. D'un autre côté, ça me rassure : je ne voyais
vraiment pas de raison de passer un pointeur vers un entier censé ne pas
être modifié par la fonction (sinon, la boucle a toutes les chances
d'échouer).

Par contre, j'ai quand même utilisé la boucle 'for' comme conseillé même si
je n'aime pas les boucles autre que 'while'.



Si vraiment tu veux utiliser un 'while' au lieu d'un 'for', c'est
toujours possible, puisque modulo les questions de portée des
variables :

for (machin; truc; bidule)
{
chose;
}

est grosso modo équivalent à :

machin;
for ( ; truc; )
{
chose;
bidule;
}

et donc à :

machin;
while (truc)
{
chose;
bidule;
}

Cela dit, je trouve la construction 'for' très lisible dans ce genre de
cas, et je trouve dommage de s'en priver. Au fait, le problème de ton
'while' n'était pas sur l'utilisation du 'while' en soi, mais sur le
fait de décrémenter de Max-1 à -1, avec un test sur le passage à une
valeur négative, ce qui interdit d'utiliser un entier non signé. En
incrémentant la variable de 0 à Max il n'y a plus de problème.

[...]

"Olivier Miakinen" a écrit dans le message de groupe de discussion :
4ccafce7$

[COPIE INTÉGRALE]



Merci d'apprendre à citer efficacement sur Usenet (technique qui est
d'ailleurs tout aussi valable par courriel) :
<http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html>.
Avatar
espie
In article <4cd04296$,
Olivier Miakinen <om+ wrote:
Bonjour,

Le 31/10/2010 13:15, Gilbert Dejardin a écrit :

Le problème venait du fait que UINT_PTR n'est pas un pointeur comme son nom
pourrait le laisser supposer. C'est simplement un entier non signé comme
UINT qui représente un ID vers le périphérique audio.



Quelle idée ! C'était donc vraiment un problème spécifiquement Windows,
sans rapport avec le C++. D'un autre côté, ça me rassure : je ne voyais
vraiment pas de raison de passer un pointeur vers un entier censé ne pas
être modifié par la fonction (sinon, la boucle a toutes les chances
d'échouer).



Ah ben si, il y a un rapport avec le C++, et meme avec le C.
Plus precisement, C99 introduit une ribambelle de types entiers d'un peu
toutes les tailles, histoire de codifier certaines pratiques pas tres portables
mais parfois utiles. Dans le lot, on trouve uintptr_t, qui correspond... a
un type entier non signe suffisamment grand pour y mettre un pointeur sans
rien perdre.

Pour ceux qui suivent, la norme de C++ actuellement en usage, c'est C++98.
Donc anterieure a C99.

Du coup, ou est-ce qu'on rajoute les extensions C99 ? c'est pas tres clair.


Et donc (et ca c'est le bout microsoft), il semblerait que certain editeur
ait choisi UINT_PTR pour... representer la meme chose. Je reconnais que
le decoupage en mot est tordu. Mais uintptr_t n'est pas si clair que ca,
il faut vraiment avoir lu la norme C99 pour savoir.

Comme quoi, ca sert de se tenir au courant, y compris des normes des
langages "voisins"...
Avatar
James Kanze
On Nov 2, 11:17 pm, (Marc Espie) wrote:
In article ,
Olivier Miakinen <om+ wrote:

Pour ceux qui suivent, la norme de C++ actuellement en usage,
c'est C++98. Donc anterieure a C99.



La version actuelle de la norme (officielle) est 2003, non 1998.
(Mais la version 2003 est un "bug-fix release" de la version
1998. Elle n'introduit rien de neuf, au moins en principe.)

Du coup, ou est-ce qu'on rajoute les extensions C99 ? c'est
pas tres clair.



La version C++0x les prend en compte. D'une part, dans la
description des types de base (il peut y en avoir plus --
« extended integer types »), et d'autre dans la spécification de
<cstdint> (ajouter dans une section à soi dans la section 18).

Et donc (et ca c'est le bout microsoft), il semblerait que
certain editeur ait choisi UINT_PTR pour... representer la
meme chose. Je reconnais que le decoupage en mot est tordu.
Mais uintptr_t n'est pas si clair que ca, il faut vraiment
avoir lu la norme C99 pour savoir.



En fait, si on suivait les conventions de nommage des autres
types entiers, ça serait uint_ptr_t. Et si ce n'est
effectivement pas très clair en isolation, pris dans l'ensemble
des autres (uint_fast32_t, uint_least16_t, etc.), ça se comprend
un peu.

--
James Kanze