+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
+LRESULT APIENTRY _EXPORT wxTimerWndProc(HWND hWnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
+
+// implemented in utils.cpp
+extern "C" WXDLLIMPEXP_BASE HWND
+wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc);
+
+
+// ----------------------------------------------------------------------------
+// wxTimerHiddenWindowModule: used to manage the hidden window used for
+// catching timer messages (we need a module to ensure that the window is
+// always deleted)
+// ----------------------------------------------------------------------------
+
+class wxTimerHiddenWindowModule : public wxModule
+{
+public:
+ // module init/finalize
+ virtual bool OnInit();
+ virtual void OnExit();
+
+ // get the hidden window (creates on demand)
+ static HWND GetHWND();
+
+private:
+ // the HWND of the hidden window
+ static HWND ms_hwnd;
+
+ // the class used to create it
+ static const wxChar *ms_className;
+
+ DECLARE_DYNAMIC_CLASS(wxTimerHiddenWindowModule)
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxTimerHiddenWindowModule, wxModule)
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+
+// ----------------------------------------------------------------------------
+// wxMSWTimerImpl class
+// ----------------------------------------------------------------------------
+
+bool wxMSWTimerImpl::Start(int milliseconds, bool oneShot)
+{
+ if ( !wxTimerImpl::Start(milliseconds, oneShot) )
+ return false;
+
+ m_id = ::SetTimer(
+ wxTimerHiddenWindowModule::GetHWND(), // window to send the messages to
+ GetId(), // timer ID
+ (UINT)m_milli, // delay
+ NULL // timer proc. Not used since we pass hwnd
+ );
+
+ if ( !m_id )
+ {
+ wxLogSysError(_("Couldn't create a timer"));
+
+ return false;
+ }
+
+ // check that SetTimer() didn't reuse an existing id: according to the MSDN
+ // this can happen and this would be catastrophic to us as we rely on ids
+ // uniquely identifying the timers because we use them as keys in the hash
+ if ( TimerMap().find(m_id) != TimerMap().end() )
+ {
+ wxLogError(_("Timer creation failed."));
+
+ ::KillTimer(wxTimerHiddenWindowModule::GetHWND(), m_id);
+ m_id = 0;