I. Introduction▲
Vous avez surement entendu parler des Timers, mais vous ne savez pas trop comment les mettre en œuvre. Cet article va vous monter qu'il n'y a rien de bien compliqué. Un timer est un système qui envoie un signal régulier à une fréquence déterminée, tel le métronome du musicien. Dans l'exemple nous utiliserons deux timers pour faire clignoter deux rectangles dessinés sur une fenêtre. Pourquoi deux, pour bien montrer la façon de les différencier. Ils auront une fréquence différente. Ils pourront être démarrés ou arrêtés depuis le menu de l'application.

II. Mise en oeuvre▲
Pour créer un timer, il suffit d'appeler la fonction SetTimer
SetTimer
(
hwnd, ID_TIMER_1, 1000
, NULL
);
- Le premier paramètre étant le handle de fenêtre à laquelle il est associé.
- Le second étant un identificateur (constante numérique) qu'on lui attribue.
- Le troisième étant le temps en millisecondes de son tempo.
- Le quatrième que nous n'utiliserons pas est un pointeur sur une fonction de rappel qui est appelée à chaque signal de tempo.
Dans l'exemple nous utiliserons le message qui est envoyé à la fenêtre associée au timer. (Si le timer n'avait pas été associé à une fenêtre, nous aurions été contraints d'utiliser la fonction de rappel.) Ce message est WM_TIMER, il se traite comme les autres messages Windows dans la procédure de fenêtre, comme ceux que nous avons vus dans les autres chapitres. Ce message dans son paramètre wParam contient l'identificateur du timer qui envoie le message, identificateur que l'on avait passé en deuxième paramètre à SetTimer et qui permet donc de savoir de quel timer il s'agit.
2.
3.
4.
5.
6.
7.
8.
9.
10.
case
WM_TIMER:
if
(
wParam ==
ID_TIMER_1)
{
/* action */
}
if
(
wParam ==
ID_TIMER_2)
{
/* action */
}
Quand vous ne voulez plus du Timer, il suffit de le détruire avec la fonction KillTimer avec comme paramètre le handle de fenêtre et l'identificateur du timer.
KillTimer
(
hwnd,ID_TIMER_1);
Pour illustrer l'exemple nos timers feront basculer de true à false et vice versa deux variables booléennes nommées T1 et T2. Ces variables permettront ensuite l'affichage ou non des rectangles dans le traitement du message WM_PAINT. Les timers sont démarrés ou arrêtés depuis les commandes du menu.
III. Code complet▲
III-A. resource.h▲
2.
3.
4.
5.
#define IDM_START_1 101
#define IDM_STOP_1 102
#define IDM_START_2 103
#define IDM_STOP_2 104
#define IDM_QUIT 105
III-B. resource.rc▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
#include <windows.h>
#include "resource.h"
LEMENU MENU
BEGIN
POPUP "
Fichier
"
BEGIN
MENUITEM "
Start Timer 1
"
, IDM_START_1
MENUITEM "
Stop Timer 1
"
, IDM_STOP_1
MENUITEM SEPARATOR
MENUITEM "
Start Timer 2
"
, IDM_START_2
MENUITEM "
Stop Timer 2
"
, IDM_STOP_2
MENUITEM SEPARATOR
MENUITEM "
Quitter
"
, IDM_QUIT
END
END
III-C. winmain.c▲
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.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
#include <windows.h>
#include "resource.h"
#define ID_TIMER_1 1
#define ID_TIMER_2 2
LRESULT CALLBACK WndProc
(
HWND, UINT, WPARAM, LPARAM);
WINAPI WinMain
(
HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int
nCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wc;
wc.style =
0
;
wc.lpfnWndProc =
WndProc;
wc.cbClsExtra =
0
;
wc.cbWndExtra =
0
;
wc.hInstance =
hInstance;
wc.hIcon =
LoadIcon
(
NULL
, IDI_APPLICATION);
wc.hCursor =
LoadCursor
(
NULL
, IDC_ARROW);
wc.hbrBackground =
(
HBRUSH)(
1
+
COLOR_BTNFACE);
wc.lpszMenuName =
"
LEMENU
"
;
wc.lpszClassName =
"
MaWinClass
"
;
if
(!
RegisterClass
(&
wc)) return
FALSE;
hwnd =
CreateWindow
(
"
MaWinClass
"
, "
Timers
"
, WS_OVERLAPPED |
WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, 400
, 260
,
NULL
, NULL
, hInstance, NULL
);
if
(!
hwnd) return
FALSE;
ShowWindow
(
hwnd, nCmdShow);
UpdateWindow
(
hwnd);
while
(
GetMessage
(&
msg, NULL
, 0
, 0
))
{
TranslateMessage
(&
msg);
DispatchMessage
(&
msg);
}
return
msg.wParam;
}
/**
***************************************************************************
*/
LRESULT CALLBACK WndProc
(
HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static
BOOL T1 =
TRUE;
static
BOOL T2 =
TRUE;
switch
(
uMsg)
{
case
WM_CREATE:
return
0
;
case
WM_COMMAND:
switch
(
LOWORD
(
wParam))
{
case
IDM_QUIT :
PostMessage
(
hwnd, WM_CLOSE,0
,0
);
break
;
case
IDM_START_1 :
SetTimer
(
hwnd,ID_TIMER_1,1000
,NULL
);
break
;
case
IDM_START_2 :
SetTimer
(
hwnd,ID_TIMER_2,500
,NULL
);
break
;
case
IDM_STOP_1 :
KillTimer
(
hwnd,ID_TIMER_1);
T1 =
TRUE;
InvalidateRect
(
hwnd,NULL
,TRUE);
break
;
case
IDM_STOP_2 :
KillTimer
(
hwnd,ID_TIMER_2);
T2 =
TRUE;
InvalidateRect
(
hwnd,NULL
,TRUE);
break
;
}
return
0
;
case
WM_TIMER:
if
(
wParam ==
ID_TIMER_1)
{
T1 =
!
T1;
InvalidateRect
(
hwnd,NULL
,TRUE);
}
if
(
wParam ==
ID_TIMER_2)
{
T2 =
!
T2;
InvalidateRect
(
hwnd,NULL
,TRUE);
}
return
0
;
case
WM_PAINT :
{
HBRUSH hbNew, hbrOld;
PAINTSTRUCT ps;
HDC hdc =
BeginPaint
(
hwnd, &
ps);
hbNew =
CreateSolidBrush
(
0x000000FF
);
hbrOld =
SelectObject
(
hdc,hbNew);
if
(
T1) Rectangle
(
hdc, 30
, 20
, 180
, 170
);
SelectObject
(
hdc,hbrOld);
DeleteObject
(
hbNew);
hbNew =
CreateSolidBrush
(
0x00007F00
);
hbrOld =
SelectObject
(
hdc,hbNew);
if
(
T2) Rectangle
(
hdc, 210
, 20
, 360
, 170
);
SelectObject
(
hdc,hbrOld);
DeleteObject
(
hbNew);
EndPaint
(
hwnd, &
ps);
return
0
;
}
case
WM_DESTROY:
PostQuitMessage
(
0
);
return
0
;
default
:
return
DefWindowProc
(
hwnd, uMsg, wParam, lParam);
}
}
À savoir que si le timer n'est pas associé à une fenêtre, c'est la valeur de retour de SetTimer qui sert d'identificateur à passer à KillTimer pour le détruire. Il est possible de changer la fréquence d'un timer déjà démarré par un second appel à SetTimer. N'hésitez pas à consulter le site de msdn pour plus d'informations sur les timers
À vos PC.