refactored code to create hidden window in one place only; use it from wxTimer; unregister class used by wxExecute (modified patch 782947)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23868 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2003-09-23 23:57:32 +00:00
parent 007bea23c3
commit eccd199223
6 changed files with 213 additions and 91 deletions

View File

@@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
// Name: timer.cpp
// Name: msw/timer.cpp
// Purpose: wxTimer implementation
// Author: Julian Smart
// Modified by:
@@ -32,11 +32,16 @@
#endif
#include "wx/hashmap.h"
#include "wx/module.h"
#include "wx/timer.h"
#include "wx/msw/private.h"
// from utils.cpp
extern "C" HWND
wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc);
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
@@ -55,13 +60,45 @@ void WINAPI wxTimerProc(HWND hwnd, WORD, int idTimer, DWORD);
// macros
// ----------------------------------------------------------------------------
// should probably be in wx/msw/missing.h
#ifdef __WXMICROWIN__
#define MakeProcInstance(proc, hinst) proc
#endif
IMPLEMENT_ABSTRACT_CLASS(wxTimer, wxObject)
// ----------------------------------------------------------------------------
// globals
// ----------------------------------------------------------------------------
// these variables are for timer shared hwnd management
static const wxChar *wxMSWTIMER_WNDCLASSNAME = wxT("_wxTimer_Internal_Class");
static LPCTSTR s_classnameTimerWnd = NULL;
static HWND s_hwndTimer = NULL;
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
class wxTimerModule : public wxModule
{
public:
virtual bool OnInit() { return true; }
virtual void OnExit()
{
if ( s_hwndTimer )
{
::DestroyWindow(s_hwndTimer);
s_hwndTimer = NULL;
if ( !::UnregisterClass(wxMSWTIMER_WNDCLASSNAME, wxGetInstance()) )
{
wxLogLastError(_T("UnregisterClass(wxTimerClass)"));
}
s_classnameTimerWnd = NULL;
}
}
private:
DECLARE_DYNAMIC_CLASS(wxTimerModule)
};
// ============================================================================
// implementation
// ============================================================================
@@ -73,10 +110,12 @@ IMPLEMENT_ABSTRACT_CLASS(wxTimer, wxObject)
void wxTimer::Init()
{
m_id = 0;
m_hwnd = NULL;
}
wxTimer::~wxTimer()
{
// save id as Stop() changes it
long id = m_id;
wxTimer::Stop();
@@ -86,40 +125,74 @@ wxTimer::~wxTimer()
bool wxTimer::Start(int milliseconds, bool oneShot)
{
(void)wxTimerBase::Start(milliseconds, oneShot);
wxCHECK_MSG( m_milli > 0, false, wxT("invalid value for timer timeour") );
#ifdef __WXWINCE__
m_id = ::SetTimer(NULL, (UINT)(m_id ? m_id : 1),
(UINT)m_milli, (TIMERPROC) wxTimerProc);
#else
TIMERPROC wxTimerProcInst = (TIMERPROC)
MakeProcInstance((FARPROC)wxTimerProc, wxGetInstance());
(void)wxTimerBase::Start(milliseconds, oneShot);
m_id = ::SetTimer(NULL, (UINT)(m_id ? m_id : 1),
(UINT)m_milli, wxTimerProcInst);
#endif
// find a window for SetTimer(): it should be a valid HWND owned by this
// thread (even if we had a non NULL m_hwnd before, reset it in case the
// owner has changed)
m_hwnd = NULL;
if ( m_id > 0 )
// first try the owner window
if ( m_owner )
{
wxTimerList[m_id] = this;
return true;
wxWindow *win = wxDynamicCast(m_owner, wxWindow);
if ( win )
{
m_hwnd = win->GetHWND();
}
}
else
// if not, use a shared hidden window
if ( !m_hwnd )
{
if ( !s_hwndTimer )
{
s_hwndTimer = wxCreateHiddenWindow
(
&s_classnameTimerWnd,
wxMSWTIMER_WNDCLASSNAME,
::DefWindowProc
);
if ( !s_hwndTimer )
{
wxASSERT_MSG( s_hwndTimer, wxT("can't create a HWND for wxTimer") );
return false;
}
}
m_hwnd = (WXHWND)s_hwndTimer;
}
m_id = ::SetTimer
(
(HWND)m_hwnd,
(UINT)(m_id ? m_id : 1),
(UINT)m_milli,
(TIMERPROC)wxTimerProc
);
if ( !m_id )
{
wxLogSysError(_("Couldn't create a timer"));
return false;
}
wxTimerList[m_id] = this;
return true;
}
void wxTimer::Stop()
{
if ( m_id )
{
::KillTimer(NULL, (UINT)m_id);
::KillTimer((HWND)m_hwnd, (UINT)m_id);
m_hwnd = NULL;
wxTimerList.erase(m_id);
}
@@ -145,7 +218,6 @@ void wxProcessTimer(wxTimer& timer)
void WINAPI wxTimerProc(HWND WXUNUSED(hwnd), WORD, int idTimer, DWORD)
{
wxTimerMap::iterator node = wxTimerList.find((long)idTimer);
wxASSERT_MSG( node != wxTimerList.end(), wxT("bogus timer id in wxTimerProc") );