Bug affichage sous mfc

Signaler
Messages postés
60
Date d'inscription
mardi 10 février 2004
Statut
Membre
Dernière intervention
17 septembre 2004
-
Messages postés
60
Date d'inscription
mardi 10 février 2004
Statut
Membre
Dernière intervention
17 septembre 2004
-
bonjour,

voila mon probleme, j'ai une fenetre de dialog construite avec mfc qui me permet de mettre a jour des champs cedit et progress bar (qui represente une position d'un robot).
Lors d'un mouvement, je suis dans une boucle while qui va relire la position du robot et qui mets a jour les objets ci dessus tant que le mouvement n'est pas fini.

Le probleme est qu'au bout d'un moment, mon affichage perd completement les pedales!!!!
c tout d'abord les chmps mis a jour qui bug puis tout le reste de la fenetre.

Voici le code de ma boucle while lors d'un mouvement:
while (gap>epsilon)
{
Sleep(500);
//verifie l'état du bouton
messagedertx=receptionmempart();
coursmouvement=messagedertx.CoursMouvement;

// Permet d'bandonner le mouvement a m'appui sur F8
if (coursmouvement==0)
{GetMessage(&msg, NULL, 0, 0);
if((msg.message)==WM_KEYDOWN && (msg.wParam)==VK_F8) { abandon=1;}
}

else {//envoi de la position courante a DKFZ
ComDKFZ->SendMobilities((float) (messagedertx.Positionmob2), (float) (messagedertx.Positionmob4), (float) (messageversrtx.Consigne));

switch (mob)
{case 2: position2=messagedertx.Positionmob2; arrondi(position2,0);
_gcvt(position2,8,cbuff);
m_Affvaleurmob2.SetSel(0,8);m_Affvaleurmob2.ReplaceSel(cbuff); //maj edit progress
m_Progressmob2.SetPos((int) ((-Min2+position2)/Pasmob2)); //maj barre progress
break;


case 3: position3=messagedertx.Positionmob3; arrondi(position3,1);
_gcvt(position3,8,cbuff);
m_Affvaleurmob3.SetSel(0,8);m_Affvaleurmob3.ReplaceSel(cbuff); //maj edit progress
m_Progressmob3.SetPos((int) ((-Min3+position3)/Pasmob3)); //maj barre progress
break;

case 4: position4=messagedertx.Positionmob4; arrondi(position4,1);
_gcvt(position4,8,cbuff);
m_Affvaleurmob4.SetSel(0,8);m_Affvaleurmob4.ReplaceSel(cbuff); //maj edit progress
m_Progressmob4.SetPos((int) ((-Min4+position4)/Pasmob4)); //maj barre progress
break;

case 5: position5=messagedertx.Positionmob5; arrondi(position5,1);
_gcvt(position5,8,cbuff);
m_Affvaleurmob5.SetSel(0,8);m_Affvaleurmob5.ReplaceSel(cbuff); //maj edit progress
m_Progressmob5.SetPos((int) ((-Min5+position5)/Pasmob5)); //maj barre progress
break;
}


//arrondi du gap et affichage du gap
gap=messagedertx.Gap;
arrondi(gap,1); if (mob==2) {arrondi(gap,0);}
_gcvt(gap,8,cgap); m_Affgap.SetSel(0,8);m_Affgap.ReplaceSel(cgap);

//calcul du pourcentage et affichage du pourcentage (valeur et barre)
pourcent=(int) (100-(100*gap/editconsigne)); //calcul du pourcentage
_gcvt(pourcent,3,cpourcent); //converti le pourcentage ne chaine de caractere
m_Affpourcent.SetSel(0,8); m_Affpourcent.ReplaceSel(cpourcent); //affiche le pourcentage
m_Barrepourcent.SetPos(pourcent); //positionne la barre progress de pourcentage

}

if (abandon==1) //detection d'abandon du mouvement (demande de confirmation et abandon si oui)
{if (IDYES==MessageBox("Voulez vous arrêter le mouvement programmé?","Attention",MB_ICONQUESTION | MB_YESNO+256)) //+256 permet de mettre NO par default
{coursmouvement=3; //permet de savoir que le mouvement a ete abandonne avant sa fin (voir goto fininterrupt)
goto fininterrupt;}
else abandon=0;
}

if (ArretMouvErreurdetect) {goto fininterrupt;ArretMouvErreurdetect=FALSE;} //detection d'une erreur, arret du mouvement

}

9 réponses

Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
=> ne fait pas une boucle while infinie avec un sleep dans une inteface graphique, utilise un thread séparé ou un timer (plus simple).

