Probleme de timer avec fonction de callback

Résolu
julienbj Messages postés 452 Date d'inscription jeudi 4 décembre 2003 Statut Membre Dernière intervention 19 décembre 2008 - 2 août 2006 à 11:28
Oliv_Nav Messages postés 5 Date d'inscription vendredi 19 mai 2006 Statut Membre Dernière intervention 11 août 2006 - 11 août 2006 à 15:32
Bonjour,
j'ai un petit souci lors de la création d'un timer avec une fonction de callback.

Voici un bout de code qui ne fonctionne pas, mais je ne vois pas pourquoi. Au debuggeur, j'ai testé les valeurs de retour de SetTimer et KillTimer, aucun souci, pourtant je ne rentre jamais dans la fonction de callback (point d'arret).

VOID CALLBACK Timer(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
 printf(".\n");
}


DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
 unsigned int id;
 MSG msg;


 printf("Création du thread\n");
 id = SetTimer(NULL, 0, 100, Timer);
 while (GetMessage(&msg, NULL, 0, 0));
 KillTimer(NULL, id);
 printf("Fin du thread\n");
 return 0;
}


int main(void)
{
 DWORD ThID;
 HANDLE hTd;


 hTd = CreateThread(NULL, 256, ThreadProc, NULL, 0, &ThID);
 while (!_kbhit());
 TerminateThread(hTd, 0);
 return 0;
}

Cependant, si je ne mets pas de fonction de callback et que j'intercepte le message WM_TIMER dans la boucle while avec le GetMessage, je n'ai pas de problèmes.

Si vous pouviez m'indiquer pourquoi ma fonction de callback n'est pas appelé, ce que j'ai mal fait...
Merci d'avance

Vive le C
Savon
A voir également:

10 réponses

julienbj Messages postés 452 Date d'inscription jeudi 4 décembre 2003 Statut Membre Dernière intervention 19 décembre 2008 15
2 août 2006 à 11:45
Ok, c'est bon, j'ai trouvé.


Comme quoi, il faut demander de l'aide pour avoir une idée ;)


Bref, il y avait 2 problemes. Dans le SetTimer, il manquait un & devant la fonction de callback, et dans la boucle while(GetMessage...), il falait rajouter bien évidemment de quoi transmettre les messages:


TranslateMessage(&msg);DispatchMessage(&msg);

Vive le C
Savon
3
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
2 août 2006 à 16:44
Salut,

Je vois pas vraiment l'utilité du timer ici, tu aurais aussi pu faire une boucle infinie avec un Sleep(100) et un printf(), non?
0
julienbj Messages postés 452 Date d'inscription jeudi 4 décembre 2003 Statut Membre Dernière intervention 19 décembre 2008 15
3 août 2006 à 17:57
Oui, evidemment, ce bout de code ne servait d'exemple que pour expliquer mon problème.

Vive le C, Savon
0
Oliv_Nav Messages postés 5 Date d'inscription vendredi 19 mai 2006 Statut Membre Dernière intervention 11 août 2006
9 août 2006 à 15:12
bonjour !


ca m'intéresse, votre histoire. Y'a quelquechose qui m'échappe : quelle est l'utilité de Settimer ?


Pour moi, ca lancait comme un mini thread caché, qui émettait des evenements périodiquement. Ces evenements allaient réveiller la fonction en call back.

Mais à partir du moment ou on met ca derriere : 

 while (GetMessage(&msg, NULL, 0, 0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }

on reste bloqué sur le while. Du coup, le déroulement dans le thread en cours est interrompu.

Bref, pour poser une question, est-il possible d'obtenir le fonctionnement que je decris plus haut (mon mini thread caché), ou dois-je créer carrément un thread (dans ce cas, j'ai vraiment du mal à saisir l'intéret de Settimer, vis à vis d'un Sleep) ?

Merci et bonne journée

Olivier
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Oliv_Nav Messages postés 5 Date d'inscription vendredi 19 mai 2006 Statut Membre Dernière intervention 11 août 2006
9 août 2006 à 17:00
je reviens juste sur ce que j'ai écrit : j'ai l'air de faire la meme remarque que aardman ; sauf que lui, il a compris l'intéret des settimer dans le cas général. Pas moi. 
Je viens donc chercher des infos plus général, pour comprendre comment on est censé se servir de cette fonction

Merci

Olivier 
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
9 août 2006 à 17:25
Salut,

L'intéret de ce type de timer, c'est qu'il est très facile à utiliser,
mais par contre on est obligé de l'utiliser dans un thread qui possede
une boucle de message (comme celle de ton post), car les evenements du
timer sont recus et traités sous forme de messages windows.
0
Oliv_Nav Messages postés 5 Date d'inscription vendredi 19 mai 2006 Statut Membre Dernière intervention 11 août 2006
10 août 2006 à 11:35
merci pour ta réponse, mais je vois pas encore bien.

Pourrais-tu me donner un exemple dans lequel il est plus malin d'utiliser "setTimer" plutot que "while() Sleep(xxx) SetEvent(xxx)" ?

merci !
0
Oliv_Nav Messages postés 5 Date d'inscription vendredi 19 mai 2006 Statut Membre Dernière intervention 11 août 2006
10 août 2006 à 15:19
il me vient une autre remarque / question : quand je fais un thread, j'aime bien ne pas rester bloqué à l'intérieur (que ce soit dans un Sleep ou un getMessage) :
 
je me met en attente d'evenement.
quand j'en recois un, je fais vite mon traitement, et me remet en attente.

Ca permet d'etre presque toujours dispo aux evenement.

La, tout le temps ou je suis dans le Sleep, ou le while GetMessage), je n'ecoute rien d'autre. Ca me chiffonne, parce que j'aimerais bien recevoir un message qui me permette d'arreter le thread proprement et rapidement.

Comment gérer cet arret de thread au moment ou le message d'arret arrive ?
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
10 août 2006 à 18:41
Salut,

Tu sembles parler de Sleep() et de GetMessage() comme qu'ils avaient la
même fonction et qu'ils bloquaient le thread de la même facon.

Sleep() est une fonction qui bloque completement le thread, pendant un
temp bien determiné. GetMessage(), par contre, bloque le thread jusqu'a
ce qu'un message soit posté dans la pile de message du thread. Si ce
message est WM_QUIT, GetMessage() retourne FALSE (ce qui a pour effet
de sortir de la boucle de message). Sinon, GetMessage retourne TRUE, et
le message est traité (généralement, par TranslateMessage() et
DispatchMessage()).


Pour en revenir aux timers, SetTimer() génere ses evenements sous forme
de message windows, et donc il est parfait pour s'integrer dans un
thread qui a une boucle de message.


Pour ta question sur le thread, tu peux le faire avec une boucle de message.

Pour terminer ton thread, it te suffit d'envoyer un WM_QUIT a ton thread.


Un dernier truc: il existe d'autres types de timers sous windows: SetWaitableTimer(), CreateTimerQueueTimer(), ...
0
Oliv_Nav Messages postés 5 Date d'inscription vendredi 19 mai 2006 Statut Membre Dernière intervention 11 août 2006
11 août 2006 à 15:32
ca m'a éclairé : le coup du WM_QUIT est intéressant.


merci beaucoup !


 


 
0
Rejoignez-nous