blob: a14aa6a2fa56ff82443a5fc893ef913310bb42b9 [file] [log] [blame]
Alexandre Julliard401710d1993-09-04 10:09:32 +00001/*
2 * Timer functions
3 *
4 * Copyright 1993 Alexandre Julliard
5 */
6
Alexandre Julliard401710d1993-09-04 10:09:32 +00007#include "windows.h"
Alexandre Julliardb817f4f1996-03-14 18:08:34 +00008#include "queue.h"
Alexandre Julliardca22b331996-07-12 19:02:39 +00009#include "winproc.h"
Alexandre Julliardaca05781994-10-17 18:12:41 +000010#include "debug.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000011
12
Alexandre Julliard5f721f81994-01-04 20:14:34 +000013typedef struct tagTIMER
Alexandre Julliard401710d1993-09-04 10:09:32 +000014{
Alexandre Julliardca22b331996-07-12 19:02:39 +000015 HWND32 hwnd;
16 HQUEUE16 hq;
17 UINT16 msg; /* WM_TIMER or WM_SYSTIMER */
18 UINT32 id;
19 UINT32 timeout;
Alexandre Julliard5f721f81994-01-04 20:14:34 +000020 struct tagTIMER *next;
Alexandre Julliard8b915631996-06-16 16:16:05 +000021 DWORD expires; /* Next expiration, or 0 if already expired */
Alexandre Julliardca22b331996-07-12 19:02:39 +000022 HWINDOWPROC proc;
Alexandre Julliard401710d1993-09-04 10:09:32 +000023} TIMER;
24
25#define NB_TIMERS 34
26#define NB_RESERVED_TIMERS 2 /* for SetSystemTimer */
27
28static TIMER TimersArray[NB_TIMERS];
29
Alexandre Julliard5f721f81994-01-04 20:14:34 +000030static TIMER * pNextTimer = NULL; /* Next timer to expire */
31
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000032 /* Duration from 'time' until expiration of the timer */
33#define EXPIRE_TIME(pTimer,time) \
34 (((pTimer)->expires <= (time)) ? 0 : (pTimer)->expires - (time))
35
Alexandre Julliard401710d1993-09-04 10:09:32 +000036
37/***********************************************************************
Alexandre Julliard5f721f81994-01-04 20:14:34 +000038 * TIMER_InsertTimer
39 *
40 * Insert the timer at its place in the chain.
Alexandre Julliard401710d1993-09-04 10:09:32 +000041 */
Alexandre Julliard5f721f81994-01-04 20:14:34 +000042static void TIMER_InsertTimer( TIMER * pTimer )
Alexandre Julliard401710d1993-09-04 10:09:32 +000043{
Alexandre Julliard5f721f81994-01-04 20:14:34 +000044 if (!pNextTimer || (pTimer->expires < pNextTimer->expires))
Alexandre Julliard401710d1993-09-04 10:09:32 +000045 {
Alexandre Julliard5f721f81994-01-04 20:14:34 +000046 pTimer->next = pNextTimer;
47 pNextTimer = pTimer;
Alexandre Julliard401710d1993-09-04 10:09:32 +000048 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +000049 else
50 {
51 TIMER * ptr = pNextTimer;
52 while (ptr->next && (pTimer->expires >= ptr->next->expires))
53 ptr = ptr->next;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000054 pTimer->next = ptr->next;
Alexandre Julliard5f721f81994-01-04 20:14:34 +000055 ptr->next = pTimer;
56 }
57}
58
59
60/***********************************************************************
61 * TIMER_RemoveTimer
62 *
63 * Remove the timer from the chain.
64 */
65static void TIMER_RemoveTimer( TIMER * pTimer )
66{
Alexandre Julliardef702d81996-05-28 18:54:58 +000067 TIMER **ppTimer = &pNextTimer;
68
69 while (*ppTimer && (*ppTimer != pTimer)) ppTimer = &(*ppTimer)->next;
70 if (*ppTimer) *ppTimer = pTimer->next;
Alexandre Julliard5f721f81994-01-04 20:14:34 +000071 pTimer->next = NULL;
Alexandre Julliard8b915631996-06-16 16:16:05 +000072 if (!pTimer->expires) QUEUE_DecTimerCount( pTimer->hq );
Alexandre Julliard5f721f81994-01-04 20:14:34 +000073}
74
Alexandre Julliardef702d81996-05-28 18:54:58 +000075
76/***********************************************************************
77 * TIMER_ClearTimer
78 *
79 * Clear and remove a timer.
80 */
81static void TIMER_ClearTimer( TIMER * pTimer )
82{
83 TIMER_RemoveTimer( pTimer );
Alexandre Julliardef702d81996-05-28 18:54:58 +000084 pTimer->hwnd = 0;
85 pTimer->msg = 0;
86 pTimer->id = 0;
87 pTimer->timeout = 0;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +000088 WINPROC_FreeProc( pTimer->proc, WIN_PROC_TIMER );
Alexandre Julliardef702d81996-05-28 18:54:58 +000089}
90
91
Alexandre Julliardc981d0b1996-03-31 16:40:13 +000092/***********************************************************************
93 * TIMER_SwitchQueue
94 */
Alexandre Julliardca22b331996-07-12 19:02:39 +000095void TIMER_SwitchQueue( HQUEUE16 old, HQUEUE16 new )
Alexandre Julliardc981d0b1996-03-31 16:40:13 +000096{
Alexandre Julliardef702d81996-05-28 18:54:58 +000097 TIMER * pT = pNextTimer;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +000098
Alexandre Julliardef702d81996-05-28 18:54:58 +000099 while (pT)
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000100 {
Alexandre Julliardef702d81996-05-28 18:54:58 +0000101 if (pT->hq == old) pT->hq = new;
102 pT = pT->next;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000103 }
104}
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000105
Alexandre Julliardef702d81996-05-28 18:54:58 +0000106
107/***********************************************************************
108 * TIMER_RemoveWindowTimers
109 *
110 * Remove all timers for a given window.
111 */
Alexandre Julliardca22b331996-07-12 19:02:39 +0000112void TIMER_RemoveWindowTimers( HWND32 hwnd )
Alexandre Julliardef702d81996-05-28 18:54:58 +0000113{
114 int i;
115 TIMER *pTimer;
116
117 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
118 if ((pTimer->hwnd == hwnd) && pTimer->timeout)
119 TIMER_ClearTimer( pTimer );
120}
121
122
123/***********************************************************************
124 * TIMER_RemoveQueueTimers
125 *
126 * Remove all timers for a given queue.
127 */
Alexandre Julliardca22b331996-07-12 19:02:39 +0000128void TIMER_RemoveQueueTimers( HQUEUE16 hqueue )
Alexandre Julliardef702d81996-05-28 18:54:58 +0000129{
130 int i;
131 TIMER *pTimer;
132
133 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
134 if ((pTimer->hq == hqueue) && pTimer->timeout)
135 TIMER_ClearTimer( pTimer );
136}
137
138
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000139/***********************************************************************
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000140 * TIMER_RestartTimers
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000141 *
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000142 * Restart an expired timer.
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000143 */
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000144static void TIMER_RestartTimer( TIMER * pTimer, DWORD curTime )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000145{
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000146 TIMER_RemoveTimer( pTimer );
147 pTimer->expires = curTime + pTimer->timeout;
148 TIMER_InsertTimer( pTimer );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000149}
150
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000151
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000152/***********************************************************************
Alexandre Julliard8b915631996-06-16 16:16:05 +0000153 * TIMER_GetNextExpiration
Alexandre Julliardef702d81996-05-28 18:54:58 +0000154 *
155 * Return next timer expiration time, or -1 if none.
156 */
Alexandre Julliard8b915631996-06-16 16:16:05 +0000157LONG TIMER_GetNextExpiration(void)
Alexandre Julliardef702d81996-05-28 18:54:58 +0000158{
159 return pNextTimer ? EXPIRE_TIME( pNextTimer, GetTickCount() ) : -1;
160}
161
162
163/***********************************************************************
Alexandre Julliard8b915631996-06-16 16:16:05 +0000164 * TIMER_ExpireTimers
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000165 *
Alexandre Julliard8b915631996-06-16 16:16:05 +0000166 * Mark expired timers and wake the appropriate queues.
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000167 */
Alexandre Julliard8b915631996-06-16 16:16:05 +0000168void TIMER_ExpireTimers(void)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000169{
Alexandre Julliard8b915631996-06-16 16:16:05 +0000170 TIMER *pTimer = pNextTimer;
171 DWORD curTime = GetTickCount();
172
173 while (pTimer && !pTimer->expires) /* Skip already expired timers */
174 pTimer = pTimer->next;
175 while (pTimer && (pTimer->expires <= curTime))
176 {
177 pTimer->expires = 0;
178 QUEUE_IncTimerCount( pTimer->hq );
179 pTimer = pTimer->next;
180 }
181}
182
183
184/***********************************************************************
185 * TIMER_GetTimerMsg
186 *
187 * Build a message for an expired timer.
188 */
Alexandre Julliardca22b331996-07-12 19:02:39 +0000189BOOL32 TIMER_GetTimerMsg( MSG16 *msg, HWND32 hwnd,
190 HQUEUE16 hQueue, BOOL32 remove )
Alexandre Julliard8b915631996-06-16 16:16:05 +0000191{
192 TIMER *pTimer = pNextTimer;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000193 DWORD curTime = GetTickCount();
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000194
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000195 if (hwnd) /* Find first timer for this window */
196 while (pTimer && (pTimer->hwnd != hwnd)) pTimer = pTimer->next;
Alexandre Julliard8b915631996-06-16 16:16:05 +0000197 else /* Find first timer for this queue */
198 while (pTimer && (pTimer->hq != hQueue)) pTimer = pTimer->next;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000199
Alexandre Julliard8b915631996-06-16 16:16:05 +0000200 if (!pTimer || (pTimer->expires > curTime)) return FALSE; /* No timer */
201 if (remove) TIMER_RestartTimer( pTimer, curTime ); /* Restart it */
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000202
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000203 TRACE(timer, "Timer expired: %04x, %04x, %04x, %08lx\n",
Alexandre Julliard8b915631996-06-16 16:16:05 +0000204 pTimer->hwnd, pTimer->msg, pTimer->id, (DWORD)pTimer->proc);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000205
206 /* Build the message */
Alexandre Julliardca22b331996-07-12 19:02:39 +0000207 msg->hwnd = (HWND16)pTimer->hwnd;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000208 msg->message = pTimer->msg;
Alexandre Julliardca22b331996-07-12 19:02:39 +0000209 msg->wParam = (UINT16)pTimer->id;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000210 msg->lParam = (LONG)pTimer->proc;
211 msg->time = curTime;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000212 return TRUE;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000213}
214
215
216/***********************************************************************
217 * TIMER_SetTimer
218 */
Alexandre Julliardca22b331996-07-12 19:02:39 +0000219static UINT32 TIMER_SetTimer( HWND32 hwnd, UINT32 id, UINT32 timeout,
220 WNDPROC16 proc, WINDOWPROCTYPE type, BOOL32 sys )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000221{
222 int i;
223 TIMER * pTimer;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000224
Alexandre Julliard401710d1993-09-04 10:09:32 +0000225 if (!timeout) return 0;
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000226
227 /* Check if there's already a timer with the same hwnd and id */
228
Alexandre Julliardaca05781994-10-17 18:12:41 +0000229 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
230 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
231 (pTimer->timeout != 0))
232 {
233 /* Got one: set new values and return */
Alexandre Julliardaca05781994-10-17 18:12:41 +0000234 TIMER_RemoveTimer( pTimer );
Alexandre Julliard8b915631996-06-16 16:16:05 +0000235 pTimer->timeout = timeout;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000236 WINPROC_FreeProc( pTimer->proc, WIN_PROC_TIMER );
Alexandre Julliardca22b331996-07-12 19:02:39 +0000237 pTimer->proc = (HWINDOWPROC)0;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000238 if (proc) WINPROC_SetProc( &pTimer->proc, proc,
239 type, WIN_PROC_TIMER );
Alexandre Julliard8b915631996-06-16 16:16:05 +0000240 pTimer->expires = GetTickCount() + timeout;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000241 TIMER_InsertTimer( pTimer );
242 return id;
243 }
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000244
Alexandre Julliard401710d1993-09-04 10:09:32 +0000245 /* Find a free timer */
246
247 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
248 if (!pTimer->timeout) break;
249
250 if (i >= NB_TIMERS) return 0;
251 if (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) return 0;
252 if (!hwnd) id = i + 1;
253
254 /* Add the timer */
255
256 pTimer->hwnd = hwnd;
Alexandre Julliardca22b331996-07-12 19:02:39 +0000257 pTimer->hq = (hwnd) ? GetTaskQueue( GetWindowTask16( hwnd ) )
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000258 : GetTaskQueue( 0 );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000259 pTimer->msg = sys ? WM_SYSTIMER : WM_TIMER;
260 pTimer->id = id;
261 pTimer->timeout = timeout;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000262 pTimer->expires = GetTickCount() + timeout;
Alexandre Julliardca22b331996-07-12 19:02:39 +0000263 pTimer->proc = (HWINDOWPROC)0;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000264 if (proc) WINPROC_SetProc( &pTimer->proc, proc, type, WIN_PROC_TIMER );
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000265 TRACE(timer, "Timer added: %p, %04x, %04x, %04x, %08lx\n",
Alexandre Julliardca22b331996-07-12 19:02:39 +0000266 pTimer, pTimer->hwnd, pTimer->msg, pTimer->id,
267 (DWORD)pTimer->proc );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000268 TIMER_InsertTimer( pTimer );
Alexandre Julliardca22b331996-07-12 19:02:39 +0000269 if (!id) return TRUE;
270 else return id;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000271}
272
273
274/***********************************************************************
275 * TIMER_KillTimer
276 */
Alexandre Julliardca22b331996-07-12 19:02:39 +0000277static BOOL32 TIMER_KillTimer( HWND32 hwnd, UINT32 id, BOOL32 sys )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000278{
279 int i;
280 TIMER * pTimer;
281
Alexandre Julliardef702d81996-05-28 18:54:58 +0000282 /* Find the timer */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000283
284 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
285 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
286 (pTimer->timeout != 0)) break;
287 if (i >= NB_TIMERS) return FALSE;
288 if (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) return FALSE;
289 if (!sys && (pTimer->msg != WM_TIMER)) return FALSE;
290 else if (sys && (pTimer->msg != WM_SYSTIMER)) return FALSE;
291
Alexandre Julliardef702d81996-05-28 18:54:58 +0000292 /* Delete the timer */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000293
Alexandre Julliardef702d81996-05-28 18:54:58 +0000294 TIMER_ClearTimer( pTimer );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000295 return TRUE;
296}
297
298
299/***********************************************************************
Alexandre Julliardca22b331996-07-12 19:02:39 +0000300 * SetTimer16 (USER.10)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000301 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000302UINT16 WINAPI SetTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
303 TIMERPROC16 proc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000304{
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000305 TRACE(timer, "%04x %d %d %08lx\n",
Alexandre Julliardca22b331996-07-12 19:02:39 +0000306 hwnd, id, timeout, (LONG)proc );
307 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc,
308 WIN_PROC_16, FALSE );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000309}
310
311
312/***********************************************************************
Alexandre Julliardca22b331996-07-12 19:02:39 +0000313 * SetTimer32 (USER32.510)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000314 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000315UINT32 WINAPI SetTimer32( HWND32 hwnd, UINT32 id, UINT32 timeout,
316 TIMERPROC32 proc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000317{
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000318 TRACE(timer, "%04x %d %d %08lx\n",
Alexandre Julliardca22b331996-07-12 19:02:39 +0000319 hwnd, id, timeout, (LONG)proc );
320 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc,
321 WIN_PROC_32A, FALSE );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000322}
323
324
325/***********************************************************************
Alexandre Julliardca22b331996-07-12 19:02:39 +0000326 * SetSystemTimer16 (USER.11)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000327 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000328UINT16 WINAPI SetSystemTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
329 TIMERPROC16 proc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000330{
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000331 TRACE(timer, "%04x %d %d %08lx\n",
Alexandre Julliardca22b331996-07-12 19:02:39 +0000332 hwnd, id, timeout, (LONG)proc );
333 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc,
334 WIN_PROC_16, TRUE );
335}
336
337
338/***********************************************************************
339 * SetSystemTimer32 (USER32.508)
340 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000341UINT32 WINAPI SetSystemTimer32( HWND32 hwnd, UINT32 id, UINT32 timeout,
342 TIMERPROC32 proc )
Alexandre Julliardca22b331996-07-12 19:02:39 +0000343{
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000344 TRACE(timer, "%04x %d %d %08lx\n",
Alexandre Julliardca22b331996-07-12 19:02:39 +0000345 hwnd, id, timeout, (LONG)proc );
346 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc,
347 WIN_PROC_32A, TRUE );
348}
349
350
351/***********************************************************************
352 * KillTimer16 (USER.12)
353 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000354BOOL16 WINAPI KillTimer16( HWND16 hwnd, UINT16 id )
Alexandre Julliardca22b331996-07-12 19:02:39 +0000355{
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000356 TRACE(timer, "%04x %d\n", hwnd, id );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000357 return TIMER_KillTimer( hwnd, id, FALSE );
358}
359
360
361/***********************************************************************
Alexandre Julliardca22b331996-07-12 19:02:39 +0000362 * KillTimer32 (USER32.353)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000363 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000364BOOL32 WINAPI KillTimer32( HWND32 hwnd, UINT32 id )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000365{
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000366 TRACE(timer, "%04x %d\n", hwnd, id );
Alexandre Julliardca22b331996-07-12 19:02:39 +0000367 return TIMER_KillTimer( hwnd, id, FALSE );
368}
369
370
371/***********************************************************************
372 * KillSystemTimer16 (USER.182)
373 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000374BOOL16 WINAPI KillSystemTimer16( HWND16 hwnd, UINT16 id )
Alexandre Julliardca22b331996-07-12 19:02:39 +0000375{
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000376 TRACE(timer, "%04x %d\n", hwnd, id );
Alexandre Julliardca22b331996-07-12 19:02:39 +0000377 return TIMER_KillTimer( hwnd, id, TRUE );
378}
379
380
381/***********************************************************************
382 * KillSystemTimer32 (USER32.352)
383 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000384BOOL32 WINAPI KillSystemTimer32( HWND32 hwnd, UINT32 id )
Alexandre Julliardca22b331996-07-12 19:02:39 +0000385{
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000386 TRACE(timer, "%04x %d\n", hwnd, id );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000387 return TIMER_KillTimer( hwnd, id, TRUE );
388}