Dans le OnInitDialog (ou après appui sur un bouton, à toi de voir) tu crée un timer :
SetTimer(0x0100, 500, NULL)
0x100 : Id du timer (au cas ou tu voudrais en faire plusieur
500 : cadence d'appel.

Ensuite, il te suffit d'aller dans le classwizard et d'ajouter la fonction OnTimer associée au message WM_TIMER.

enfin dans la fonction OnTimer, tu met le code qui te sert à récupérer et mettre à jour tes données.
Messages postés
60
Date d'inscription
mardi 10 février 2004
Statut
Membre
Dernière intervention
17 septembre 2004

est tu sur que ca resoudra le probleme?
est ce que dans le timer j'aurais acces au variable membres de la classe (variables des fenetres edit, progress....)?

merci
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
OnTimer est une fonction virtuelle membre de la classe CWnd dont dérive CDialog. Tu aura donc accès à tous dans le dialoge. Au passe pour arrêter le Timer, c'est KillTimer(IdTimer).
Messages postés
60
Date d'inscription
mardi 10 février 2004
Statut
Membre
Dernière intervention
17 septembre 2004

ok deux derniere petites questions.

as tu remarque que dans ma boucle precedente, je regardais l'atat du bouton F8 pour savoir si le mouvement devait etre annule. J'ai repris la meme chosedans mon timer mais il me semble que le messagebox qui s'affiche peine a recevoir les ordre du clavier? puis je comme mettre cette fonction dans le timer?:
if (coursmouvement==0)
{GetMessage(&msg, NULL, 0, 0);
if((msg.message)==WM_KEYDOWN && (msg.wParam)==VK_F8) { abandon=1;}
}

Si je suis dans l'etat de l'attente d'une reponse de ma messagebox, que se passe t'il 500ms apres l'appel du timer? rien? ou alors le timer s'execute t'il de nouveau en arriere plan? dans ma boucle while il fallait que j'attende la reponse du messagebox pour continuer.

Voila si tu pouvais m'eclairer en reprenant simplement ces questions une a une....

encore merci, le timer fonctionne, je n'est pas vu de bug mais je n'ai pas teste.....
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
n'appelle pas GetMessage dans OnTimer, rajoute simplement une commande (dans un menu ou pas) associer à un raccourcis clavier. Ajoute un gestion de la commande et modifie une variable membre indiquant que F8 a été pressé.

Dans OnTimer (appelée régulièrement) il suffit de vérifier l'état de la variable. Ou bien Kill le Timer des la réception de la commande associée à F8.

n'appelle pas non plus MessageBox dans le OnTimer car c'est assez dangereux (appel en cascade possible).

pour résumer :
ajoute une commande (ca peur être dans un menu ou un bouton visible ou non). ASsocie un racourci clavier à cette commande.

Dans le Dialogue, ajoute une fonction traitant cette commande dans laquelle tu affiche le messageBox de confirmation (tu peut arrêter momentanément le timer avant l'affichage su tu le souhaite).
Messages postés
60
Date d'inscription
mardi 10 février 2004
Statut
Membre
Dernière intervention
17 septembre 2004

j'ai pas tout compris pour l'histoire de la messagebox, comment faire pour quelle ne soit pas appele continuellement?
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
la mettre dans la gestion de la commande d'arrêt et pas dans OnTimer. Si t'as un mail à fournir (en message perso si tu préferre), j'ai un exemple que je peut de filer.
Messages postés
60
Date d'inscription
mardi 10 février 2004
Statut
Membre
Dernière intervention
17 septembre 2004

ca a l'air d'aller j'ai fait la modif. par contre j'ai un bug au bout d'un moment. (une fentre s'ouvre avec un stop et abandonner, reessayer, ignorer). Je sais pas si ca viens du timer. Vu que je suis en pleine phase de test je sais pas si j'aurais le temps de regarder d'ici la semaine prochaine. mais peut tu garder un oeil sur ce topic, je te ferais signe. Merci pour tes conseils.
Messages postés
60
Date d'inscription
mardi 10 février 2004
Statut
Membre
Dernière intervention
17 septembre 2004

le bug de l'affichage est toujours present, malgres le timer, qui en passant est plus propre.
voila ce qui se passse, certain objet ne se redessine plus et lors de l'affichage de messagebox, je n'ai plus aucune couleur (tout est en grris assez gros, sans bordure.....)
je ne vois pas d'ou peut venir le probleme.
aurais tu une idee?