1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxTimer implementation
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "timer.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
26 #include "wx/window.h"
34 #include "wx/hashmap.h"
35 #include "wx/module.h"
39 #include "wx/msw/private.h"
43 wxCreateHiddenWindow(LPCTSTR
*pclassname
, LPCTSTR classname
, WNDPROC wndproc
);
45 // ----------------------------------------------------------------------------
47 // ----------------------------------------------------------------------------
49 // define a hash containing all the timers: it is indexed by HWND and timer id
52 wxTimerKey(WXHWND hwnd
, int id
) : m_hwnd(hwnd
), m_id(id
) { }
53 wxTimerKey(HWND hwnd
, int id
) : m_hwnd((WXHWND
)hwnd
), m_id(id
) { }
59 static inline bool operator==(const wxTimerKey
& tk1
, const wxTimerKey
& tk2
)
61 return tk1
.m_hwnd
== tk2
.m_hwnd
&& tk1
.m_id
== tk2
.m_id
;
67 unsigned long operator()(const wxTimerKey
& tk
) const
68 { return (unsigned long)tk
.m_hwnd
+ tk
.m_id
; }
70 wxTimerKeyHash
& operator=(const wxTimerKeyHash
&) { return *this; }
73 struct wxTimerKeyEqual
76 bool operator()(const wxTimerKey
& tk1
, const wxTimerKey
& tk2
) const
77 { return tk1
== tk2
; }
79 wxTimerKeyEqual
& operator=(const wxTimerKeyEqual
&) { return *this; }
82 WX_DECLARE_HASH_MAP(wxTimerKey
, wxTimer
*, wxTimerKeyHash
, wxTimerKeyEqual
,
85 static wxTimerMap g_timerMap
;
87 void WINAPI
wxTimerProc(HWND hwnd
, WORD
, int idTimer
, DWORD
);
89 // ----------------------------------------------------------------------------
91 // ----------------------------------------------------------------------------
93 IMPLEMENT_ABSTRACT_CLASS(wxTimer
, wxObject
)
95 // ----------------------------------------------------------------------------
97 // ----------------------------------------------------------------------------
99 // these variables are for timer shared hwnd management
100 static const wxChar
*wxMSWTIMER_WNDCLASSNAME
= wxT("_wxTimer_Internal_Class");
101 static LPCTSTR s_classnameTimerWnd
= NULL
;
102 static HWND s_hwndTimer
= NULL
;
104 // ----------------------------------------------------------------------------
106 // ----------------------------------------------------------------------------
108 class wxTimerModule
: public wxModule
111 virtual bool OnInit() { return true; }
112 virtual void OnExit()
116 ::DestroyWindow(s_hwndTimer
);
119 if ( !::UnregisterClass(wxMSWTIMER_WNDCLASSNAME
, wxGetInstance()) )
121 wxLogLastError(_T("UnregisterClass(wxTimerClass)"));
124 s_classnameTimerWnd
= NULL
;
129 DECLARE_DYNAMIC_CLASS(wxTimerModule
)
132 // ============================================================================
134 // ============================================================================
136 // ----------------------------------------------------------------------------
138 // ----------------------------------------------------------------------------
151 bool wxTimer
::Start(int milliseconds
, bool oneShot
)
153 (void)wxTimerBase
::Start(milliseconds
, oneShot
);
155 wxCHECK_MSG( m_milli
> 0, false, wxT("invalid value for timer timeour") );
157 // find a window for SetTimer(): it should be a valid HWND owned by this
158 // thread (even if we had a non NULL m_hwnd before, reset it in case the
159 // owner has changed)
162 // first try the owner window
165 wxWindow
*win
= wxDynamicCast(m_owner
, wxWindow
);
168 m_hwnd
= win
->GetHWND();
172 // if not, use a shared hidden window
177 s_hwndTimer
= wxCreateHiddenWindow
179 &s_classnameTimerWnd
,
180 wxMSWTIMER_WNDCLASSNAME
,
186 wxASSERT_MSG( s_hwndTimer
, wxT("can't create a HWND for wxTimer") );
191 m_hwnd
= (WXHWND
)s_hwndTimer
;
198 (UINT
)(m_id ? m_id
: 1),
200 (TIMERPROC
)wxTimerProc
205 wxLogSysError(_("Couldn't create a timer"));
210 g_timerMap
[wxTimerKey(m_hwnd
, m_id
)] = this;
219 ::KillTimer((HWND
)m_hwnd
, (UINT
)m_id
);
222 g_timerMap
.erase(wxTimerKey(m_hwnd
, m_id
));
228 // ----------------------------------------------------------------------------
230 // ----------------------------------------------------------------------------
232 void wxProcessTimer(wxTimer
& timer
)
234 wxASSERT_MSG( timer
.m_id
!= 0, _T("bogus timer id") );
236 if ( timer
.IsOneShot() )
242 void WINAPI
wxTimerProc(HWND hwnd
, WORD
, int idTimer
, DWORD
)
244 wxTimerMap
::iterator node
= g_timerMap
.find(wxTimerKey(hwnd
, idTimer
));
246 wxCHECK_RET( node
!= g_timerMap
.end(), wxT("bogus timer id in wxTimerProc") );
248 wxProcessTimer(*(node
->second
));
251 #endif // wxUSE_TIMER