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:
Vadim Zeitlin
2000-04-16 23:58:50 +00:00
parent 831026c188
commit 59d3027c0c
9 changed files with 220 additions and 90 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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" ),
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -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;
} }

View File

@@ -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));
} }

View File

@@ -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;
} }

View File

@@ -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();
} }
} }

View File

@@ -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;
} }