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 ?
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 ?
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. -> lobjet doit être signalé // WaitForSingleObject renvoie WAIT_OBJECT_0 si lobjet 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
Allez, un dernier UP désespéré pour ce sujet, sans trop d'espoir maintenant...
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.)Envoyé par Brouzouf
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).
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.
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.
Pour communiquer avec une fenêtre dans un thread, tu dois obligatoirement passer par des messages.
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.
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.
salut,
je reprends au vol,
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.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
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
![]()
Ce qui est affirmé sans preuve peut être nié sans preuve Euclide.
Les conversions numériques en C,C++,C++/CLI
DLL d'extensions : écriture d'un plug-in de classe
Démarrer avec les MFC 2/2
Création d'un ActiveX MFC
Intégration d'une imprimante PDF pour éditions automatisées
Migrer du code de Visual C++ 6.0 vers Visual C++ 2005
Démarrer avec les MFC sous Visual C++1/2
la Faq Visual C++ 500 Q/R,Mon blog
Aide en Ligne MFC
Cours et tutoriels C++ - FAQ C++ - Forum C++.
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. -> lobjet doit être signalé // WaitForSingleObject renvoie WAIT_OBJECT_0 si lobjet 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.
![]()
aaah aiaia,
voila play, pitie tu lui passe en argument le pointeur sur la view recu dans ta fonction thread.
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); }
![]()
Ce qui est affirmé sans preuve peut être nié sans preuve Euclide.
Les conversions numériques en C,C++,C++/CLI
DLL d'extensions : écriture d'un plug-in de classe
Démarrer avec les MFC 2/2
Création d'un ActiveX MFC
Intégration d'une imprimante PDF pour éditions automatisées
Migrer du code de Visual C++ 6.0 vers Visual C++ 2005
Démarrer avec les MFC sous Visual C++1/2
la Faq Visual C++ 500 Q/R,Mon blog
Aide en Ligne MFC
Cours et tutoriels C++ - FAQ C++ - Forum C++.
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!![]()
Partager