IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

Souci avec SendMessage()


Sujet :

MFC

  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2008
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 62
    Par défaut [Résolu] Souci avec SendMessage()
    Bonsoir,

    Je vous explique mon problème : J'ai un programme qui comporte 2 threads de comptage (incremente une progressBar). Jusque là tout va bien. Maintenant je dois gerer les threads en fonction des messages.

    Un compteur a son propre thread. a la fin du comptage le thread est détruit et recreer pour recommencé le comptage...

    diagramme de classe :
    ihm->Sablier (par composition)

    dans Sablier il y a une methode Execute() pour faire le thread dans ihm.
    dans la méthode Execute j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    UINT Sablier::Execute()
    {
    	value->SetRange(mini,maxi);
     
            do
    	{
    		value->SetPos(i);
    		Sleep(100);
    		i++;
     
    	}while(i!=maxi);
     
    	ihm->PostMessage(valmess,0,0);
     
    	return 0;
    }
    dans l'ihm pour gerer les messages :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    BEGIN_MESSAGE_MAP(CQuizzDlg, CDialog)
    	ON_WM_SYSCOMMAND()
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	//}}AFX_MSG_MAP
    	ON_BN_CLICKED(B_REPONSE, &CQuizzDlg::OnBnClickedReponse)
    	ON_MESSAGE(WM_USER,&CQuizzDlg::FinTempsQuestion)
    	ON_MESSAGE(WM_USER+1,&CQuizzDlg::FinTempsQuizz)
    END_MESSAGE_MAP()
    puis dans la méthode FinTempsQuestion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    LRESULT CQuizzDlg::FinTempsQuestion(WPARAM,LPARAM)
    {
    	if(p != Mc.GetTailPosition())
    		{
    			Mc.GetNext(p);
    			Afficher();
    		}
    	return 0;
    }
    L'image du programme pour mieux comprendre :


    1er probleme débile : Comment faire en sorte que la barre de progression arrive jusqu'au bout ? (pourtant j'ai bien défini les mini et maxi avec Setrange...

    2e probleme : a la fin de la 1ere barre de progression (celui du haut) il envoie un message a l'ihm pour que le thread du compteur reparte a zero et change de question. Or mon probleme, la barre s'arrete a la fin et ne redemarre pas sauf la 2e barre de progression (or sa devrait etre l'inverse)? Kesaco ?

    Merci a celui qui me remettra sur le bon chemin avec les Sendmessages...

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    Pour le dernier élément, en général, c'est parce qu'on ne laisse pas le temps à l'IHM de se rafraîchir avec le dernier tick.
    Pour ta deuxième question: n'aurais-tu pas inversé les deux éléments (question bête mais des fois... )?

    Sinon, je ne suis pas sur d'avoir tout compris. Tu as CQuizzDlg qui possède deux barres et Sablier est un CWinThread? Ou est le second thread dont tu parles? Peux-tu préciser la dynamique que tu veux mettre en oeuvre entre tes différents éléments?

  3. #3
    Membre confirmé
    Inscrit en
    Décembre 2008
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 62
    Par défaut
    je procède comme cela pour les threads :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Sablier1 = new Sablier(WM_USER,&C1,this);
    	Sablier2 = new Sablier(WM_USER+1,&C2,this);
     
    	//créée les 2 threads
    	T1 = AfxBeginThread(Install_thread,(LPVOID)Sablier1,0,0,CREATE_SUSPENDED,0); //crée le thread 1
    	T2 = AfxBeginThread(Install_thread,(LPVOID)Sablier2,0,0,CREATE_SUSPENDED,0); //crée le thread 2
    Egalement la classe Sablier hérite d'une classe abstraite Thread.

    Pour te répondre j'ai déja essayé d'inversé ça ne change rien...

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    1/Pour aller jusqu'au bout : ton while s'arrête à <maxi
    2/ Pour réinitialiser, faire un setpos(0)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    UINT Sablier::Execute()
    {
    	value->SetRange(mini,maxi);
    	value->SetPos(0);
            int i=0;
            do
    	{
    		value->SetPos(i);
    		Sleep(100);
    		i++;
     
    	}while(i<=maxi);
     
    	ihm->PostMessage(valmess,0,0);
    	
    	return 0;
    }
    Par contre, je reste assez sceptique d'utiliser les méthodes de CProgressCtrl dans un autre thread. Je ne suis pas sur qu'elles soient thread-safe.

  5. #5
    Membre confirmé
    Inscrit en
    Décembre 2008
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 62
    Par défaut
    deja j'ai reussi a corrigé le 1er probleme avec ton setpos(0);

    Par contre thread-safe : j'ai pas compris?

    On peut tres bien gerer 2 thread avec 2 adresses differentes de CProgressCTrl

    grace au passage d'adresse de l'objet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Sablier::Sablier(UINT mess,CProgressCtrl* valueEdit,CDialog *IHM)
    {
         value = valueEdit; // met l'adresse du CProgressCtrl concernée dans la variable value pour le thread
         ihm = IHM;
         valmess = mess;
     
    }
    Si tu vois toujours pas dit le moi.

    Sinon mon 2e probleme persiste encore...

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Cyr69 Voir le message
    deja j'ai reussi a corrigé le 1er probleme avec ton setpos(0);
    Euh, ce devait plutôt corrigé le second ! Le premier est corrigé par la modification du test en while. Enfin, c'est ce que je pensais faire...

    Citation Envoyé par Cyr69 Voir le message
    Par contre thread-safe : j'ai pas compris?
    Tu créés ton contrôle dans ton thread principal. Tu utilises un CProgressCtrl*créé dans le thread principal dans ton thread secondaire. Ca je suis pas sûr que ce soit très catholique... Perso, quand je fais ce genre de chose, le thread secondaire envoie une notification au thread principal et à charge de celui-ci de mettre à jour l'IHM. Bref: un seul thread intervient sur l'IHM (le thread principal, qui hérite de CWinApp et qui l'a créé).

    Citation Envoyé par Cyr69 Voir le message
    On peut tres bien gerer 2 thread avec 2 adresses differentes de CProgressCTrl
    Oui, comme j'ai essayé de le dire ci-dessus, le pb c'est plus entre les threads secondaires et le thread principal.

    Citation Envoyé par Cyr69 Voir le message
    Sinon mon 2e probleme persiste encore...
    Faudrait que tu montres CQuizzDlg::FinTempsQuestion et CQuizzDlg::FinTempsQuizz. Sablier::Execute() est tel que tu l'as recopié ou il y a autre chose?

  7. #7
    Membre confirmé
    Inscrit en
    Décembre 2008
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 62
    Par défaut
    je vous ajoutes les 3 méthodes :

    FinTempsQuestion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    LRESULT CQuizzDlg::FinTempsQuestion(WPARAM,LPARAM)
    {
    	if(p != Mc.GetTailPosition())
    		{
    			Mc.GetNext(p);
                            //Recreer un thread et le relancer
    			T1->ResumeThread();
     
    	}
    	return 0;
    }
    FinTempsQuizz :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    LRESULT CQuizzDlg::FinTempsQuizz(WPARAM,LPARAM)
    {
    	//A completer une fois les threads bien gérés
    MessageBox(_T("Le temps du jeu s'est écoulé ! Vous avez un score de .../10 !"),_T("Fin du jeu"));
     
    	return 0;
    }
    Execute :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    UINT Sablier::Execute()
    {
    	value->SetRange(mini,maxi);
    	value->SetPos(0);
     
    	do
    	{
    		value->SetPos(i);
    		Sleep(100);
    		i++;
    	}while(i<=maxi);
     
    	ihm->PostMessage(valmess,0,0);
     
    	return 0;
    }
    Le probleme c'est que quand le compteur arrive a la fin il est bien détruit et il faut le recreer donc dans la méthode FinTempsQuestion faut que je rajoute ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Sablier1 = new Sablier(WM_USER,&C1,this);
     
    T1 = AfxBeginThread(Install_thread,(LPVOID)Sablier1,0,0,CREATE_SUSPENDED,0);
     
    T1->ResumeThread();
    Mais bon ça merde, le souci c'est que en lançant mon programme il passe quand meme dans la méthode FinTempsQuestion alors que le message n'est pas envoyé depuis la méthode execute ! Normalement il ne devrait pas. Il débloque mon MFC

    Si tu vois où ça peut venir sinon je te passerai le code en mp

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    En préambule, tu m'as dis que Sablier dérive de CWinThread? Si c'est le cas, ce n'est pas la bonne surcharge de AfxBeginThread.
    Sinon, ResumeThread ne relance pas le thread si celui-ci était terminé mais le réveille. Pour un thread terminé, il ne se passe rien. A condition que T1->ResumeThread corresponde bien à CWinThread::ResumeThread? En fait, il te faut recréer le thread (AfxBeginThread()). Je ne sais pas si tu peux utiliser la même instance.

  9. #9
    Membre chevronné Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Par défaut
    salut,

    pourquoi utiliser un thread, juste pour faire avancer une progress bar ?!
    un timer serait beaucoup plus efficace pour ce genre de situation, et plus facile à mettre en place ...

    @+

  10. #10
    Membre confirmé
    Inscrit en
    Décembre 2008
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 62
    Par défaut
    Parce que c'est le prof qui veut qu'on fasse avec les threads pas moi je sais que pour moi c'est pas utile mais bon je dois respecter sa consigne.

    Sablier ne dérive pas de Cwinthread mais de ma classe abstraite Thread que j'ai créé et dedans il y a qu'une méthode virtual pure Execute().

    pour répondre à 3DArchi, je vais essayer de récréé le thread une fois le compteur de question fini. Je te tiendrais au courant.

    Sinon j'ai toujours un probleme : rien qu'a la compilation, il recoit le message de Sendmessage de la méthode Execute() OR il DEVRAIT pas passer dans ! Seulement à la fin du comptage... Kesaco ?

Discussions similaires

  1. quelques soucis avec word 2000
    Par ramchou dans le forum Word
    Réponses: 3
    Dernier message: 06/09/2004, 18h13
  2. SOucis avec une reequete imbriquee
    Par Ni4k dans le forum Langage SQL
    Réponses: 6
    Dernier message: 30/03/2004, 08h56
  3. souci avec un algorithme
    Par slider16 dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 22/03/2004, 17h17
  4. [DEBUTANT] petits soucis avec un prgm de chat
    Par LechucK dans le forum MFC
    Réponses: 8
    Dernier message: 19/01/2004, 16h52
  5. Réponses: 4
    Dernier message: 16/02/2003, 12h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo