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 :

Thread--> problème avec ThreadProc


Sujet :

MFC

  1. #21
    Membre éprouvé
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Par défaut
    Si j'ai bien compris, le problème c'est que tu ne sors pas de ton thread.

    Tu as vérifié quelle valeur avait dwWait dans ton thread quand WaitForSingleObject retourne ?

  2. #22
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Je ne sais plus quel chiffre, mais c'était donc ni WAIT_OBJECT_0 ni WAIT_TIMEOUT.


    En fait le mieux après avoir tout fait, c'est revenir à cette forme où le seul problème concerne l'utilisation d'une fonction non-statique, d'où ce que m'a dit Farscape d'utiliser les messages privés [j'ai pas du tout compris comment au bout d'une journée entière} ( donc c'est génial de n'avoir qu'un problème)

    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
    19
    20
    21
    void CMySequence::PlaySequence(int m_iFrom, int m_iTo, int m_iSpeedPlay, BOOL m_bBoucle)
    {
    	m_iSeqFrom=m_iFrom;
    	m_iSeqTo=m_iTo;
    	m_iSpeedPlay=m_iSpeedPlay;
    	m_bSeqBoucle=m_bBoucle;
     
    	// Creation des  events
    	m_EndThread = CreateEvent(0, TRUE, FALSE, 0);
    	m_WaitThread = CreateEvent(0, TRUE, FALSE, 0);
     
    	// depart du thread
         m_pThread = AfxBeginThread(ThreadFunction, this);
        if(!m_pThread)
        {
           AfxMessageBox("Impossible de créer le thread");
           return ;
        }
        return ;   
     
    }

    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
    19
    20
    21
    22
    23
    24
    // Fonction appellée par le thread //
    UINT CMySequence::ThreadFunction(LPVOID pvParam)
    {  
    	CMySequence *pThis = (CMySequence*)(pvParam);
    	int i=0;
     
      while(true)
      {
        // attente evenement de fin du thread. -> l’objet doit être ‘signalé ‘
       // WaitForSingleObject  renvoie WAIT_OBJECT_0 si l’objet est signalé.
        if(::WaitForSingleObject(pThis->m_EndThread, 0) == WAIT_OBJECT_0)
     
        {
          // signale l'objet event d'attente et sort.
          ::SetEvent(pThis->m_WaitThread);
          return 0;
        }
     
    	Play(); //Ma fonction Play
     
      }
     
    	return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void CMySequence::Stop(void)
    {
      // declenche la fin du thread
      ::SetEvent(m_EndThread);
     
      // attend que le thread soit terminé
      ::WaitForSingleObject(m_WaitThread, INFINITE);
     
      // fermeture dans handles
      ::CloseHandle(m_EndThread);
      ::CloseHandle(m_WaitThread);
    }


    Dans cette configuration, on peut bien arrêter une fonction à l'endroit où j'ai écrit Play (j'ai testé avec une boucle infinie) mais le seul problème comme je disais plus haut, c'est que je ne peux pas utiliser ma fonction Play qui va vouloir récupérer les m_iSeqFrom, m_iSeqTo, m_iSpeedPlay, et m_bSeqBoucle. à cause de ces termes non-statiques et GUI je-sais-pas-trop-quoi

  3. #23
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Allez, un dernier UP désespéré pour ce sujet, sans trop d'espoir maintenant...

  4. #24
    Membre éprouvé
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Par défaut
    La fonction Play est statique ?
    Sinon tu peux appeler une fonction de CMySequence, et rien ne t'empêche d'accéder aux données memebres de CMySequence dans le thread, je ne vois pas trop quel est ton problème.

  5. #25
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Citation Envoyé par Brouzouf
    La fonction Play est statique ?
    Sinon tu peux appeler une fonction de CMySequence, et rien ne t'empêche d'accéder aux données memebres de CMySequence dans le thread, je ne vois pas trop quel est ton problème.
    Non, la fonction Play n'est pas statique, voilà tout le problème de ThreadFunction qui n'accepte à l'intérieur que des membres statiques (ce que ne sont pas mes variables m_iSeqFrom, m_iSeqTo, etc.)
    Ecrire Play() et se servir de variables non-statiques à l'intérieur ne résoud [évidemment] rien de ce côté-là.

    Et l'autre problème, c''est que je ne peux pas non plus appeler des fonctions GUI, c'est-à-dire qui s'adressent à ma fenêtre (cf la syntaxe de ma fonction Play désirée en page1).

    Voilà, voilà... (mais les Timer peuvent tout simplement fonctionner, mais c'est du travail de sagouin, et c'est dommage que je n'ai rien appris sur les threads).

  6. #26
    Membre éprouvé
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Par défaut
    Et si au lieu de faire Play() tu fais pThis->Play() ?
    Dans la fonction Play() tu pourras alors utiliser les variables mamabres de ta classe.

  7. #27
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Oui, là c'est pas faux, je vois vaguement pourquoi, mais ça ne résoud pas l'autre problème dont paralit Farscape à propos de l'interdiction d'utiliser des GUI puisque ça plante ici:

    CMyProjectView *pView=(CMyProjectView *) ((CMainFrame *)AfxGetMainWnd())->GetActiveFrame()->GetActiveView();
    Violation d'emplacement et tout...

    Encore une fois, c'est lié à la staticité de ThreadFunction, et j'ai pas l'impression que dans cette configuration on puisse communiquer avec la View.

  8. #28
    Membre éprouvé
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Par défaut
    Pour communiquer avec une fenêtre dans un thread, tu dois obligatoirement passer par des messages.

  9. #29
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Et oui, ces fameux messages privés que j'ai pas compris ;-)

    Je ne vois concrètement pas comment écrire ma fonction Play à l'aide de ces messages privés.

    Mais bon, laisse tomber, on va pas y passer la semaine non plus.

  10. #30
    Membre éprouvé
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Par défaut
    Tout dépend de ce que doit faire ta fonction play, les messages privés ne osn pas une notion très compliquée, bien moins que les threads, et c'est une notion indispensable quand tu développe sous windows.

  11. #31
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    salut,
    je reprends au vol ,
    Dans cette configuration, on peut bien arrêter une fonction à l'endroit où j'ai écrit Play (j'ai testé avec une boucle infinie) mais le seul problème comme je disais plus haut, c'est que je ne peux pas utiliser ma fonction Play qui va vouloir récupérer les m_iSeqFrom, m_iSeqTo, m_iSpeedPlay, et m_bSeqBoucle. à cause de ces termes non-statiques et GUI je-sais-pas-trop-quoi
    Un détail tu ne peux pas faire de gui avec le pointeur de la view que tu as passé dans le thread, ok je pense que tu l'a bien compris maintenant.
    Mais tu peux utiliser les données membres (pas de contrôles graphiques) de ta classe dans ton thread:m_iSeqFrom etc .. , avec le pointeur sur la vue.
    Donc la plus de pb .
    Rappel : un fonction statique a une classe existe dans toutes les instances de la classe, donc on ne peut effectivement pas travailler avec des données liées à une instance, sauf si on dispose du pointeur sur l’objet.
    Ce qui est le cas ici dans la fonction statique du thread...

    Voila j'espère que j'ai ete clair

  12. #32
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    J'ai compris un peu mieux tout ça, j'ai effectivement pu utiliser les variables m_iSeqFrom, m_iSeqTo...de ma classe CMySequence.

    Voilà où j'en suis :

    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
    19
    20
    21
    22
    23
    24
    // Fonction appellée par le thread //
    UINT CMySequence::ThreadFunction(LPVOID pvParam)
    { 
       CMySequence *pThis = (CMySequence*)(pvParam);
       int i=0;
     
      while(true)
      {
        // attente evenement de fin du thread. -> l’objet doit être ‘signalé ‘
       // WaitForSingleObject  renvoie WAIT_OBJECT_0 si l’objet est signalé.
        if(::WaitForSingleObject(pThis->m_EndThread, 0) == WAIT_OBJECT_0)
     
        {
          // signale l'objet event d'attente et sort.
          ::SetEvent(pThis->m_WaitThread);
          return 0;
        }
     
       Play(); //Ma fonction Play
     
      }
     
       return 0;
    }


    Et là, ce qu'on ne peut pas faire :

    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
    19
    20
    void CMySequence::Play(void)
    {	
    	CMyImage* pCMyIm;
    	CMyProjectView *pView=(CMyProjectView *) ((CMainFrame *)AfxGetMainWnd())->GetActiveFrame()->GetActiveView();
     
    	do
    	{
    		for(m_iCur=m_iSeqFrom-1; m_iCur<m_iSeqTo; m_iCur++) 
    		{
    		BYTE *pimg=(BYTE *)pView->imgOriginal.GetBits();
    		pCMyIm = GetAtImage(m_iCur);
    		memcpy(pimg  -  pCMyIm->Width() * (pCMyIm->Height() - 1 ) * pCMyIm->BytesPerPix(), pCMyIm->GetImage(), pCMyIm->Width() * pCMyIm->Height() * pCMyIm->BytesPerPix());
    		pView->Invalidate();
    		pView->UpdateWindow();
    		Sleep((DWORD)(1000/m_iSeqSpeedPlay )); 		
    		}
     
    	}while(m_bSeqBoucle);
     
    }

    Voilà; alors c'est là qu'il faut faire intervenir les messages privés je ne sais pas comment pour écrire ailleurs ce que doit faire la fonction Play
    http://www.developpez.net/forums/vie...567222#1567222

    Seulement je ne comprend pas du tout ce qui est fait dans la FAQ

    void CSdisamplesView::OnButtonUp(NMHDR* pNMHDR, LRESULT* pResult)
    {
    PostMessage(WM_TEST);
    }


    C'est quoi OnButtonUp (quel bouton), c'est quoi NMHDR* et tout ça.
    Je rappelle que moi, ce sont les boutons "PLAY" et "STOP" d'une boîte CPlayDlg qui entrent en jeu (et dans cette classe, on appelle des fonctions de CMySequence)

    Appel à partir d'un Thread de travail initié par la classe Fenêtre :
    Code:

    void CSdisamplesView::OnButton1()
    {
    // TODO: Add your control notification handler code here
    // le handle de fenetre est passé en arguement par GetSafeWnd().
    AfxBeginThread(TheThread,GetSafeHwnd(),THREAD_PRIORITY_NORMAL) ;
    }

    Pareil, c'est quoi OnButton1, et puis The Thread doit être dans la View aussi...etc je sais plus trop quoi dire parce que j'ai tellement rien compris que je ne sais plus où ça foirait quand j'essayais de faire un truc du genre.


  13. #33
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    aaah aiaia ,
    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
    19
    20
    21
    22
    23
     
    void CMySequence::Play(CMyProjectView *pView)
    {   
       CMyImage* pCMyIm;
     
       do
       {
          for(pView->m_iCur=pView->m_iSeqFrom-1; pView->m_iCur<pView->m_iSeqTo;pView-> m_iCur++)
          {
            ::SendMessage(pView->mhWnd,WM_WORK);
    /* tout ça comme dis dans un de mes post precedents dans la fonction de reponse au message ici le message WM_WORK.
          BYTE *pimg=(BYTE *)pView->imgOriginal.GetBits();
          pCMyIm = GetAtImage(m_iCur);
          memcpy(pimg  -  pCMyIm->Width() * (pCMyIm->Height() - 1 ) * pCMyIm->BytesPerPix(), pCMyIm->GetImage(), pCMyIm->Width() * pCMyIm->Height() * pCMyIm->BytesPerPix());
          pView->Invalidate();
          pView->UpdateWindow();
    */
          Sleep((DWORD)(1000/m_pView->m_iSeqSpeedPlay ));       
          }
     
       }while(m_pView->m_bSeqBoucle);
     
    }
    voila play, pitie tu lui passe en argument le pointeur sur la view recu dans ta fonction thread.

  14. #34
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Je met résolu parce que j'ai l'impression que cette réponse est assez claire.; je vais voir ça.

    De toutes façons, si ça marche pas, c'est que je suis irrécupérable.

    MERCI à tous pour votre participation!

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Problèmes avec les thread et les pointeurs
    Par raspac dans le forum POSIX
    Réponses: 2
    Dernier message: 22/10/2006, 17h35
  2. [BOOST] Problème avec les threads
    Par SOAD08 dans le forum Dev-C++
    Réponses: 7
    Dernier message: 08/10/2006, 10h23
  3. Réponses: 1
    Dernier message: 08/08/2006, 15h39
  4. Réponses: 11
    Dernier message: 14/02/2006, 00h26
  5. Réponses: 5
    Dernier message: 10/05/2005, 10h22

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