Les timers

 

 

C'est la possibilité de lancer un traitement périodiquement. Vous informez Windows que vous voulez qu'un traitement soit déclencher tous les n millisecondes.

Cette solution était la toute première méthode pour lancer un traitement précis à une heure précise (quoique pour la précision, il faudra repasser, car ce message n'est pas prioritaire dans la liste des messages). C'est donc du vieux, cela existait déjà sous Windows 3.1 !

Ce type de timer ne fonctionne qu'à l'intérieur d'un thread (Et oui, les threads n'existaient pas sous Windows 3.1. Si vous ne savez pas encore ce que c'est un thread, il y a un chapitre dessus, mais dans votre cas, vous n'en avez peut-être pas forcément besoin...).

 

Pour activer les timers:

Pour activer un timer, utilisez la fonction SetTimer()

UINT_PTR SetTimer(

HWND hWnd,
UINT_PTR nIDEvent,
UINT uElapse,
TIMERPROC lpTimerFunc

);

Les paramètres sont les suivants:

hWnd : Handle de la fenêtre associée au timer

Image non trouvée ! (et je me répète): la fenêtre et le timer doivent avoir le même thread). Si la valeur passée est NULL, il n'y a alors pas de fenêtre associée et le second paramètre (nIDEvent) ne serait pas traité.

nIDEvent : Numéro pour identifier les timers dans une fenêtre. Cette valeur est inutile si hWnd est NULL. Par contre, si pour une fenêtre, vous positionnez un identificateur déjà utiliser par un timer sur cette même fenêtre, alors le timer existant est remplacé par le nouveau timer et l'horloge est alors remise à zéro. Remarque: si deux timers sont créés mais chacun dans des fenêtres différentes, alors il est possible d'avoir le même numéro d'identification de timer. Ils seront quand même différents l'un de l'autre.

uElapse : Indique la durée d'attente avant de déclencher le timer en milliseconde. Ne mettez pas n'importe quoi comme valeur !

lpTimerFunc : Pointeur sur une fonction qui sera déclenchée à la fin du temps écoulé. Si la valeur est NULL, le système enverra WM_TIMER dans la file de messages de l'application.

La fonction retourne l'identifiant du timer qui sera utile pour pouvoir l'arrêter ensuite ou zéro si problème (exemple : plus de timer disponible).

 

Si vous ne précisez pas de procédure pour le timer, alors l'application recevra le message WM_TIMER. La procédure de la fenêtre pourra ainsi traiter ce message normalement.

Si vous précisez une procédure, alors cette procédure pourra récupérer les informations qui passent normalement dans un message WM_TIMER.

 

Que ce soit la procédure de la fenêtre ou une procédure associée au timer, la lecture des informations envoyées par le timer est la suivante:

wParam sera renseigné avec le numéro d'identification du timer.

lParam sera un pointeur sur la fonction a déclencher pour le timer (la fonction définie dans SetTimer()).

 

Comment arrêter le timer !

Tout les matins, c'est pareil, ce fichu réveil sonne, mais voilà le weekend, et je ne veux pas être dérangé !

Il y a une solution : KillTimer. Cette fonction va arrêter votre horloge. (Mais cela n'évitera pas votre bambin de se réveiller à 6 h00 pour le biberon !)

BOOL KillTimer(
HWND hWnd,
UINT_PTR uIDEvent
);

Cette fonction n'est pas bien difficile, cela correspond aux valeurs passées lors du SetTimer() !

Si une erreur se produit, la fonction retournera 0.

Remarque : Cette fonction ne retire pas les messages WM_TIMER déjà présent dans la file d'attente !

 

La procédure TIMER:

Comme indiqué précédemment, il est possible d'identifier une procédure qui gérera les messages spécifiques des timers, enfin quand je dis les messages, le seul type de message qu'il lira sera du type WM_TIMER:

Voici donc un exemple:

VOID CALLBACK MyTimerProc(
HWND hwnd, // handle de la window
UINT message, // Message WM_TIMER
UINT idTimer, // identificateur du timer
DWORD dwTime) // heure système courante
{

/* Votre code ici */

}

 

Les différents utilisations du timer

Voici un premier exemple:

Un timer est créé, votre procédure de fenêtre va traiter ce message.

Image non trouvée !

Même chose, mais avec une procédure pour le timer associé à votre fenêtre.

Image non trouvée !

Enfin, un timer avec une procédure et qui n'est pas associé à votre fenêtre. Je ne sais pas à quoi cela peut servir, A part pour ne pas s'embêter avec l'identificateur du handle (il est généré...)

Image non trouvée !

 

Remarque:

- Il ne faut pas confondre les timers et le multithreading, le multithreading (étudié dans un autre chapitre) est la possibilité de lancer n traitements en "parallèle" dans un même processus. C'est à dire que pour le même processus, n codes tournent en "même temps". Ce n'est pas du tout le cas des timers. Un timer c'est un traitement qui ne sera lancé uniquement lorsque le traitement précédant sera fini.

- Ce type de timer n'a rien à voir avec les objets timers qui existent pour les threads (voir le chapitre multithreads/les timers).

- Ne pas confondre avec les interruptions timer sous DOS. Dans ce cas, le programme était interrompu immédiatement pour exécuter le code du timer. Sous Windows, ce n'est pas le cas car lorsque le temps est écoulé, Windows pose un message dans la file d'attente pour informer qu'un time out vient de se produire pour ce timer. Ce qui veut dire qu'il faudra un certain laps de temps avant de traiter ce message (il faut d'abord lire les autres messages). De plus, le message WM_TIMER est le message le moins urgent dans la gestion des messages. Vous risquez donc d'avoir du retard entre l'émission du message et son traitement effectif.