blob: b46be521caafe7d46df09b5544b42e657eb7583c [file] [log] [blame]
Alexandre Julliard401710d1993-09-04 10:09:32 +00001/*
2 * Timer functions
3 *
4 * Copyright 1993 Alexandre Julliard
5 */
6
Patrik Stridvall1ed4ecf1999-06-26 14:58:24 +00007#include "wine/winuser16.h"
Marcus Meissner61afa331999-02-22 10:16:00 +00008#include "winuser.h"
Alexandre Julliardb817f4f1996-03-14 18:08:34 +00009#include "queue.h"
Ulrich Weigand1babe5b1998-12-24 15:16:08 +000010#include "task.h"
Alexandre Julliardca22b331996-07-12 19:02:39 +000011#include "winproc.h"
Ulrich Weigand9dcaeca1999-05-02 11:30:39 +000012#include "services.h"
Patrik Stridvall1ed4ecf1999-06-26 14:58:24 +000013#include "message.h"
Alexandre Julliard359f497e1999-07-04 16:02:24 +000014#include "debugtools.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000015
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000016DEFAULT_DEBUG_CHANNEL(timer)
17
Alexandre Julliard401710d1993-09-04 10:09:32 +000018
Alexandre Julliard5f721f81994-01-04 20:14:34 +000019typedef struct tagTIMER
Alexandre Julliard401710d1993-09-04 10:09:32 +000020{
Alexandre Julliarda3960291999-02-26 11:11:13 +000021 HWND hwnd;
Ulrich Weiganda9238081999-06-22 19:11:33 +000022 HQUEUE16 hq;
23 UINT16 msg; /* WM_TIMER or WM_SYSTIMER */
Alexandre Julliarda3960291999-02-26 11:11:13 +000024 UINT id;
25 UINT timeout;
Ulrich Weiganda9238081999-06-22 19:11:33 +000026 HANDLE hService;
27 BOOL expired;
28 HWINDOWPROC proc;
Alexandre Julliard401710d1993-09-04 10:09:32 +000029} TIMER;
30
31#define NB_TIMERS 34
32#define NB_RESERVED_TIMERS 2 /* for SetSystemTimer */
33
Uwe Bonnes23cadd31999-09-04 14:32:27 +000034#define SYS_TIMER_RATE 54925
35
Alexandre Julliard401710d1993-09-04 10:09:32 +000036static TIMER TimersArray[NB_TIMERS];
37
Stephane Lussier35ffc5d1999-03-25 13:23:26 +000038static CRITICAL_SECTION csTimer;
39
Alexandre Julliard401710d1993-09-04 10:09:32 +000040
41/***********************************************************************
Stephane Lussier35ffc5d1999-03-25 13:23:26 +000042 * TIMER_Init
43 *
44 * Initialize critical section for the timer.
45 */
46BOOL TIMER_Init( void )
47{
48 InitializeCriticalSection( &csTimer );
49 MakeCriticalSectionGlobal( &csTimer );
50
51 return TRUE;
52}
53
54
55/***********************************************************************
Alexandre Julliardef702d81996-05-28 18:54:58 +000056 * TIMER_ClearTimer
57 *
58 * Clear and remove a timer.
59 */
60static void TIMER_ClearTimer( TIMER * pTimer )
61{
Ulrich Weiganda9238081999-06-22 19:11:33 +000062 if ( pTimer->hService != INVALID_HANDLE_VALUE )
63 {
64 SERVICE_Delete( pTimer->hService );
65 pTimer->hService = INVALID_HANDLE_VALUE;
66 }
67
68 if ( pTimer->expired )
69 {
70 QUEUE_DecTimerCount( pTimer->hq );
71 pTimer->expired = FALSE;
72 }
73
Alexandre Julliardef702d81996-05-28 18:54:58 +000074 pTimer->hwnd = 0;
75 pTimer->msg = 0;
76 pTimer->id = 0;
77 pTimer->timeout = 0;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +000078 WINPROC_FreeProc( pTimer->proc, WIN_PROC_TIMER );
Alexandre Julliardef702d81996-05-28 18:54:58 +000079}
80
81
Alexandre Julliardc981d0b1996-03-31 16:40:13 +000082/***********************************************************************
Alexandre Julliardef702d81996-05-28 18:54:58 +000083 * TIMER_RemoveWindowTimers
84 *
85 * Remove all timers for a given window.
86 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000087void TIMER_RemoveWindowTimers( HWND hwnd )
Alexandre Julliardef702d81996-05-28 18:54:58 +000088{
89 int i;
90 TIMER *pTimer;
91
Stephane Lussier35ffc5d1999-03-25 13:23:26 +000092 EnterCriticalSection( &csTimer );
93
Alexandre Julliardef702d81996-05-28 18:54:58 +000094 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
95 if ((pTimer->hwnd == hwnd) && pTimer->timeout)
96 TIMER_ClearTimer( pTimer );
Stephane Lussier35ffc5d1999-03-25 13:23:26 +000097
98 LeaveCriticalSection( &csTimer );
Alexandre Julliardef702d81996-05-28 18:54:58 +000099}
100
101
102/***********************************************************************
103 * TIMER_RemoveQueueTimers
104 *
105 * Remove all timers for a given queue.
106 */
Alexandre Julliardca22b331996-07-12 19:02:39 +0000107void TIMER_RemoveQueueTimers( HQUEUE16 hqueue )
Alexandre Julliardef702d81996-05-28 18:54:58 +0000108{
109 int i;
110 TIMER *pTimer;
111
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000112 EnterCriticalSection( &csTimer );
113
Alexandre Julliardef702d81996-05-28 18:54:58 +0000114 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
115 if ((pTimer->hq == hqueue) && pTimer->timeout)
116 TIMER_ClearTimer( pTimer );
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000117
118 LeaveCriticalSection( &csTimer );
Alexandre Julliardef702d81996-05-28 18:54:58 +0000119}
120
121
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000122/***********************************************************************
Ulrich Weiganda9238081999-06-22 19:11:33 +0000123 * TIMER_CheckTimer
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000124 */
Ulrich Weiganda9238081999-06-22 19:11:33 +0000125static void CALLBACK TIMER_CheckTimer( ULONG_PTR timer_ptr )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000126{
Ulrich Weiganda9238081999-06-22 19:11:33 +0000127 TIMER *pTimer = (TIMER *)timer_ptr;
128 HQUEUE16 wakeQueue = 0;
Alexandre Julliard8b915631996-06-16 16:16:05 +0000129
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000130 EnterCriticalSection( &csTimer );
Ulrich Weigand9dcaeca1999-05-02 11:30:39 +0000131
Ulrich Weiganda9238081999-06-22 19:11:33 +0000132 /* Paranoid check to prevent a race condition ... */
133 if ( !pTimer->timeout )
Alexandre Julliard8b915631996-06-16 16:16:05 +0000134 {
Ulrich Weiganda9238081999-06-22 19:11:33 +0000135 LeaveCriticalSection( &csTimer );
136 return;
Alexandre Julliard8b915631996-06-16 16:16:05 +0000137 }
Ulrich Weigand9dcaeca1999-05-02 11:30:39 +0000138
Ulrich Weiganda9238081999-06-22 19:11:33 +0000139 if ( !pTimer->expired )
Ulrich Weigand9dcaeca1999-05-02 11:30:39 +0000140 {
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000141 TRACE("Timer expired: %04x, %04x, %04x, %08lx\n",
Ulrich Weiganda9238081999-06-22 19:11:33 +0000142 pTimer->hwnd, pTimer->msg, pTimer->id, (DWORD)pTimer->proc);
Ulrich Weigand9dcaeca1999-05-02 11:30:39 +0000143
Ulrich Weiganda9238081999-06-22 19:11:33 +0000144 pTimer->expired = TRUE;
145 wakeQueue = pTimer->hq;
Ulrich Weigand9dcaeca1999-05-02 11:30:39 +0000146 }
Ulrich Weigand9dcaeca1999-05-02 11:30:39 +0000147
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000148 LeaveCriticalSection( &csTimer );
Ulrich Weiganda9238081999-06-22 19:11:33 +0000149
150 /* Note: This has to be done outside the csTimer critical section,
151 otherwise we'll get deadlocks. */
152
153 if ( wakeQueue )
154 QUEUE_IncTimerCount( wakeQueue );
Alexandre Julliard8b915631996-06-16 16:16:05 +0000155}
156
157
158/***********************************************************************
159 * TIMER_GetTimerMsg
160 *
161 * Build a message for an expired timer.
162 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000163BOOL TIMER_GetTimerMsg( MSG *msg, HWND hwnd,
164 HQUEUE16 hQueue, BOOL remove )
Alexandre Julliard8b915631996-06-16 16:16:05 +0000165{
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000166 TIMER *pTimer;
Ulrich Weiganda9238081999-06-22 19:11:33 +0000167 int i;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000168
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000169 EnterCriticalSection( &csTimer );
170
Ulrich Weiganda9238081999-06-22 19:11:33 +0000171 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
172 if ( pTimer->timeout != 0 && pTimer->expired
173 && (hwnd? (pTimer->hwnd == hwnd) : (pTimer->hq == hQueue)) )
174 break;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000175
Ulrich Weiganda9238081999-06-22 19:11:33 +0000176 if ( i == NB_TIMERS )
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000177 {
178 LeaveCriticalSection( &csTimer );
179 return FALSE; /* No timer */
180 }
181
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000182 TRACE("Timer got message: %04x, %04x, %04x, %08lx\n",
Alexandre Julliard8b915631996-06-16 16:16:05 +0000183 pTimer->hwnd, pTimer->msg, pTimer->id, (DWORD)pTimer->proc);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000184
Ulrich Weigand9dcaeca1999-05-02 11:30:39 +0000185 if (remove)
Ulrich Weiganda9238081999-06-22 19:11:33 +0000186 pTimer->expired = FALSE;
Ulrich Weigand9dcaeca1999-05-02 11:30:39 +0000187
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000188 /* Build the message */
Stephane Lussierb3a99de1999-02-09 15:35:12 +0000189 msg->hwnd = pTimer->hwnd;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000190 msg->message = pTimer->msg;
Stephane Lussierb3a99de1999-02-09 15:35:12 +0000191 msg->wParam = pTimer->id;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000192 msg->lParam = (LONG)pTimer->proc;
Ulrich Weiganda9238081999-06-22 19:11:33 +0000193 msg->time = GetTickCount();
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000194
195 LeaveCriticalSection( &csTimer );
196
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000197 return TRUE;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000198}
199
200
201/***********************************************************************
202 * TIMER_SetTimer
203 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000204static UINT TIMER_SetTimer( HWND hwnd, UINT id, UINT timeout,
205 WNDPROC16 proc, WINDOWPROCTYPE type, BOOL sys )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000206{
207 int i;
208 TIMER * pTimer;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000209
Uwe Bonnes23cadd31999-09-04 14:32:27 +0000210 if (!timeout)
211 { /* timeout==0 is a legal argument UB 990821*/
212 WARN("Timeout== 0 not implemented, using timeout=1\n");
213 timeout=1;
214 }
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000215 EnterCriticalSection( &csTimer );
216
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000217 /* Check if there's already a timer with the same hwnd and id */
218
Alexandre Julliardaca05781994-10-17 18:12:41 +0000219 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
220 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
221 (pTimer->timeout != 0))
222 {
Ulrich Weiganda9238081999-06-22 19:11:33 +0000223 TIMER_ClearTimer( pTimer );
224 break;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000225 }
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000226
Ulrich Weiganda9238081999-06-22 19:11:33 +0000227 if ( i == NB_TIMERS )
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000228 {
Ulrich Weiganda9238081999-06-22 19:11:33 +0000229 /* Find a free timer */
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000230
Ulrich Weiganda9238081999-06-22 19:11:33 +0000231 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
232 if (!pTimer->timeout) break;
233
234 if ( (i >= NB_TIMERS) ||
235 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) )
236 {
237 LeaveCriticalSection( &csTimer );
238 return 0;
239 }
240 }
241
Alexandre Julliard401710d1993-09-04 10:09:32 +0000242 if (!hwnd) id = i + 1;
243
244 /* Add the timer */
245
246 pTimer->hwnd = hwnd;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000247 pTimer->hq = (hwnd) ? GetThreadQueue16( GetWindowThreadProcessId( hwnd, NULL ) )
248 : GetFastQueue16( );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000249 pTimer->msg = sys ? WM_SYSTIMER : WM_TIMER;
250 pTimer->id = id;
251 pTimer->timeout = timeout;
Alexandre Julliardca22b331996-07-12 19:02:39 +0000252 pTimer->proc = (HWINDOWPROC)0;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000253 if (proc) WINPROC_SetProc( &pTimer->proc, proc, type, WIN_PROC_TIMER );
Ulrich Weiganda9238081999-06-22 19:11:33 +0000254
255 pTimer->expired = FALSE;
Uwe Bonnes23cadd31999-09-04 14:32:27 +0000256 pTimer->hService = SERVICE_AddTimer( MAX( timeout * 1000L, SYS_TIMER_RATE ),
257 TIMER_CheckTimer, (ULONG_PTR)pTimer );
258
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000259 TRACE("Timer added: %p, %04x, %04x, %04x, %08lx\n",
Alexandre Julliardca22b331996-07-12 19:02:39 +0000260 pTimer, pTimer->hwnd, pTimer->msg, pTimer->id,
261 (DWORD)pTimer->proc );
Ulrich Weiganda9238081999-06-22 19:11:33 +0000262
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000263 LeaveCriticalSection( &csTimer );
264
Alexandre Julliardca22b331996-07-12 19:02:39 +0000265 if (!id) return TRUE;
266 else return id;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000267}
268
269
270/***********************************************************************
271 * TIMER_KillTimer
272 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000273static BOOL TIMER_KillTimer( HWND hwnd, UINT id, BOOL sys )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000274{
275 int i;
276 TIMER * pTimer;
277
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000278 EnterCriticalSection( &csTimer );
279
Alexandre Julliardef702d81996-05-28 18:54:58 +0000280 /* Find the timer */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000281
282 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
283 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
284 (pTimer->timeout != 0)) break;
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000285
286 if ( (i >= NB_TIMERS) ||
287 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) ||
288 (!sys && (pTimer->msg != WM_TIMER)) ||
289 (sys && (pTimer->msg != WM_SYSTIMER)) )
290 {
291 LeaveCriticalSection( &csTimer );
292 return FALSE;
293 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000294
Alexandre Julliardef702d81996-05-28 18:54:58 +0000295 /* Delete the timer */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000296
Alexandre Julliardef702d81996-05-28 18:54:58 +0000297 TIMER_ClearTimer( pTimer );
Stephane Lussier35ffc5d1999-03-25 13:23:26 +0000298
299 LeaveCriticalSection( &csTimer );
300
Alexandre Julliard401710d1993-09-04 10:09:32 +0000301 return TRUE;
302}
303
304
305/***********************************************************************
Alexandre Julliardca22b331996-07-12 19:02:39 +0000306 * SetTimer16 (USER.10)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000307 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000308UINT16 WINAPI SetTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
309 TIMERPROC16 proc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000310{
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000311 TRACE("%04x %d %d %08lx\n",
Alexandre Julliardca22b331996-07-12 19:02:39 +0000312 hwnd, id, timeout, (LONG)proc );
313 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc,
314 WIN_PROC_16, FALSE );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000315}
316
317
318/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000319 * SetTimer32 (USER32.511)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000320 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000321UINT WINAPI SetTimer( HWND hwnd, UINT id, UINT timeout,
322 TIMERPROC proc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000323{
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000324 TRACE("%04x %d %d %08lx\n",
Alexandre Julliardca22b331996-07-12 19:02:39 +0000325 hwnd, id, timeout, (LONG)proc );
326 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc,
327 WIN_PROC_32A, FALSE );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000328}
329
330
331/***********************************************************************
Alexandre Julliardca22b331996-07-12 19:02:39 +0000332 * SetSystemTimer16 (USER.11)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000333 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000334UINT16 WINAPI SetSystemTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
335 TIMERPROC16 proc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000336{
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000337 TRACE("%04x %d %d %08lx\n",
Alexandre Julliardca22b331996-07-12 19:02:39 +0000338 hwnd, id, timeout, (LONG)proc );
339 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc,
340 WIN_PROC_16, TRUE );
341}
342
343
344/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000345 * SetSystemTimer32 (USER32.509)
Alexandre Julliardca22b331996-07-12 19:02:39 +0000346 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000347UINT WINAPI SetSystemTimer( HWND hwnd, UINT id, UINT timeout,
348 TIMERPROC proc )
Alexandre Julliardca22b331996-07-12 19:02:39 +0000349{
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000350 TRACE("%04x %d %d %08lx\n",
Alexandre Julliardca22b331996-07-12 19:02:39 +0000351 hwnd, id, timeout, (LONG)proc );
352 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc,
353 WIN_PROC_32A, TRUE );
354}
355
356
357/***********************************************************************
358 * KillTimer16 (USER.12)
359 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000360BOOL16 WINAPI KillTimer16( HWND16 hwnd, UINT16 id )
Alexandre Julliardca22b331996-07-12 19:02:39 +0000361{
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000362 TRACE("%04x %d\n", hwnd, id );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000363 return TIMER_KillTimer( hwnd, id, FALSE );
364}
365
366
367/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000368 * KillTimer32 (USER32.354)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000369 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000370BOOL WINAPI KillTimer( HWND hwnd, UINT id )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000371{
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000372 TRACE("%04x %d\n", hwnd, id );
Alexandre Julliardca22b331996-07-12 19:02:39 +0000373 return TIMER_KillTimer( hwnd, id, FALSE );
374}
375
376
377/***********************************************************************
378 * KillSystemTimer16 (USER.182)
379 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000380BOOL16 WINAPI KillSystemTimer16( HWND16 hwnd, UINT16 id )
Alexandre Julliardca22b331996-07-12 19:02:39 +0000381{
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000382 TRACE("%04x %d\n", hwnd, id );
Alexandre Julliardca22b331996-07-12 19:02:39 +0000383 return TIMER_KillTimer( hwnd, id, TRUE );
384}
385
386
387/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000388 * KillSystemTimer32 (USER32.353)
Alexandre Julliardca22b331996-07-12 19:02:39 +0000389 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000390BOOL WINAPI KillSystemTimer( HWND hwnd, UINT id )
Alexandre Julliardca22b331996-07-12 19:02:39 +0000391{
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000392 TRACE("%04x %d\n", hwnd, id );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000393 return TIMER_KillTimer( hwnd, id, TRUE );
394}