fixed signature of wxTimerProc to be conformant to what Windows expects it to be
[wxWidgets.git] / src / msw / timer.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/timer.cpp
3 // Purpose: wxTimer implementation
4 // Author: Julian Smart
5 // Modified by: Vadim Zeitlin (use hash map instead of list, global rewrite)
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "timer.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #if wxUSE_TIMER
24
25 #ifndef WX_PRECOMP
26 #include "wx/window.h"
27 #include "wx/list.h"
28 #include "wx/event.h"
29 #include "wx/app.h"
30 #include "wx/intl.h"
31 #include "wx/log.h"
32 #endif
33
34 #include "wx/hashmap.h"
35
36 #include "wx/timer.h"
37
38 #include "wx/msw/private.h"
39
40 // ----------------------------------------------------------------------------
41 // private globals
42 // ----------------------------------------------------------------------------
43
44 // define a hash containing all the timers: it is indexed by timer id and
45 // contains the corresponding timer
46 WX_DECLARE_HASH_MAP(unsigned long, wxTimer *, wxIntegerHash, wxIntegerEqual,
47 wxTimerMap);
48
49 static wxTimerMap g_timerMap;
50
51 // ----------------------------------------------------------------------------
52 // private functions
53 // ----------------------------------------------------------------------------
54
55 // timer callback used for all timers
56 void WINAPI wxTimerProc(HWND hwnd, UINT msg, UINT idTimer, DWORD dwTime);
57
58 // ----------------------------------------------------------------------------
59 // macros
60 // ----------------------------------------------------------------------------
61
62 IMPLEMENT_ABSTRACT_CLASS(wxTimer, wxEvtHandler)
63
64 // ============================================================================
65 // implementation
66 // ============================================================================
67
68 // ----------------------------------------------------------------------------
69 // wxTimer class
70 // ----------------------------------------------------------------------------
71
72 void wxTimer::Init()
73 {
74 m_id = 0;
75 }
76
77 wxTimer::~wxTimer()
78 {
79 wxTimer::Stop();
80 }
81
82 bool wxTimer::Start(int milliseconds, bool oneShot)
83 {
84 (void)wxTimerBase::Start(milliseconds, oneShot);
85
86 wxCHECK_MSG( m_milli > 0, false, wxT("invalid value for timer timeour") );
87
88 m_id = ::SetTimer
89 (
90 NULL, // don't use window
91 1, // id ignored with NULL hwnd anyhow
92 (UINT)m_milli, // delay
93 wxTimerProc // timer proc to call
94 );
95
96 if ( !m_id )
97 {
98 wxLogSysError(_("Couldn't create a timer"));
99
100 return false;
101 }
102
103 // check that SetTimer() didn't reuse an existing id: according to the MSDN
104 // this can happen and this would be catastrophic to us as we rely on ids
105 // uniquely identifying the timers because we use them as keys in the hash
106 if ( g_timerMap.find(m_id) != g_timerMap.end() )
107 {
108 wxLogError(_("Timer creation failed."));
109
110 ::KillTimer(NULL, m_id);
111 m_id = 0;
112
113 return false;
114 }
115
116 g_timerMap[m_id] = this;
117
118 return true;
119 }
120
121 void wxTimer::Stop()
122 {
123 if ( m_id )
124 {
125 ::KillTimer(NULL, m_id);
126
127 g_timerMap.erase(m_id);
128 }
129
130 m_id = 0;
131 }
132
133 // ----------------------------------------------------------------------------
134 // private functions
135 // ----------------------------------------------------------------------------
136
137 void wxProcessTimer(wxTimer& timer)
138 {
139 wxASSERT_MSG( timer.m_id != 0, _T("bogus timer id") );
140
141 if ( timer.IsOneShot() )
142 timer.Stop();
143
144 timer.Notify();
145 }
146
147 void WINAPI
148 wxTimerProc(HWND WXUNUSED(hwnd),
149 UINT WXUNUSED(msg),
150 UINT idTimer,
151 DWORD WXUNUSED(dwTime))
152 {
153 wxTimerMap::iterator node = g_timerMap.find(idTimer);
154
155 wxCHECK_RET( node != g_timerMap.end(), wxT("bogus timer id in wxTimerProc") );
156
157 wxProcessTimer(*(node->second));
158 }
159
160 #endif // wxUSE_TIMER
161