1. wxTextCtrl::SetValue() moves the cursor to the end of text (as in GTK)
2. bug in wxThread::Delete() when the thread hadn't been staretd fixed 3. setting font for radiobox now works immediately (you had to invalidate the window manually, e.g. by covering it with another one, before) 4. added and documented wxConstCast() and wxStaticCast() 5. attempts to make wxFontEnumeraotr::EnumEncodings() work under MSW git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_2_BRANCH@7185 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -2162,6 +2162,18 @@ avoid using {\tt \#ifdef}s when creating bitmaps.
|
|||||||
|
|
||||||
<wx/gdicmn.h>
|
<wx/gdicmn.h>
|
||||||
|
|
||||||
|
\membersection{wxConstCast}\label{wxconstcast}
|
||||||
|
|
||||||
|
\func{}{wxConstCast}{ptr, classname}
|
||||||
|
|
||||||
|
This macro expands into {\tt const\_cast<classname *>(ptr)} if the compiler
|
||||||
|
supports {\it const\_cast} or into an old, C-style cast, otherwise.
|
||||||
|
|
||||||
|
\wxheading{See also}
|
||||||
|
|
||||||
|
\helpref{wxDynamicCast}{wxdynamiccast}\\
|
||||||
|
\helpref{wxStatiicCast}{wxstaticcast}
|
||||||
|
|
||||||
\membersection{WXDEBUG\_NEW}\label{debugnew}
|
\membersection{WXDEBUG\_NEW}\label{debugnew}
|
||||||
|
|
||||||
\func{}{WXDEBUG\_NEW}{arg}
|
\func{}{WXDEBUG\_NEW}{arg}
|
||||||
@@ -2207,7 +2219,9 @@ Example:
|
|||||||
|
|
||||||
\wxheading{See also}
|
\wxheading{See also}
|
||||||
|
|
||||||
\helpref{RTTI overview}{runtimeclassoverview}
|
\helpref{RTTI overview}{runtimeclassoverview}\\
|
||||||
|
\helpref{wxConstCast}{wxconstcast}\\
|
||||||
|
\helpref{wxStatiicCast}{wxstaticcast}
|
||||||
|
|
||||||
\membersection{wxICON}\label{wxiconmacro}
|
\membersection{wxICON}\label{wxiconmacro}
|
||||||
|
|
||||||
@@ -2456,6 +2470,17 @@ is no connection between names used in resources, and the global bitmap data.
|
|||||||
|
|
||||||
Another name for \helpref{wxResourceRegisterBitmapData}{registerbitmapdata}.
|
Another name for \helpref{wxResourceRegisterBitmapData}{registerbitmapdata}.
|
||||||
|
|
||||||
|
\membersection{wxStaticCast}\label{wxstaticcast}
|
||||||
|
|
||||||
|
\func{}{wxStaticCast}{ptr, classname}
|
||||||
|
|
||||||
|
This macro checks that the cast is valid in debug mode (an assert failure will
|
||||||
|
result if {\tt wxDynamicCast(ptr, classname) == NULL}) and then returns the
|
||||||
|
result of executing an equivalent of {\tt static\_cast<classname *>(ptr)}.
|
||||||
|
|
||||||
|
\helpref{wxDynamicCast}{wxdynamiccast}\\
|
||||||
|
\helpref{wxConstCast}{wxconstcast}
|
||||||
|
|
||||||
\section{Log functions}\label{logfunctions}
|
\section{Log functions}\label{logfunctions}
|
||||||
|
|
||||||
These functions provide a variety of logging functions: see \helpref{Log classes overview}{wxlogoverview} for
|
These functions provide a variety of logging functions: see \helpref{Log classes overview}{wxlogoverview} for
|
||||||
|
@@ -321,6 +321,7 @@ WXDLLEXPORT wxWindow* wxFindWinFromHandle(WXHWND hWnd);
|
|||||||
WXDLLEXPORT void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font);
|
WXDLLEXPORT void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font);
|
||||||
WXDLLEXPORT void wxFillLogFont(LOGFONT *logFont, const wxFont *font);
|
WXDLLEXPORT void wxFillLogFont(LOGFONT *logFont, const wxFont *font);
|
||||||
WXDLLEXPORT wxFont wxCreateFontFromLogFont(const LOGFONT *logFont);
|
WXDLLEXPORT wxFont wxCreateFontFromLogFont(const LOGFONT *logFont);
|
||||||
|
WXDLLEXPORT wxFontEncoding wxGetFontEncFromCharSet(int charset);
|
||||||
|
|
||||||
WXDLLEXPORT void wxSliderEvent(WXHWND control, WXWORD wParam, WXWORD pos);
|
WXDLLEXPORT void wxSliderEvent(WXHWND control, WXWORD wParam, WXWORD pos);
|
||||||
WXDLLEXPORT void wxScrollBarEvent(WXHWND hbar, WXWORD wParam, WXWORD pos);
|
WXDLLEXPORT void wxScrollBarEvent(WXHWND hbar, WXWORD wParam, WXWORD pos);
|
||||||
|
@@ -170,6 +170,21 @@ wxObject* WXDLLEXPORT_CTORFN wxConstructorFor##name(void) \
|
|||||||
? (className *)(obj) \
|
? (className *)(obj) \
|
||||||
: (className *)0)
|
: (className *)0)
|
||||||
|
|
||||||
|
#define wxConstCast(obj, className) ((className *)(obj))
|
||||||
|
|
||||||
|
#ifdef __WXDEBUG__
|
||||||
|
inline void wxCheckCast(void *ptr)
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( ptr, _T("wxStaticCast() used incorrectly") );
|
||||||
|
}
|
||||||
|
|
||||||
|
#define wxStaticCast(obj, className) \
|
||||||
|
(wxCheckCast(wxDynamicCast(obj, className)), ((className *)(obj)))
|
||||||
|
|
||||||
|
#else // !Debug
|
||||||
|
#define wxStaticCast(obj, className) ((className *)(obj))
|
||||||
|
#endif // Debug/!Debug
|
||||||
|
|
||||||
// Unfortunately Borland seems to need this include.
|
// Unfortunately Borland seems to need this include.
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
#if wxUSE_IOSTREAMH
|
#if wxUSE_IOSTREAMH
|
||||||
|
@@ -88,6 +88,7 @@ static wxFontEncoding gs_encodings[] =
|
|||||||
wxFONTENCODING_CP1255,
|
wxFONTENCODING_CP1255,
|
||||||
wxFONTENCODING_CP1256,
|
wxFONTENCODING_CP1256,
|
||||||
wxFONTENCODING_CP1257,
|
wxFONTENCODING_CP1257,
|
||||||
|
wxFONTENCODING_CP437,
|
||||||
};
|
};
|
||||||
|
|
||||||
// the descriptions for them
|
// the descriptions for them
|
||||||
@@ -117,6 +118,7 @@ static const wxChar* gs_encodingDescs[] =
|
|||||||
wxTRANSLATE( "Windows Hebrew (CP 1255)" ),
|
wxTRANSLATE( "Windows Hebrew (CP 1255)" ),
|
||||||
wxTRANSLATE( "Windows Arabic (CP 1256)" ),
|
wxTRANSLATE( "Windows Arabic (CP 1256)" ),
|
||||||
wxTRANSLATE( "Windows Baltic (CP 1257)" ),
|
wxTRANSLATE( "Windows Baltic (CP 1257)" ),
|
||||||
|
wxTRANSLATE( "Windows/DOS OEM (CP 437)" ),
|
||||||
};
|
};
|
||||||
|
|
||||||
// and the internal names
|
// and the internal names
|
||||||
@@ -146,6 +148,7 @@ static const wxChar* gs_encodingNames[] =
|
|||||||
wxT( "windows1255" ),
|
wxT( "windows1255" ),
|
||||||
wxT( "windows1256" ),
|
wxT( "windows1256" ),
|
||||||
wxT( "windows1257" ),
|
wxT( "windows1257" ),
|
||||||
|
wxT( "windows437" ),
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -41,15 +41,21 @@
|
|||||||
// private classes
|
// private classes
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// the helper class which calls ::EnumFontFamilies() and whose OnFont() is
|
||||||
|
// called from the callback passed to this function and, in its turn, calls the
|
||||||
|
// appropariate wxFontEnumerator method
|
||||||
class wxFontEnumeratorHelper
|
class wxFontEnumeratorHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxFontEnumeratorHelper(wxFontEnumerator *fontEnum);
|
wxFontEnumeratorHelper(wxFontEnumerator *fontEnum);
|
||||||
|
|
||||||
// control what exactly are we enumerating
|
// control what exactly are we enumerating
|
||||||
|
// we enumerate fonts with given enocding
|
||||||
bool SetEncoding(wxFontEncoding encoding);
|
bool SetEncoding(wxFontEncoding encoding);
|
||||||
void SetFixedOnly(bool fixedOnly)
|
// we enumerate fixed-width fonts
|
||||||
{ m_fixedOnly = fixedOnly; }
|
void SetFixedOnly(bool fixedOnly) { m_fixedOnly = fixedOnly; }
|
||||||
|
// we enumerate the encodings available in this family
|
||||||
|
void SetFamily(const wxString& family);
|
||||||
|
|
||||||
// call to start enumeration
|
// call to start enumeration
|
||||||
void DoEnumerate();
|
void DoEnumerate();
|
||||||
@@ -67,8 +73,17 @@ private:
|
|||||||
// if not empty, enum only the fonts with this facename
|
// if not empty, enum only the fonts with this facename
|
||||||
wxString m_facename;
|
wxString m_facename;
|
||||||
|
|
||||||
|
// if not empty, enum only the fonts in this family
|
||||||
|
wxString m_family;
|
||||||
|
|
||||||
// if TRUE, enum only fixed fonts
|
// if TRUE, enum only fixed fonts
|
||||||
bool m_fixedOnly;
|
bool m_fixedOnly;
|
||||||
|
|
||||||
|
// if TRUE, we enumerate the encodings, not fonts
|
||||||
|
bool m_enumEncodings;
|
||||||
|
|
||||||
|
// the list of charsets we already found while enumerating charsets
|
||||||
|
wxArrayInt m_charsets;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -91,6 +106,13 @@ wxFontEnumeratorHelper::wxFontEnumeratorHelper(wxFontEnumerator *fontEnum)
|
|||||||
m_fontEnum = fontEnum;
|
m_fontEnum = fontEnum;
|
||||||
m_charset = -1;
|
m_charset = -1;
|
||||||
m_fixedOnly = FALSE;
|
m_fixedOnly = FALSE;
|
||||||
|
m_enumEncodings = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxFontEnumeratorHelper::SetFamily(const wxString& family)
|
||||||
|
{
|
||||||
|
m_enumEncodings = TRUE;
|
||||||
|
m_family = family;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxFontEnumeratorHelper::SetEncoding(wxFontEncoding encoding)
|
bool wxFontEnumeratorHelper::SetEncoding(wxFontEncoding encoding)
|
||||||
@@ -147,6 +169,25 @@ void wxFontEnumeratorHelper::DoEnumerate()
|
|||||||
bool wxFontEnumeratorHelper::OnFont(const LPLOGFONT lf,
|
bool wxFontEnumeratorHelper::OnFont(const LPLOGFONT lf,
|
||||||
const LPTEXTMETRIC tm) const
|
const LPTEXTMETRIC tm) const
|
||||||
{
|
{
|
||||||
|
if ( m_enumEncodings )
|
||||||
|
{
|
||||||
|
// is this a new charset?
|
||||||
|
int cs = lf->lfCharSet;
|
||||||
|
if ( m_charsets.Index(cs) == wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
wxConstCast(this, wxFontEnumeratorHelper)->m_charsets.Add(cs);
|
||||||
|
|
||||||
|
wxFontEncoding enc = wxGetFontEncFromCharSet(cs);
|
||||||
|
return m_fontEnum->OnFontEncoding(m_family,
|
||||||
|
wxFontMapper::GetEncodingName(enc));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// continue enumeration
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( m_fixedOnly )
|
if ( m_fixedOnly )
|
||||||
{
|
{
|
||||||
// check that it's a fixed pitch font (there is *no* error here, the
|
// check that it's a fixed pitch font (there is *no* error here, the
|
||||||
@@ -191,7 +232,9 @@ bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
|
|||||||
|
|
||||||
bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
|
bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
|
||||||
{
|
{
|
||||||
wxFAIL_MSG(wxT("TODO"));
|
wxFontEnumeratorHelper fe(this);
|
||||||
|
fe.SetFamily(family);
|
||||||
|
fe.DoEnumerate();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@@ -94,7 +94,7 @@ bool wxNativeEncodingInfo::FromString(const wxString& s)
|
|||||||
wxString wxNativeEncodingInfo::ToString() const
|
wxString wxNativeEncodingInfo::ToString() const
|
||||||
{
|
{
|
||||||
wxString s;
|
wxString s;
|
||||||
|
|
||||||
s << (long)encoding << _T(';') << facename;
|
s << (long)encoding << _T(';') << facename;
|
||||||
if ( charset != ANSI_CHARSET )
|
if ( charset != ANSI_CHARSET )
|
||||||
{
|
{
|
||||||
@@ -173,7 +173,7 @@ bool wxGetNativeFontEncoding(wxFontEncoding encoding,
|
|||||||
}
|
}
|
||||||
|
|
||||||
info->encoding = encoding;
|
info->encoding = encoding;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,6 +198,69 @@ bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxFontEncoding <-> CHARSET_XXX
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxFontEncoding wxGetFontEncFromCharSet(int cs)
|
||||||
|
{
|
||||||
|
wxFontEncoding fontEncoding;
|
||||||
|
|
||||||
|
switch ( cs )
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
// JACS: Silently using ANSI_CHARSET
|
||||||
|
// apparently works for Chinese Windows. Assume it works
|
||||||
|
// for all/most other languages.
|
||||||
|
//wxFAIL_MSG(wxT("unsupported charset"));
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
case ANSI_CHARSET:
|
||||||
|
fontEncoding = wxFONTENCODING_CP1252;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef __WIN32__
|
||||||
|
case EASTEUROPE_CHARSET:
|
||||||
|
fontEncoding = wxFONTENCODING_CP1250;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BALTIC_CHARSET:
|
||||||
|
fontEncoding = wxFONTENCODING_CP1257;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RUSSIAN_CHARSET:
|
||||||
|
fontEncoding = wxFONTENCODING_CP1251;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARABIC_CHARSET:
|
||||||
|
fontEncoding = wxFONTENCODING_CP1256;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GREEK_CHARSET:
|
||||||
|
fontEncoding = wxFONTENCODING_CP1253;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HEBREW_CHARSET:
|
||||||
|
fontEncoding = wxFONTENCODING_CP1255;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TURKISH_CHARSET:
|
||||||
|
fontEncoding = wxFONTENCODING_CP1254;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case THAI_CHARSET:
|
||||||
|
fontEncoding = wxFONTENCODING_CP437;
|
||||||
|
break;
|
||||||
|
#endif // Win32
|
||||||
|
|
||||||
|
case OEM_CHARSET:
|
||||||
|
fontEncoding = wxFONTENCODING_CP437;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fontEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxFont <-> LOGFONT conversion
|
// wxFont <-> LOGFONT conversion
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -410,62 +473,8 @@ wxFont wxCreateFontFromLogFont(const LOGFONT *logFont)
|
|||||||
#endif
|
#endif
|
||||||
int fontPoints = (int) (((72.0*((double)height))/(double) ppInch) + 0.5);
|
int fontPoints = (int) (((72.0*((double)height))/(double) ppInch) + 0.5);
|
||||||
|
|
||||||
wxFontEncoding fontEncoding;
|
|
||||||
switch ( logFont->lfCharSet )
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
// JACS: Silently using ANSI_CHARSET
|
|
||||||
// apparently works for Chinese Windows. Assume it works
|
|
||||||
// for all/most other languages.
|
|
||||||
//wxFAIL_MSG(wxT("unsupported charset"));
|
|
||||||
// fall through
|
|
||||||
|
|
||||||
case ANSI_CHARSET:
|
|
||||||
fontEncoding = wxFONTENCODING_CP1252;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef __WIN32__
|
|
||||||
case EASTEUROPE_CHARSET:
|
|
||||||
fontEncoding = wxFONTENCODING_CP1250;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BALTIC_CHARSET:
|
|
||||||
fontEncoding = wxFONTENCODING_CP1257;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RUSSIAN_CHARSET:
|
|
||||||
fontEncoding = wxFONTENCODING_CP1251;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARABIC_CHARSET:
|
|
||||||
fontEncoding = wxFONTENCODING_CP1256;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GREEK_CHARSET:
|
|
||||||
fontEncoding = wxFONTENCODING_CP1253;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HEBREW_CHARSET:
|
|
||||||
fontEncoding = wxFONTENCODING_CP1255;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TURKISH_CHARSET:
|
|
||||||
fontEncoding = wxFONTENCODING_CP1254;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case THAI_CHARSET:
|
|
||||||
fontEncoding = wxFONTENCODING_CP437;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case OEM_CHARSET:
|
|
||||||
fontEncoding = wxFONTENCODING_CP437;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxFont(fontPoints, fontFamily, fontStyle,
|
return wxFont(fontPoints, fontFamily, fontStyle,
|
||||||
fontWeight, fontUnderline, fontFace,
|
fontWeight, fontUnderline, fontFace,
|
||||||
fontEncoding);
|
wxGetFontEncFromCharSet(logFont->lfCharSet));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -716,11 +716,12 @@ bool wxRadioBox::SetFont(const wxFont& font)
|
|||||||
WXHFONT hfont = wxFont(font).GetResourceHandle();
|
WXHFONT hfont = wxFont(font).GetResourceHandle();
|
||||||
for ( int n = 0; n < m_noItems; n++ )
|
for ( int n = 0; n < m_noItems; n++ )
|
||||||
{
|
{
|
||||||
::SendMessage((HWND)m_radioButtons[n], WM_SETFONT, (WPARAM)hfont, 0L);
|
HWND hwndBtn = (HWND)m_radioButtons[n];
|
||||||
}
|
::SendMessage(hwndBtn, WM_SETFONT, (WPARAM)hfont, 0L);
|
||||||
|
|
||||||
// this is needed because otherwise the buttons are not redrawn correctly
|
// otherwise the buttons are not redrawn correctly
|
||||||
Refresh();
|
::InvalidateRect(hwndBtn, NULL, FALSE /* don't erase bg */);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@@ -422,6 +422,10 @@ void wxTextCtrl::SetValue(const wxString& value)
|
|||||||
|
|
||||||
SetWindowText(GetHwnd(), valueDos.c_str());
|
SetWindowText(GetHwnd(), valueDos.c_str());
|
||||||
|
|
||||||
|
// for compatibility with the GTK and because it is more logical, we
|
||||||
|
// move the cursor to the end of the text after SetValue()
|
||||||
|
SetInsertionPointEnd();
|
||||||
|
|
||||||
AdjustSpaceLimit();
|
AdjustSpaceLimit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -390,31 +390,38 @@ private:
|
|||||||
|
|
||||||
DWORD wxThreadInternal::WinThreadStart(wxThread *thread)
|
DWORD wxThreadInternal::WinThreadStart(wxThread *thread)
|
||||||
{
|
{
|
||||||
// first of all, check whether we hadn't been cancelled already
|
DWORD rc;
|
||||||
|
bool wasCancelled;
|
||||||
|
|
||||||
|
// first of all, check whether we hadn't been cancelled already and don't
|
||||||
|
// start the user code at all then
|
||||||
if ( thread->m_internal->GetState() == STATE_EXITED )
|
if ( thread->m_internal->GetState() == STATE_EXITED )
|
||||||
{
|
{
|
||||||
return (DWORD)-1;
|
rc = (DWORD)-1;
|
||||||
|
wasCancelled = TRUE;
|
||||||
}
|
}
|
||||||
|
else // do run thread
|
||||||
// store the thread object in the TLS
|
|
||||||
if ( !::TlsSetValue(gs_tlsThisThread, thread) )
|
|
||||||
{
|
{
|
||||||
wxLogSysError(_("Can not start thread: error writing TLS."));
|
// store the thread object in the TLS
|
||||||
|
if ( !::TlsSetValue(gs_tlsThisThread, thread) )
|
||||||
|
{
|
||||||
|
wxLogSysError(_("Can not start thread: error writing TLS."));
|
||||||
|
|
||||||
return (DWORD)-1;
|
return (DWORD)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = (DWORD)thread->Entry();
|
||||||
|
|
||||||
|
// enter m_critsect before changing the thread state
|
||||||
|
thread->m_critsect.Enter();
|
||||||
|
wasCancelled = thread->m_internal->GetState() == STATE_CANCELED;
|
||||||
|
thread->m_internal->SetState(STATE_EXITED);
|
||||||
|
thread->m_critsect.Leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD rc = (DWORD)thread->Entry();
|
|
||||||
|
|
||||||
// enter m_critsect before changing the thread state
|
|
||||||
thread->m_critsect.Enter();
|
|
||||||
bool wasCancelled = thread->m_internal->GetState() == STATE_CANCELED;
|
|
||||||
thread->m_internal->SetState(STATE_EXITED);
|
|
||||||
thread->m_critsect.Leave();
|
|
||||||
|
|
||||||
thread->OnExit();
|
thread->OnExit();
|
||||||
|
|
||||||
// if the thread was cancelled (from Delete()), then it the handle is still
|
// if the thread was cancelled (from Delete()), then its handle is still
|
||||||
// needed there
|
// needed there
|
||||||
if ( thread->IsDetached() && !wasCancelled )
|
if ( thread->IsDetached() && !wasCancelled )
|
||||||
{
|
{
|
||||||
@@ -522,7 +529,13 @@ bool wxThreadInternal::Resume()
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_state = STATE_RUNNING;
|
// don't change the state from STATE_EXITED because it's special and means
|
||||||
|
// we are going to terminate without running any user code - if we did it,
|
||||||
|
// the codei n Delete() wouldn't work
|
||||||
|
if ( m_state != STATE_EXITED )
|
||||||
|
{
|
||||||
|
m_state = STATE_RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -753,29 +766,44 @@ wxThreadError wxThread::Delete(ExitCode *pRc)
|
|||||||
|
|
||||||
// Delete() is always safe to call, so consider all possible states
|
// Delete() is always safe to call, so consider all possible states
|
||||||
|
|
||||||
// has the thread started to run?
|
// we might need to resume the thread, but we might also not need to cancel
|
||||||
bool shouldResume = FALSE;
|
// it if it doesn't run yet
|
||||||
|
bool shouldResume = FALSE,
|
||||||
|
shouldCancel = TRUE,
|
||||||
|
isRunning = FALSE;
|
||||||
|
|
||||||
|
// check if the thread already started to run
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(m_critsect);
|
wxCriticalSectionLocker lock(m_critsect);
|
||||||
|
|
||||||
if ( m_internal->GetState() == STATE_NEW )
|
if ( m_internal->GetState() == STATE_NEW )
|
||||||
{
|
{
|
||||||
// WinThreadStart() will see it and terminate immediately
|
// WinThreadStart() will see it and terminate immediately, no need
|
||||||
|
// to cancel the thread - but we still need to resume it to let it
|
||||||
|
// run
|
||||||
m_internal->SetState(STATE_EXITED);
|
m_internal->SetState(STATE_EXITED);
|
||||||
|
|
||||||
shouldResume = TRUE;
|
Resume(); // it knows about STATE_EXITED special case
|
||||||
|
|
||||||
|
shouldCancel = FALSE;
|
||||||
|
isRunning = TRUE;
|
||||||
|
|
||||||
|
// shouldResume is correctly set to FALSE here
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shouldResume = IsPaused();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the thread paused?
|
// resume the thread if it is paused
|
||||||
if ( shouldResume || IsPaused() )
|
if ( shouldResume )
|
||||||
Resume();
|
Resume();
|
||||||
|
|
||||||
HANDLE hThread = m_internal->GetHandle();
|
HANDLE hThread = m_internal->GetHandle();
|
||||||
|
|
||||||
// does is still run?
|
// does is still run?
|
||||||
if ( IsRunning() )
|
if ( isRunning || IsRunning() )
|
||||||
{
|
{
|
||||||
if ( IsMain() )
|
if ( IsMain() )
|
||||||
{
|
{
|
||||||
@@ -788,6 +816,7 @@ wxThreadError wxThread::Delete(ExitCode *pRc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ask the thread to terminate
|
// ask the thread to terminate
|
||||||
|
if ( shouldCancel )
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(m_critsect);
|
wxCriticalSectionLocker lock(m_critsect);
|
||||||
|
|
||||||
@@ -880,7 +909,7 @@ wxThreadError wxThread::Delete(ExitCode *pRc)
|
|||||||
{
|
{
|
||||||
// if the thread exits normally, this is done in WinThreadStart, but in
|
// if the thread exits normally, this is done in WinThreadStart, but in
|
||||||
// this case it would have been too early because
|
// this case it would have been too early because
|
||||||
// MsgWaitForMultipleObject() would fail if the therad handle was
|
// MsgWaitForMultipleObject() would fail if the thread handle was
|
||||||
// closed while we were waiting on it, so we must do it here
|
// closed while we were waiting on it, so we must do it here
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user