Comment arréter une boucle dans une autre fonction...(+clair ci-dessou - C++ - Programmation
Marsh Posté le 29-04-2003 à 00:12:05
Tu ne peux pas arreter une boucle while comme ca (a moins de faire une espece de gestion d'interuption). Pendant l'execution de la boucle while le programme sera insensible à ton evenement bouton et ta variable ne seras pas modifiée.
A mon avis pour que ca marche, il faut lancer deux threads separés, un pour l'aquisition et l'autre pour catcher l'evemement associé au bouton.
Marsh Posté le 29-04-2003 à 00:18:51
pendant que tu est dans ta boucle while, ton programme est uniquement dans ta boucle while et ne peut pas gérer le click sur le bouton.
La solution propre consiste a utiliser des threads, mais on peut bidouiller un truc.
Il faut dire au programme que tu veux prendre en compte les messages (click, mouvement de la souris ...) pendant que tu est dans ta boucle while, il faut demander à ton appli de traiter les messages qui lui arrivent.
y a un début de solution ici :
http://msdn.microsoft.com/library/ [...] essing.asp
Marsh Posté le 29-04-2003 à 00:20:44
fykman a écrit : Tu ne peux pas arreter une boucle while comme ca (a moins de faire une espece de gestion d'interuption). Pendant l'execution de la boucle while le programme sera insensible à ton evenement bouton et ta variable ne seras pas modifiée. |
Et comment je peux faire ce petit miracle ;-) ???
Parce que moi et le MFC, on est pas copain depuis très longtemps;
à vrai dire j'ai beaucoup de mal à m'en servir, vu que mon seul prof, c'est moi!!! ...
Marsh Posté le 29-04-2003 à 00:22:34
SquiZz a écrit : pendant que tu est dans ta boucle while, ton programme est uniquement dans ta boucle while et ne peut pas gérer le click sur le bouton. |
ok; je vais voir ça!
Marsh Posté le 29-04-2003 à 00:25:59
j'ai codé un petit exemple rapide,
tu crées une appli MFC dialog
tu ajoutes deux boutons et tu mets ca comme code pour le click sur les boutons :
Code :
|
m_loop c'est une variable membre bool de la classe de ton dialog .
et 'oila cappucino
[edit] c'est pas très propre mais ca marche.
Marsh Posté le 29-04-2003 à 00:29:57
SquiZz a écrit : j'ai codé un petit exemple rapide,
|
Danke schön!!!
(de toute façon la propreté c'est pas mon fort!!!! :-) )
Marsh Posté le 29-04-2003 à 00:31:14
SquiZz a écrit : |
C'est bien ce que je disait, il faut deux threads ....
Marsh Posté le 29-04-2003 à 00:32:21
ReplyMarsh Posté le 29-04-2003 à 15:38:22
Bon en fait j'ai un gros probleme, lorsque je lance mon prog,
la fonction que j'ai cité ci-dessus, merde à mort :
soit elle se lance et la plus moyen de rien faire,
soit elle ne se lance pas et rien ne se passe!!
donc la je vais mettre un peu de code pour que ce soit plus clair (
//ma fonction //
int
SegmentorCallback( PSEGMENTOR_DATA pData)
{
assert( pData != (PSEGMENTOR_DATA)NULL );
/* Write segmentor scene data to an 8-bit pgm file */
COLOUR_IMAGE *pClrImage = &pData->scene_colour_image; //on pointe sur l'adresse des données de l'image
static int image_no = 0;
m_bLoop=true;
//on fait l'acquisition de 100 images, possibilité de le régler aussi (bouton stop)
MSG msg;
while(m_bLoop)
{
Sleep(10);
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
char filename[50],filename1[50],filename2[50],filename3[50],filename4[50],filename5[50];
unsigned int image[120][160];
*/etc etc /*
fclose(pf2);
}
AfxMessageBox("fin de la boucle" ); //pour le repérage
return 1;
}
mon bouton demarrer
void CAcquisitionV1Dlg::OnButtonDemar()
{
// TODO: Add your control notification handler code here
CENSYS_INSTANCE cinstance;
CENSYS_ERROR err;
*/code ......../*
L'appel de ma fonction
err = censysSystemSetSegmentorCallback( cinstance, SegmentorCallback );
*/code......./*
censysSystemSetSegmentorCallback se trouve dans un fichier censys.h que j'ai inclu dans mon projet
declaration de censysSystemSetSegmentorCallback [#00f00e]
CENSYS_API CENSYS_ERROR
censysSystemSetSegmentorCallback(
CENSYS_INSTANCE ciInstance,
CENSYS_SEGMENTOR_CALLBACK cscCallbackFunction
);
avec [#f00e00]typedef void* CENSYS_INSTANCE;
typedef int CENSYS_SEGMENTOR_CALLBACK( PSEGMENTOR_DATA pData );
Si vous comprenez quelque chose, HELP!!!
Marsh Posté le 29-04-2003 à 22:55:39
Desolé pour les couleurs, je pensais pas que ça serait aussi laid!!!
Sinon un petit up!
brouillard, mon joli brouillard, où suis je???
->int *projet de merde
Marsh Posté le 29-04-2003 à 22:56:06
Desolé pour les couleurs, je pensais pas que ça serait aussi laid!!!
Sinon un petit up!
brouillard, mon joli brouillard, où suis je???
->int *projet de merde
Marsh Posté le 30-04-2003 à 02:40:20
SquiZz a écrit : |
ouais, c'est degueulasse et ca marche pas.
Bravo pour le code fouettant, mettre un TranslateMessage() dans un handler, faut le faire... Apres l'autre il s'etonne ke ca marche mal...
Effectivement pour faire un minimum propre il faut un thread supplémentaire (un seul, pas 2 ou 3).
Si j'ai tout compris ce ke tu voulais, une solution est :
- dans le handler du bouton demarrer, tu crée un thread ki éxécutera ton code.
- dans le handler du bouton arreter, tu signale au thread qu'il faiut qu'il évite.
ah bah voila, c tout en fait.
apres, je te repondrais bien "fais man CreateThread", mais chuis dans une bonne heure, donc voila un bout de code rapide :
Code :
|
voila.
j'ai rien testé, et j'espere meme ke ca marche pas, histoire ke ca te fasse penser un minimum.
pour le handler du bouton arreter, t'as le choix entre 2 méthodes : la 1ere si tu veux gerer tout bien au risque ke ca continue du code pendant un peu de temps (le temps ke ca arrive au while), ou bien "fo ke ca s'arrete maintenant, tant pis pour ma ram".
si t'utilises des classes, t'auras le droit d'éviter les globales.
.
Marsh Posté le 30-04-2003 à 02:49:13
et il est ou le WaitForSingleObject(), hein???
au lieu de faire un while() avec un booleen global, on fait un
Code :
|
Tu me decois Konar... C un peu faible tout ca.
Marsh Posté le 30-04-2003 à 03:03:59
konar_spreme a écrit : et il est ou le WaitForSingleObject(), hein???
|
ouais mais la ca va te repondre : c koi hEvent ? c koi WaitForSingleObject ? c koi le C++ ? c koi blabla ?
Marsh Posté le 30-04-2003 à 03:10:21
Konar a écrit : |
Oui ms la je peux pas aider, c sur...
Je fais deja de l aide handicapé toute la journée, vais pas en faire le soir en plus.
Tiens ca t'apprendra.
Marsh Posté le 30-04-2003 à 08:00:58
Konar a écrit : |
ouep, mais j'ai trouvé ca dans le msdn :
http://msdn.microsoft.com/library/ [...] essing.asp
citation :
"PeekMessage Elsewhere in Your Application
Another method for performing idle processing in an application involves embedding a message loop in one of your functions"
ensuite on voit un exemple qui utilise pumpmessage.
autre citation :
"Although PumpMessage is undocumented, you can examine its source code in the ThrdCore.Cpp file in MFC\Src relative to your Visual C++ installation."
et si on va voir le code de pumpmessage, ca fait un pretranslate et un dispatchmessage.
Donc ma solution :
1 - est pas très propre
2 - marche pas trop mal
3 - est décrite dans le MSDN
Marsh Posté le 30-04-2003 à 17:26:49
Konar a écrit :
|
Oki, je vais zieuter ça, merci!
Marsh Posté le 01-05-2003 à 20:34:29
Konar a écrit :
|
Bon en fait, je n'arrive pas à me servir de ce que tu as dit;
J'ai donc fait une recherche sur WaitForSingleObject,
j'ai trouvé ça : www.codeppc.com/evc/articles/multithread/mt1.htm
LE problème est que quand mettre un thread sur ma fonction, je ne peux plus passer en parametre les parmatres de ma fonction
ma fonction :
int SegmentorCallBack(PSEGMENTOR_DATA pData)
{
while (WaitForSingleObject //je sais que ca n'a pas de sens la mais c'est pour le reperage
{code}
code
}
J'ai testé ça :
declaration
DWORD WINAPI SegmentorCallBack(LPVOID p,PSEGMENTOR_DATA pData)
ensuite ma fonction
DWORD WINAPI SegmentorCallBack(LPVOID p,PSEGMENTOR_DATA pData)
{
code...
while (WaitForSingleObject //je sais que ca n'a pas de sens la mais c'est pour le reperage
{code}
code
}
mais bon, ça passe pas trop,
Alors comment je peux passer en paramètre PSEGMENTOR_DATA pData????
Marsh Posté le 01-05-2003 à 20:43:01
Le lpParameter te permet de faire passer tous les parametres dont tu as besoin.
Exemple :
Code :
|
sinon oublie le WaitForSingleObject pour le moment...
Marsh Posté le 01-05-2003 à 20:50:59
Konar a écrit : Le lpParameter te permet de faire passer tous les parametres dont tu as besoin.
|
Alala , konar toujours à ma rescousse!!
merci!
I go to test that!!!
Marsh Posté le 02-05-2003 à 16:18:03
sbbtn a écrit : |
Bon ça ne marche pas non plus, le gros probleme est que je n'arrive pas à changer la declaration de ma fonction;
la en gros , tu me dit que je dois declarer ma fonction en tant que DWORD WINAPI SegmentorCalllBack(LPVOID lpParameter)
ok je veux bien,
je l'ai fait, j'ai fait aussi une structure (t_Truc....) avec mes variables;
mais lorsque je veux lancer ma new fonction
err=CensysSystemSetSegmentorCallback(cinstance /*on s'en fout*/ , SegmentorCalllBack);
J'ai une erreur de type:
error C2664: 'censysSystemSetSegmentorCallback' : impossible de convertir le paramètre 2 de 'DWORD (LPVOID)' en 'CENSYS_SEGMENTOR_CALLBACK (__cdecl *)'
J'ai essayé de modifier les types de chaque parametre mais ça n'a pas marcher.
Marsh Posté le 28-04-2003 à 23:05:08
Bon voila, j'ai un prog avec le MFC
J'ai declaré un bouton "demarrer", il fait parti de la classe acquisit
En fait en cliquant sur ce bouton, je lance une fonction à l'interieur de laquelle s'execute une boucle while avec pour parametre (par ex) :
while(m_intMavariable!=1)
{code}
dans la meme classe j'ai mis un bouton "arretter",
lorsqu'on clique dessus :
void acquisit::OnButtonArreter
{m_intMavariable=1;}
je voudrais arreter le while de tout à l'heure, mais ça ne marche pas;
j'ai declaré m_intMavariable en variable globale, ma fonction de tout à l'heure retourne un entier et est déclaré en globale aussi;
mais ça ne marche pas, vous avez une idée???