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. #1
    Membre habitué
    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
    Points : 159
    Points
    159
    Par défaut Thread--> problème avec ThreadProc
    Bonjour,

    Voilà, je me renseigne depuis 9h30 ce matin sur les threads (l'idée est d'arrêter la boucle for de ma fonction "PLAYSEQUENCE" quand on appuie sur "STOP" et apparemment, c'est le seul moyen).

    Voilà la fonction Playsequence
    dans CMySequence (elle est appelée d'une autre classe liée à ma boîte de dialogue).

    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::PlaySequence(int m_iFrom, int m_iTo, int m_iSpeedPlay, BOOL m_bBoucle)
    {
     
    	m_iSeqFrom = m_iFrom ;
    	m_iSeqTo = m_iTo;
    	m_iSeqSpeedPlay = m_iSpeedPlay;
    	m_bSeqBoucle = m_bBoucle;
     
    	// Le thread ne doit pas être actif
    	assert(!s_hThread);
    	assert(!s_hEvent);
     
    	// Création de l'event
    	s_hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
     
    	// Création du thread
    	DWORD threadId;
    	s_hThread=CreateThread(NULL, 0, ThreadProc, NULL, 0, &threadId);
     
    }

    Voilà la procédure de thread :
    Ca m'a bien ennuyé cette histoire de statique : je voulais directement entrer mon code qui joue la séquence mais comme on ne peut pas rajouter de paramètres à cette fonction, il faut rechercher les m-iFrom, m_iTo, etc; c'est pour ça que j'ai créé les variables m_iSeqFrom, m_iSeqTo qui seront elles accessibles dans ma procédure de thread.
    Oui, mais voilà, une fois dans ThreadProc il a pas voulu de mes variables non statiques!!!!
    D'où le truc tordu (reinterpret_cast<CMySequence*>(lpParam))->Play(); où dans cette fonction Play je pourrai ENFIN écrire ma fonction tranquille (on verra que non, d'om le post ;-) )


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Fonction appellée par le thread //
    DWORD CMySequence::ThreadProc(LPVOID lpParam)
    {
    	// On boucle tant que l'événement n'est pas signalé
    	while(WaitForSingleObject(s_hEvent, 0)!=WAIT_OBJECT_0)
    	(reinterpret_cast<CMySequence*>(lpParam))->Play();
     
    	return 0;
    }

    QUESTION1 : je crois comprendre pourquoi la ligne pour obtenir le pView plante (c'est parce que ThreadProc est statique et donc violation d'accès quand on cherche un pointeur lié au document actif) mais je n'ai pas la solution.

    QUESTION2 (pendant que j'y suis) : Avec Invalidate() et UpdateWindow(), je vois bien mes images, mais pas de façon fluide (elles mettent trop de temps à s'afficher avant d'être remplacées par la suivante). J'ai essayé de laisser soit l'un, soit l'autre mais on ne voit rien du coup. Quoi 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
    21
    22
    23
    void CMySequence::Play(void)
    {
    	CMyProjectView *pView=(CMyProjectView *) ((CMainFrame *)AfxGetMainWnd())->GetActiveFrame()->GetActiveView();  //argh, il veut pas !!!!!!
    	CMyImage* pCMyIm;
     
    	BOOL bContinue=1;
    	while (bContinue)
    	{
    		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();   //pas terrible comme effet
    		pView->UpdateWindow(); //mais l'un ou l'autre seulement ne suffit pas
     
    		Sleep((DWORD)(1000/m_iSeqSpeedPlay)); 
     
    		}
    		bContinue=m_bSeqBoucle;
    	}
    }

  2. #2
    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
    Points : 17 323
    Points
    17 323
    Par défaut
    salut,
    tu ne peux pas faire ce que tu as ecrit dans ton thread :
    pas de gui dans un thread, regarde l'explication dans la faq :
    http://c.developpez.com/faq/vc/?page...d#WorkerThread

    au cas ou tu te poserais la question sur les messages prives:
    http://c.developpez.com/faq/vc/?page...d#WorkerThread


  3. #3
    Membre habitué
    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
    Points : 159
    Points
    159
    Par défaut
    Bon, j'ai tout changé en faisant comme le modèle que tu proposes.

    Ca donne ça :

    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
    void CMySequence::PlaySequence(int m_iFrom, int m_iTo, int m_iSpeedPlay, BOOL m_bBoucle)
    {
    	m_iSeqFrom = m_iFrom ;
    	m_iSeqTo = m_iTo;
    	m_iSeqSpeedPlay = m_iSpeedPlay;
    	m_bSeqBoucle = m_bBoucle;
     
    	// Création des events
    	m_EndThread=::CreateEvent(0, TRUE, FALSE, 0);
    	m_WaitThread =::CreateEvent(0, TRUE, FALSE, 0);
     
    	// Création du thread
    	AfxBeginThread(ThreadFunction, this); ////////erreur 1///////
     
    }

    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
    // Fonction appellée par le thread //
    UINT CMySequence::ThreadFunction(LPVOID* lpParam)
    {
    	CMySequence *pThis = static_cast(lpParam); /////erreur 2//////
    	// On boucle tant que l'événement n'est pas signalé
    	if(::WaitForSingleObject(pThis->m_EndThread, 0)!=WAIT_OBJECT_0)
    	{
    		::SetEvent(pThis->m_WaitThread);
    		return 0;
    	}
     
    	(reinterpret_cast<CMySequence*>(lpParam))->Play();
     
    		return 0;
    }


    Les problèmes :


    /////erreur 1////// : 'AfxBeginThread' : aucune des surcharges 2 ne peut convertir le paramètre 1 à partir du type 'UINT (LPVOID * )'
    -------------> c'est vrai que je ne vois aucune définition commençant par un UINT

    /////erreur 2////// : erreur de syntaxe : '(' à l'endroit signalé ci-dessus par



    Et sinon quand on en aura fini avec ça, tu peux me dire aussi pour le problème d'affichage (cf premier post avec Invalidate et updateWindow)?

    Merci.

  4. #4
    Membre habitué
    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
    Points : 159
    Points
    159
    Par défaut
    Bon, j'ai résolu les 2 problèmes (à corriger dans la FAQ ou c'est que dans mon cas?)

    CMySequence *pThis = static_cast(lpParam); //pas bien
    CMySequence *pThis = reinterpret_cast<CMySequence*>(lpParam); //bien

    UINT CMySequence::ThreadFunction(LPVOID* lpParam) //pas bien
    UINT CMySequence::ThreadFunction(LPVOID lpParam) //bien

    ----------------------------------------------------------------------------------------
    Maintenant que ça compile, voilà les 2 derniers :

    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
    UINT CMySequence::ThreadFunction(LPVOID lpParam)
    {
    	//CMySequence *pThis = reinterpret_cast<CMySequence*>(lpParam);
    	CMySequence *pThis = (CMySequence*)(lpParam);
     
    	while(true)
    	{
    		// On boucle tant que l'événement n'est pas signalé
    		if(WaitForSingleObject(pThis->m_EndThread, 0)!=WAIT_OBJECT_0)
    		{
    			SetEvent(pThis->m_WaitThread);
    			return 0;
    		}
     
    		pThis->Play();
     
    			return 0;
    	}
    }

    On rentre à chaque fois dans la partie SetEvent(pThis->m_WaitThread); donc ma fonction Play n'est jamais appelée,

    Et pour ma question d'affichage...une idée (Invalidate, UpdateWindow, rappel)

  5. #5
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Points : 138
    Points
    138
    Par défaut
    Bonjour,

    Quand tu appelles AfxBeginThread, cast ta fonction en AFX_THREADPROC.

  6. #6
    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
    Points : 17 323
    Points
    17 323
    Par défaut
    re,desole pour la static_cast faut que je corrige ..
    pour le 1 tu n'as rien resolu lol ,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (reinterpret_cast<CMySequence*>(lpParam))->Play();
    ta fonction play fait du gui !!! d'ou le plantage

  7. #7
    Membre habitué
    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
    Points : 159
    Points
    159
    Par défaut
    Bon, alors concrètement - parce que là depuis 9h30 ce matin, j'ai fait que tourner en rond et j'aimerais beaucoup finir par produire quelque chose aujourd'hui - qu'est-ce que je fais avec ma fonction "Play"?

    Please, du code, du concrès parce que la j'en peux plus (et cette histoire de gui, c'est loin de me porter chance contrairement à la plante , lol)


    PS: elle est peut-être pas bien ma fonction Play mais de toutes façons le programme essaie même pas de rentrer dedans

  8. #8
    Membre du Club Avatar de Hokagge
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 149
    Points : 67
    Points
    67
    Par défaut
    Une petite idée, comme ca gratos:

    Pourquoi ne pas mettre le contenu de ta boucle for dans un timer reglé a quelque millisecondes, du coup il devient facile de couper l'éxécution du contenu de ta boucle for, par l'appui sur ton bouton stop, en lancant le "StopTimer".

  9. #9
    Membre habitué
    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
    Points : 159
    Points
    159
    Par défaut
    J'ai eu cette idée au départ mais je ne sais plus pourquoi j'ai fini par avoir l'impression que c'était typiquement les threads qu'il fallait utiliser.
    De toutes façons, j'y suis jusqu'au cou maintenant alors autant que j'aille jusqu'au bout, ça me sera de toutes façons utile pour la suite.

  10. #10
    Membre habitué
    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
    Points : 159
    Points
    159
    Par défaut
    Citation Envoyé par farscape
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (reinterpret_cast<CMySequence*>(lpParam))->Play();
    ta fonction play fait du gui !!! d'ou le plantage
    Je ne sais toujours pas quoi faire alors; comment je peux remplacer ce que j'avais mis dedans?!

    Et sinon, pour mes problèmes d'affichage d'images successives avec Invalidate() et UpdateWindow(), une solution?
    Rappel : cela met trop de temps à mettre la nouvelle image, d'où le problème de fluidité lors de la lecture.

    Bref, tous mes problèmes sont dans la fonction Play.

  11. #11
    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
    Points : 17 323
    Points
    17 323
    Par défaut
    salut,
    et bien je te l'ai dis lol,
    tout ce traitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        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();   //pas terrible comme effet
          pView->UpdateWindow(); //mais l'un ou l'autre seulement ne suffit pas
    ne peut pas etre fait dans le thread.
    ton thread doit envoyer un message privé à ta view pour effectué ce traitement ....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        BYTE *pimg=(BYTE *)imgOriginal.GetBits();
          pCMyIm = GetAtImage(m_iCur);
          memcpy(pimg  -  pCMyIm->Width() * (pCMyIm->Height() - 1 ) * pCMyIm->BytesPerPix(), pCMyIm->GetImage(), pCMyIm->Width() * pCMyIm->Height() * pCMyIm->BytesPerPix());
     
        Invalidate();   //pas terrible comme effet
    //    UpdateWindow(); //mais l'un ou l'autre seulement ne suffit pas
    voir ce post pour le message privé :
    http://www.developpez.net/forums/vie...567222#1567222
    (note je me suis planté dans mon post precedent le deuxieme lien correspondait en fait a ce post ).

    j'espere que c'est plus clair.

  12. #12
    Membre habitué
    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
    Points : 159
    Points
    159
    Par défaut
    Citation Envoyé par farscape
    j'espere que c'est plus clair.
    Hello,

    Non, je suis en super panique là!

    Bon, faut faire un mix de la méthode précédente et des messages privés ou pas, parce que ça n'a plus rien à voir:

    Avant il y avait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // Création des events
    m_EndThread=CreateEvent(0, TRUE, FALSE, 0);
    m_WaitThread =CreateEvent(0, TRUE, FALSE, 0);
    // Création du thread
    AfxBeginThread(ThreadFunction, this);
    Là, fait mettre
    AfxBeginThread(TheThread,GetSafeHwnd(),THREAD_PRIORITY_NORMAL) ;
    Mais maintenant on dirait qu'il faut mettre ça dans View alors que moi c'est un bouton d'une boîte de dialogue avec sa classe associée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void CSdisamplesView::OnButtonUp(NMHDR* pNMHDR, LRESULT* pResult)
    {
       PostMessage(WM_TEST);
    }
    Alors ça, je ne sais pas du tout ce que c'est : la vue ne vas quand même pas guetter durant toute l'application que le bouton de la souris s'active (même quand il est dowm, ça n'a pas forcément avoir avec le thread en question)


    Je suis complètement perdu


    Si on revient au commencement, j'ai ma boîte de dialogue de classe CPlayDlgqui lance la séquence et qui appelle alors la fonction de CMySequence
    void CMySequence:laySequence(int m_iFrom, int m_iTo, int m_iSpeedPlay, BOOL m_bBoucle)


    Où je met les threads et tout : dans l'exemple des messages privés, j'ai l'impression que tout se fait dans la View donc je suis perplexe

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Points : 102
    Points
    102
    Par défaut nananna
    Il suffit que ta boite de dialogue traite les messages de ton thread c'est tout. Comme dans la FAQ tu ajoute ON_MESSAGE pour le/les messages de ton thread c'est tout.

    Ensuite tu ajoute une fonction du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    OnMyMessage()
    {
    //Fait ce que tu veux avec ton gui
    }
    Les macron de message map sont deja dans ta classe cdialog alors t'embete pas a les mettre autre part

  14. #14
    Membre habitué
    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
    Points : 159
    Points
    159
    Par défaut
    Bon, j'ai une configuration qui fait "Coucou" (lol, cf FAQ) quand j'appuie sur Play (une fois) et quand j'appuie sur STOP (une fois).

    Autrement dit rein à voir avec une fonction qui a lieu quand on appuie sur Play jusqu'à temps qu'on appuie sur Stop

    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
    void CMySequence::PlaySequence(int m_iFrom, int m_iTo, int m_iSpeedPlay, BOOL m_bBoucle)
    {
    	m_iSeqFrom = m_iFrom ;
    	m_iSeqTo = m_iTo;
    	m_iSeqSpeedPlay = m_iSpeedPlay;
    	m_bSeqBoucle = m_bBoucle;
     
    	CMyProjectView *pView=(CMyProjectView *) ((CMainFrame *)AfxGetMainWnd())->GetActiveFrame()->GetActiveView();
    	AfxBeginThread(ThreadFunction,pView->GetSafeHwnd(),THREAD_PRIORITY_NORMAL) ;
    }
     
    // Fonction appellée par le thread //
    UINT CMySequence::ThreadFunction(LPVOID lpParam)
    {
    	HWND hWnd= static_cast< HWND >(lpParam) ;
    	PostMessage(hWnd,WM_TEST,0,0) ;
    	return 0;
    }

    Fonction d'arrêt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void CMySequence::Stop(void)
    {
    	CMyProjectView *pView=(CMyProjectView *) ((CMainFrame *)AfxGetMainWnd())->GetActiveFrame()->GetActiveView();
    	pView->PostMessage(WM_TEST);
    }
    Et puis dans ma classe View j'ai fait ce qui était dit à propos de la création de la fonction :
    long CMyProjectView::OnReceiveTest(WPARAM wparam, LPARAM lparam)
    {
    AfxMessageBox("coucou");
    return 0L;
    }

  15. #15
    Membre habitué
    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
    Points : 159
    Points
    159
    Par défaut
    Après l'intervention de chronos, voilà que maintenant je met tout dans ma boîte CPlayDlg; pour l'instant, le bouton Stop est inactif quand on a le thread (boucle infinie) en cours.

    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
    25
    26
    27
    28
    void CPlayDlg::OnBnClickedPlay()
    {
    AfxBeginThread(ThreadFunction,GetSafeHwnd(),THREAD_PRIORITY_NORMAL) ;
    }
     
    // Fonction appellée par le thread //
    UINT CPlayDlg::ThreadFunction(LPVOID lpParam)
    {
    	HWND hWnd= static_cast< HWND >(lpParam) ;
    	::PostMessage(hWnd,WM_TEST,0,0) ;
    	return 0;
     
    }
     
     
    void CPlayDlg::OnBnClickedStop()
    {
    PostMessage(WM_TEST);
    }
     
    long CPlayDlg::OnReceiveTest(WPARAM wparam, LPARAM lparam)
    {
    // c'est là que j'écrirai ma fonction qui tourne en boucke, un peu comme ci-dessous :
     
    	int i=0;
    	while(1)
    		i++;
    }

    Donc, avec ça, qu'est-ce qui fait qu'on ne peut pas lancer l'interruption?

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Points : 102
    Points
    102
    Par défaut ahhhh
    Oups j'ai compri de travers....
    Toi tu part du bouton pour arrter le thread et moi je part du thread pour dire a la boite de dialog a y est fini !!

    Tu veux simplement arreter ton thread ???
    Si c'est le cas oubli les messages et autres trucs

    http://msdn.microsoft.com/library/de...pendthread.asp

    Tu suspends (ou arrete simplement ton thread) avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DWORD SuspendThread(
      HANDLE hThread
    );
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void CPlayDlg::OnBnClickedStop() 
    { 
    SuspendThread(handledetonthraed);
    }
    C'est quand meme plus simple !!!
    Eu je suis désolé je commence tout juste l'apprentissage de la lecture

  17. #17
    Membre habitué
    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
    Points : 159
    Points
    159
    Par défaut
    Et bien au final, après avoir essayé 15 méthodes différentes, j'aurais strictement RIEN compris aux threads!!!

    Pfffffffffff

  18. #18
    Membre habitué
    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
    Points : 159
    Points
    159
    Par défaut
    J'ai même essayé de voir ça :
    http://www.codeppc.com/evc/articles/multithread/mt1.htm

    Son idée de créér une structure pParams, astuce pour passer plusieurs paramètres au lieu d'un LPVOID semblait intéressante avant de faire :
    hThread = CreateThread(NULL,0,ReceptionThread,(LPVOID) pParams,0,NULL);

    Mais comme il faut aussi avoir un Event (hStopEvent) pour arrêter le thread
    hThread = CreateThread(NULL,0,ReceptionThread,(LPVOID) hStopEvent,0,NULL);
    C'est pas possible de faire les 2 en même temps.

    De toutes façons, j'arrivais pas à me servir du LPVOID pour accéder aux champs de ma structure ensuite.



    Enfin mince, comment on peut arrêter une fonction de lecture déclenchée par PLAY qui comporte une boucle ininterrompue simplement en appuyant sur STOP
    Avec les problèmes de la fonction à exécuter qui veut différents paramètres (non statiques)

    Ca fait maintenant 2 journées entières que j'ai perdues sur cette c...

  19. #19
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Points : 138
    Points
    138
    Par défaut
    Salut,

    Bon un LPVOID c'est un void *, donc un pointeur, à paritr de là tu peux passer ce que tu veux à ta fonction (ou presque), par exemple une liste de pointeurs.

    [CODE]
    CPtrList *pt_Liste_Params;

    pt_Lsite_Params->AddTail((void*)hStopEvent);
    pt_Lsite_Params->AddTail((void*)pParams);
    //etc

    hThread = CreateThread(NULL,0,ReceptionThread,(LPVOID) Params,0,NULL);

    [\CODE]

    Il suffit de récupérer ensuite ta liste et tout ce qu'elle contient.
    Tu peux bien sur passer d'autres type de pointeurs à ton thread.


    Pour arrêter ta boucle infinie, il suffit de signaler un event ou bien tu attends sur une condition qui n'est pas tout le temps à vraie.

    Bon courage.

  20. #20
    Membre habitué
    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
    Points : 159
    Points
    159
    Par défaut
    Merci pour tous ceux qui prennent le temps et la patience de se pencher sur mon cas (qui a dit sésespéré).

    Malheureusement, toujours et encore rien à faire avec cette version :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	typedef struct tagTHREAD_PARAMS
    	{
    		int m_iSeqFrom;
    		int  m_iSeqTo;
    		int m_iSeqSpeedPlay;
    		int m_bSeqBoucle;
    		HANDLE hStopEvent;
     
    	} THREAD_PARAMS, *LPTHREAD_PARAMS;
    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
    25
    26
    void CMySequence::PlaySequence(int m_iFrom, int m_iTo, int m_iSpeedPlay, BOOL m_bBoucle)
    {
    	pParams = (LPTHREAD_PARAMS) malloc(sizeof(THREAD_PARAMS));
    	pParams->m_iSeqFrom = m_iFrom;
    	pParams->m_iSeqTo = m_iTo;
    	pParams->m_iSeqSpeedPlay = m_iSpeedPlay;
    	pParams->m_bSeqBoucle = m_bBoucle;
    	pParams->hStopEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
     
     
    	hThread = CreateThread(NULL,0,ThreadFunction,(LPVOID)pParams,0,NULL);
     
    	if (hThread==NULL)
           AfxMessageBox("Echec de la céation du thread",MB_OK);
        else
        {
           DWORD dwWait;
     
           SetEvent(pParams->hStopEvent); //demande de sortie au thread
           dwWait = WaitForSingleObject(hThread,INFINITE);
     
    		if (dwWait==WAIT_OBJECT_0)
    		CloseHandle(hThread);
        }
     
    }

    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
    25
    26
    27
    28
    // Fonction appellée par le thread //
    DWORD WINAPI CMySequence::ThreadFunction(LPVOID lpParam)
    {
    	HANDLE hStopEvent = (HANDLE)lpParam;
        DWORD dwWait;
        BOOL fRun = TRUE;
    	int i=0;
     
     
        while(fRun)
        {
           dwWait = WaitForSingleObject(hStopEvent,1000); //là faudra que je mette le temps que je veux
           switch(dwWait)
            {
              case WAIT_OBJECT_0:
                 // L'événement stop a été déclenché,
                 // sortir proprement du thread
                fRun = FALSE;
                break;
     
              case WAIT_TIMEOUT:
                // Chaque seconde, effectuer le boulot
                i++; //ma vraie fonction Play
                break;
             }
    	}
    	return 0;
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void CMySequence::Stop(void)
    {
    	DWORD dwWait;
        SetEvent(pParams->hStopEvent);
        dwWait = WaitForSingleObject(hThread,INFINITE);
        CloseHandle(hThread);
    }

    Toujours les 2 problèmes :
    1°/ la fonction STOP ne fait rien (on reste coincé dans le while(fRun) ), et je ne peux même pas utiliser mes variables m_iSeqFrom et autres dans le case WAIT_TIMEOUT et de toutes façons je ne rentre même pas dedans [dans aucun des 2 "case"], etc, j'avance vraiment pas du tout, je vais me tirer une balle moi!

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

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