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:
@@ -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") );
|
||||
|
Reference in New Issue
Block a user