]> git.saurik.com Git - wxWidgets.git/blob - src/msw/timer.cpp
Fixed wxPropertyGridPage::DoSetSplitterPosition() infinite recursion
[wxWidgets.git] / src / msw / timer.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/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 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16     #pragma hdrstop
17 #endif
18
19 #if wxUSE_TIMER
20
21 #include "wx/msw/private/timer.h"
22
23 #ifndef WX_PRECOMP
24     #include "wx/list.h"
25     #include "wx/event.h"
26     #include "wx/app.h"
27     #include "wx/intl.h"
28     #include "wx/log.h"
29     #include "wx/hashmap.h"
30 #endif
31
32 #include "wx/msw/private.h"
33
34 // ----------------------------------------------------------------------------
35 // private globals
36 // ----------------------------------------------------------------------------
37
38 // define a hash containing all the timers: it is indexed by timer id and
39 // contains the corresponding timer
40 WX_DECLARE_HASH_MAP(unsigned long, wxMSWTimerImpl *, wxIntegerHash, wxIntegerEqual,
41                     wxTimerMap);
42
43 // instead of using a global here, wrap it in a static function as otherwise it
44 // could have been used before being initialized if a timer object were created
45 // globally
46 static wxTimerMap& TimerMap()
47 {
48     static wxTimerMap s_timerMap;
49
50     return s_timerMap;
51 }
52
53 // ----------------------------------------------------------------------------
54 // private functions
55 // ----------------------------------------------------------------------------
56
57 // timer callback used for all timers
58 void WINAPI wxTimerProc(HWND hwnd, UINT msg, UINT_PTR idTimer, DWORD dwTime);
59
60 // ============================================================================
61 // implementation
62 // ============================================================================
63
64 // ----------------------------------------------------------------------------
65 // wxMSWTimerImpl class
66 // ----------------------------------------------------------------------------
67
68 bool wxMSWTimerImpl::Start(int milliseconds, bool oneShot)
69 {
70     if ( !wxTimerImpl::Start(milliseconds, oneShot) )
71         return false;
72
73     m_id = ::SetTimer
74              (
75                 NULL,                       // don't use window
76                 1,                          // id ignored with NULL hwnd anyhow
77                 (UINT)m_milli,              // delay
78                 wxTimerProc                 // timer proc to call
79              );
80
81     if ( !m_id )
82     {
83         wxLogSysError(_("Couldn't create a timer"));
84
85         return false;
86     }
87
88     // check that SetTimer() didn't reuse an existing id: according to the MSDN
89     // this can happen and this would be catastrophic to us as we rely on ids
90     // uniquely identifying the timers because we use them as keys in the hash
91     if ( TimerMap().find(m_id) != TimerMap().end() )
92     {
93         wxLogError(_("Timer creation failed."));
94
95         ::KillTimer(NULL, m_id);
96         m_id = 0;
97
98         return false;
99     }
100
101     TimerMap()[m_id] = this;
102
103     return true;
104 }
105
106 void wxMSWTimerImpl::Stop()
107 {
108     wxASSERT_MSG( m_id, _T("should be running") );
109
110     ::KillTimer(NULL, m_id);
111
112     TimerMap().erase(m_id);
113
114     m_id = 0;
115 }
116
117 // ----------------------------------------------------------------------------
118 // private functions
119 // ----------------------------------------------------------------------------
120
121 void wxProcessTimer(wxMSWTimerImpl& timer)
122 {
123     wxASSERT_MSG( timer.IsRunning(), _T("bogus timer id") );
124
125     if ( timer.IsOneShot() )
126         timer.Stop();
127
128     timer.Notify();
129 }
130
131 void WINAPI
132 wxTimerProc(HWND WXUNUSED(hwnd),
133             UINT WXUNUSED(msg),
134             UINT_PTR idTimer,
135             DWORD WXUNUSED(dwTime))
136 {
137     wxTimerMap::iterator node = TimerMap().find((unsigned long)idTimer);
138
139     wxCHECK_RET( node != TimerMap().end(), wxT("bogus timer id in wxTimerProc") );
140
141     wxProcessTimer(*(node->second));
142 }
143
144 #endif // wxUSE_TIMER