1. fixes for DrawRotatedText(), drawing sample extended to show it

2. implemented colour/font support for wxTreeCtrl items
3. corrected a bug in wxListCtrl colour/font support code, the items should
   now be deleted ok
4. SetProcessAffinityMask() correction, wxThread::SetConcurrency() kind of
   works (difficult to test on a UP machine)
5. wxMimeType::EnumAllFileTypes() added, works (somewhat) under MSW
6. made default fonts under MSW 10 points and not 12 - this is the standard
   size


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4849 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
1999-12-07 00:09:40 +00:00
parent c8ce6bccc3
commit 696e1ea0b7
11 changed files with 348 additions and 79 deletions

View File

@@ -190,11 +190,10 @@ public:
// read in additional file in mime.types format // read in additional file in mime.types format
bool ReadMimeTypes(const wxString& filename); bool ReadMimeTypes(const wxString& filename);
// enumerate all known file types: the caller is responsible for freeing // enumerate all known MIME types
// both the array and its elements! The previous value of filetypes is lost
// //
// returns the number of retrieved file types // returns the number of retrieved file types
size_t EnumAllFileTypes(wxFileType **filetypes); size_t EnumAllFileTypes(wxArrayString& mimetypes);
// these functions can be used to provide default values for some of the // these functions can be used to provide default values for some of the
// MIME types inside the program itself (you may also use // MIME types inside the program itself (you may also use

View File

@@ -478,8 +478,15 @@ private:
wxTreeItemIndirectData *data); wxTreeItemIndirectData *data);
bool HasIndirectData(const wxTreeItemId& item) const; bool HasIndirectData(const wxTreeItemId& item) const;
// the array storing all item ids which have indirect data
wxArrayTreeItemIds m_itemsWithIndirectData; wxArrayTreeItemIds m_itemsWithIndirectData;
// the hash storing the items attributes (indexed by items ids)
wxHashTable m_attrs;
// TRUE if the hash above is not empty
bool m_hasAnyAttr;
DECLARE_DYNAMIC_CLASS(wxTreeCtrl) DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
}; };

View File

@@ -33,14 +33,14 @@ static const int wxTREE_HITTEST_NOWHERE = 0x0004;
static const int wxTREE_HITTEST_ONITEMBUTTON = 0x0008; static const int wxTREE_HITTEST_ONITEMBUTTON = 0x0008;
// on the bitmap associated with an item. // on the bitmap associated with an item.
static const int wxTREE_HITTEST_ONITEMICON = 0x0010; static const int wxTREE_HITTEST_ONITEMICON = 0x0010;
// on the ident associated with an item. // on the indent associated with an item.
static const int wxTREE_HITTEST_ONITEMIDENT = 0x0020; static const int wxTREE_HITTEST_ONITEMINDENT = 0x0020;
// on the label (string) associated with an item. // on the label (string) associated with an item.
static const int wxTREE_HITTEST_ONITEMLABEL = 0x0040; static const int wxTREE_HITTEST_ONITEMLABEL = 0x0040;
// on the right of the label associated with an item. // on the right of the label associated with an item.
static const int wxTREE_HITTEST_ONITEMRIGHT = 0x0080; static const int wxTREE_HITTEST_ONITEMRIGHT = 0x0080;
// on the label (string) associated with an item. // on the label (string) associated with an item.
//static const int wxTREE_HITTEST_ONITEMSTATEICON = 0x0100; static const int wxTREE_HITTEST_ONITEMSTATEICON = 0x0100;
// on the left of the wxTreeCtrl. // on the left of the wxTreeCtrl.
static const int wxTREE_HITTEST_TOLEFT = 0x0200; static const int wxTREE_HITTEST_TOLEFT = 0x0200;
// on the right of the wxTreeCtrl. // on the right of the wxTreeCtrl.

View File

@@ -31,8 +31,9 @@
//#define TEST_ARRAYS //#define TEST_ARRAYS
//#define TEST_LOG //#define TEST_LOG
#define TEST_MIME
//#define TEST_STRINGS //#define TEST_STRINGS
#define TEST_THREADS //#define TEST_THREADS
//#define TEST_TIME //#define TEST_TIME
//#define TEST_LONGLONG //#define TEST_LONGLONG
@@ -40,6 +41,48 @@
// implementation // implementation
// ============================================================================ // ============================================================================
// ----------------------------------------------------------------------------
// MIME types
// ----------------------------------------------------------------------------
#ifdef TEST_MIME
#include <wx/mimetype.h>
static void TestMimeEnum()
{
wxMimeTypesManager mimeTM;
wxArrayString mimetypes;
size_t count = mimeTM.EnumAllFileTypes(mimetypes);
printf("*** All %u known filetypes: ***\n", count);
wxArrayString exts;
wxString desc;
for ( size_t n = 0; n < count; n++ )
{
wxFileType *filetype = mimeTM.GetFileTypeFromMimeType(mimetypes[n]);
if ( !filetype )
continue;
filetype->GetDescription(&desc);
filetype->GetExtensions(exts);
wxString extsAll;
for ( size_t e = 0; e < exts.GetCount(); e++ )
{
if ( e > 0 )
extsAll << _T(", ");
extsAll += exts[e];
}
printf("\t%s: %s (%s)\n", mimetypes[n], desc, extsAll);
}
}
#endif // TEST_MIME
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// long long // long long
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -647,7 +690,10 @@ int main(int argc, char **argv)
#endif // TEST_LOG #endif // TEST_LOG
#ifdef TEST_THREADS #ifdef TEST_THREADS
printf("This system has %d CPUs\n", wxThread::GetCPUCount()); int nCPUs = wxThread::GetCPUCount();
printf("This system has %d CPUs\n", nCPUs);
if ( nCPUs != -1 )
wxThread::SetConcurrency(nCPUs);
if ( argc > 1 && argv[1][0] == 't' ) if ( argc > 1 && argv[1][0] == 't' )
wxLog::AddTraceMask("thread"); wxLog::AddTraceMask("thread");
@@ -670,6 +716,10 @@ int main(int argc, char **argv)
TestDivision(); TestDivision();
#endif // TEST_LONGLONG #endif // TEST_LONGLONG
#ifdef TEST_MIME
TestMimeEnum();
#endif // TEST_MIME
#ifdef TEST_TIME #ifdef TEST_TIME
TestTimeStatic(); TestTimeStatic();
TestTimeSet(); TestTimeSet();

View File

@@ -212,46 +212,46 @@ void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc )
{ {
dc.SetPen( wxPen( "black", width, wxSOLID) ); dc.SetPen( wxPen( "black", width, wxSOLID) );
dc.SetBrush( *wxRED_BRUSH ); dc.SetBrush( *wxRED_BRUSH );
dc.DrawRectangle( x+10, y+10, 400, 190 ); dc.DrawRectangle( x+10, y+10, 110, 190 );
dc.SetPen( wxPen( "black", width, wxSOLID) ); dc.SetPen( wxPen( "black", width, wxSOLID) );
dc.DrawLine( x+20, y+20, 390, y+20 ); dc.DrawLine( x+20, y+20, 100, y+20 );
dc.SetPen( wxPen( "black", width, wxDOT) ); dc.SetPen( wxPen( "black", width, wxDOT) );
dc.DrawLine( x+20, y+30, 390, y+30 ); dc.DrawLine( x+20, y+30, 100, y+30 );
dc.SetPen( wxPen( "black", width, wxSHORT_DASH) ); dc.SetPen( wxPen( "black", width, wxSHORT_DASH) );
dc.DrawLine( x+20, y+40, 390, y+40 ); dc.DrawLine( x+20, y+40, 100, y+40 );
dc.SetPen( wxPen( "black", width, wxLONG_DASH) ); dc.SetPen( wxPen( "black", width, wxLONG_DASH) );
dc.DrawLine( x+20, y+50, 390, y+50 ); dc.DrawLine( x+20, y+50, 100, y+50 );
dc.SetPen( wxPen( "black", width, wxDOT_DASH) ); dc.SetPen( wxPen( "black", width, wxDOT_DASH) );
dc.DrawLine( x+20, y+60, 390, y+60 ); dc.DrawLine( x+20, y+60, 100, y+60 );
dc.SetPen( wxPen( "black", width, wxBDIAGONAL_HATCH) ); dc.SetPen( wxPen( "black", width, wxBDIAGONAL_HATCH) );
dc.DrawLine( x+20, y+70, 390, y+70 ); dc.DrawLine( x+20, y+70, 100, y+70 );
dc.SetPen( wxPen( "black", width, wxCROSSDIAG_HATCH) ); dc.SetPen( wxPen( "black", width, wxCROSSDIAG_HATCH) );
dc.DrawLine( x+20, y+80, 390, y+80 ); dc.DrawLine( x+20, y+80, 100, y+80 );
dc.SetPen( wxPen( "black", width, wxFDIAGONAL_HATCH) ); dc.SetPen( wxPen( "black", width, wxFDIAGONAL_HATCH) );
dc.DrawLine( x+20, y+90, 390, y+90 ); dc.DrawLine( x+20, y+90, 100, y+90 );
dc.SetPen( wxPen( "black", width, wxCROSS_HATCH) ); dc.SetPen( wxPen( "black", width, wxCROSS_HATCH) );
dc.DrawLine( x+20, y+100, 390, y+100 ); dc.DrawLine( x+20, y+100, 100, y+100 );
dc.SetPen( wxPen( "black", width, wxHORIZONTAL_HATCH) ); dc.SetPen( wxPen( "black", width, wxHORIZONTAL_HATCH) );
dc.DrawLine( x+20, y+110, 390, y+110 ); dc.DrawLine( x+20, y+110, 100, y+110 );
dc.SetPen( wxPen( "black", width, wxVERTICAL_HATCH) ); dc.SetPen( wxPen( "black", width, wxVERTICAL_HATCH) );
dc.DrawLine( x+20, y+120, 390, y+120 ); dc.DrawLine( x+20, y+120, 100, y+120 );
wxPen ud( "black", width, wxUSER_DASH ); wxPen ud( "black", width, wxUSER_DASH );
wxDash dash1[1]; wxDash dash1[1];
dash1[0] = 0; dash1[0] = 0;
ud.SetDashes( 1, dash1 ); ud.SetDashes( 1, dash1 );
dc.DrawLine( x+20, y+140, 390, y+140 ); dc.DrawLine( x+20, y+140, 100, y+140 );
dash1[0] = 1; dash1[0] = 1;
ud.SetDashes( 1, dash1 ); ud.SetDashes( 1, dash1 );
dc.DrawLine( x+20, y+150, 390, y+150 ); dc.DrawLine( x+20, y+150, 100, y+150 );
dash1[0] = 2; dash1[0] = 2;
ud.SetDashes( 1, dash1 ); ud.SetDashes( 1, dash1 );
dc.DrawLine( x+20, y+160, 390, y+160 ); dc.DrawLine( x+20, y+160, 100, y+160 );
dash1[0] = 0xFF; dash1[0] = 0xFF;
ud.SetDashes( 1, dash1 ); ud.SetDashes( 1, dash1 );
dc.DrawLine( x+20, y+170, 390, y+170 ); dc.DrawLine( x+20, y+170, 100, y+170 );
} }
@@ -278,8 +278,14 @@ void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
dc.DrawText( "This is text", 110, 10 ); dc.DrawText( "This is text", 110, 10 );
dc.DrawRotatedText( "+90 rotated text", 30, 30, 90 ); wxString text;
dc.DrawRotatedText( "-90 rotated text", 30, 30, -90 ); dc. SetBackgroundMode(wxSOLID);
for ( int n = -180; n < 180; n += 30 )
{
text.Printf(" %d rotated text", n);
dc.DrawRotatedText(text , 400, 400, n);
}
dc.SetFont( wxFont( 18, wxSWISS, wxNORMAL, wxNORMAL ) ); dc.SetFont( wxFont( 18, wxSWISS, wxNORMAL, wxNORMAL ) );
@@ -289,7 +295,6 @@ void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
long height; long height;
long descent; long descent;
dc.GetTextExtent( "This is Swiss 18pt text.", &length, &height, &descent ); dc.GetTextExtent( "This is Swiss 18pt text.", &length, &height, &descent );
wxString text;
text.Printf( "Dimensions are length %ld, height %ld, descent %ld", length, height, descent ); text.Printf( "Dimensions are length %ld, height %ld, descent %ld", length, height, descent );
dc.DrawText( text, 110, 80 ); dc.DrawText( text, 110, 80 );

View File

@@ -360,10 +360,17 @@ void wxInitializeStockObjects ()
// wxFontPool = new XFontPool; // wxFontPool = new XFontPool;
#endif #endif
wxNORMAL_FONT = new wxFont (12, wxMODERN, wxNORMAL, wxNORMAL); // why under MSW fonts shouldn't have the standard system size?
wxSMALL_FONT = new wxFont (10, wxSWISS, wxNORMAL, wxNORMAL); #ifdef __WXMSW__
wxITALIC_FONT = new wxFont (12, wxROMAN, wxITALIC, wxNORMAL); static const int sizeFont = 10;
wxSWISS_FONT = new wxFont (12, wxSWISS, wxNORMAL, wxNORMAL); #else
static const int sizeFont = 12;
#endif
wxNORMAL_FONT = new wxFont (sizeFont, wxMODERN, wxNORMAL, wxNORMAL);
wxSMALL_FONT = new wxFont (sizeFont - 2, wxSWISS, wxNORMAL, wxNORMAL);
wxITALIC_FONT = new wxFont (sizeFont, wxROMAN, wxITALIC, wxNORMAL);
wxSWISS_FONT = new wxFont (sizeFont, wxSWISS, wxNORMAL, wxNORMAL);
wxRED_PEN = new wxPen ("RED", 1, wxSOLID); wxRED_PEN = new wxPen ("RED", 1, wxSOLID);
wxCYAN_PEN = new wxPen ("CYAN", 1, wxSOLID); wxCYAN_PEN = new wxPen ("CYAN", 1, wxSOLID);

View File

@@ -138,7 +138,7 @@ public:
wxFileType *GetFileTypeFromExtension(const wxString& ext); wxFileType *GetFileTypeFromExtension(const wxString& ext);
wxFileType *GetFileTypeFromMimeType(const wxString& mimeType); wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
size_t EnumAllFileTypes(wxFileType **filetypes); size_t EnumAllFileTypes(wxArrayString& mimetypes);
// this are NOPs under Windows // this are NOPs under Windows
bool ReadMailcap(const wxString& filename, bool fallback = TRUE) bool ReadMailcap(const wxString& filename, bool fallback = TRUE)
@@ -167,7 +167,7 @@ public :
wxFileType *GetFileTypeFromExtension(const wxString& ext); wxFileType *GetFileTypeFromExtension(const wxString& ext);
wxFileType *GetFileTypeFromMimeType(const wxString& mimeType); wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
size_t EnumAllFileTypes(wxFileType **filetypes); size_t EnumAllFileTypes(wxArrayString& mimetypes);
// this are NOPs under MacOS // this are NOPs under MacOS
bool ReadMailcap(const wxString& filename, bool fallback = TRUE) { return TRUE; } bool ReadMailcap(const wxString& filename, bool fallback = TRUE) { return TRUE; }
@@ -354,7 +354,7 @@ public:
wxFileType *GetFileTypeFromExtension(const wxString& ext); wxFileType *GetFileTypeFromExtension(const wxString& ext);
wxFileType *GetFileTypeFromMimeType(const wxString& mimeType); wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
size_t EnumAllFileTypes(wxFileType **filetypes); size_t EnumAllFileTypes(wxArrayString& mimetypes);
bool ReadMailcap(const wxString& filename, bool fallback = FALSE); bool ReadMailcap(const wxString& filename, bool fallback = FALSE);
bool ReadMimeTypes(const wxString& filename); bool ReadMimeTypes(const wxString& filename);
@@ -654,11 +654,9 @@ void wxMimeTypesManager::AddFallbacks(const wxFileTypeInfo *filetypes)
} }
} }
size_t wxMimeTypesManager::EnumAllFileTypes(wxFileType **filetypes) size_t wxMimeTypesManager::EnumAllFileTypes(wxArrayString& mimetypes)
{ {
wxCHECK_MSG( filetypes, 0u, _T("bad pointer in EnumAllFileTypes") ); return m_impl->EnumAllFileTypes(mimetypes);
return m_impl->EnumAllFileTypes(filetypes);
} }
// ============================================================================ // ============================================================================
@@ -945,12 +943,22 @@ wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
return NULL; return NULL;
} }
size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxFileType **filetypes) size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes)
{ {
// enumerate all keys under MIME_DATABASE_KEY // enumerate all keys under MIME_DATABASE_KEY
wxRegKey key(wxRegKey::HKCR, MIME_DATABASE_KEY); wxRegKey key(wxRegKey::HKCR, MIME_DATABASE_KEY);
return 0; wxString type;
long cookie;
bool cont = key.GetFirstKey(type, cookie);
while ( cont )
{
mimetypes.Add(type);
cont = key.GetNextKey(type, cookie);
}
return mimetypes.GetCount();
} }
#elif defined ( __WXMAC__ ) #elif defined ( __WXMAC__ )
@@ -1069,7 +1077,7 @@ wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
return NULL; return NULL;
} }
size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxFileType **filetypes) size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes)
{ {
wxFAIL_MSG( _T("TODO") ); // VZ: don't know anything about this for Mac wxFAIL_MSG( _T("TODO") ); // VZ: don't know anything about this for Mac
@@ -1762,17 +1770,11 @@ bool wxMimeTypesManagerImpl::ReadMailcap(const wxString& strFileName,
return TRUE; return TRUE;
} }
size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxFileType **filetypes) size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes)
{ {
size_t count = m_aTypes.GetCount(); mimetypes = m_aTypes;
*filetypes = new wxFileType[count]; return m_aTypes.GetCount();
for ( size_t n = 0; n < count; n++ )
{
(*filetypes)[n].m_impl->Init(this, n);
}
return count;
} }
#endif #endif

View File

@@ -666,7 +666,7 @@ void wxDC::DrawAnyText(const wxString& text, wxCoord x, wxCoord y)
: OPAQUE); : OPAQUE);
if ( ::TextOut(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), if ( ::TextOut(GetHdc(), XLOG2DEV(x), YLOG2DEV(y),
text.c_str(), text.length()) != 0 ) text.c_str(), text.length()) == 0 )
{ {
wxLogLastError("TextOut"); wxLogLastError("TextOut");
} }
@@ -684,28 +684,39 @@ void wxDC::DoDrawRotatedText(const wxString& text,
wxCoord x, wxCoord y, wxCoord x, wxCoord y,
double angle) double angle)
{ {
if ( angle == 0.0 ) // we test that we have some font because otherwise we should still use the
// "else" part below to avoid that DrawRotatedText(angle = 180) and
// DrawRotatedText(angle = 0) use different fonts (we can't use the default
// font for drawing rotated fonts unfortunately)
if ( (angle == 0.0) && m_font.Ok() )
{ {
DoDrawText(text, x, y); DoDrawText(text, x, y);
} }
else else
{ {
// NB: don't take DEFAULT_GUI_FONT because it's not TrueType and so
// can't have non zero orientation/escapement
wxFont font = m_font.Ok() ? m_font : *wxNORMAL_FONT;
HFONT hfont = (HFONT)font.GetResourceHandle();
LOGFONT lf; LOGFONT lf;
wxFillLogFont(&lf, &m_font); if ( ::GetObject(hfont, sizeof(lf), &lf) == 0 )
{
wxLogLastError("GetObject(hfont)");
}
// GDI wants the angle in tenth of degree // GDI wants the angle in tenth of degree
long angle10 = (long)(angle * 10); long angle10 = (long)(angle * 10);
lf.lfEscapement = angle10; lf.lfEscapement = angle10;
lf. lfOrientation = angle10; lf. lfOrientation = angle10;
HFONT hfont = ::CreateFontIndirect(&lf); hfont = ::CreateFontIndirect(&lf);
if ( !hfont ) if ( !hfont )
{ {
wxLogLastError("CreateFont"); wxLogLastError("CreateFont");
} }
else else
{ {
HFONT hfontOld = ::SelectObject(GetHdc(), hfont); HFONT hfontOld = (HFONT)::SelectObject(GetHdc(), hfont);
DrawAnyText(text, x, y); DrawAnyText(text, x, y);

View File

@@ -1280,7 +1280,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
if ( m_hasAnyAttr ) if ( m_hasAnyAttr )
{ {
delete m_attrs.Delete(hdr->iItem); delete (wxListItemAttr *)m_attrs.Delete(hdr->iItem);
} }
} }
break; break;

View File

@@ -363,6 +363,12 @@ private:
DWORD wxThreadInternal::WinThreadStart(wxThread *thread) DWORD wxThreadInternal::WinThreadStart(wxThread *thread)
{ {
// first of all, check whether we hadn't been cancelled already
if ( thread->m_internal->GetState() == STATE_EXITED )
{
return (DWORD)-1;
}
// store the thread object in the TLS // store the thread object in the TLS
if ( !::TlsSetValue(gs_tlsThisThread, thread) ) if ( !::TlsSetValue(gs_tlsThisThread, thread) )
{ {
@@ -430,7 +436,7 @@ bool wxThreadInternal::Create(wxThread *thread)
typedef unsigned (__stdcall *RtlThreadStart)(void *); typedef unsigned (__stdcall *RtlThreadStart)(void *);
m_hThread = (HANDLE)_beginthreadex(NULL, 0, m_hThread = (HANDLE)_beginthreadex(NULL, 0,
(RtlThreadStart) (RtlThreadStart)
wxThreadInternal::WinThreadStart, wxThreadInternal::WinThreadStart,
thread, CREATE_SUSPENDED, thread, CREATE_SUSPENDED,
(unsigned int *)&m_tid); (unsigned int *)&m_tid);
@@ -595,7 +601,7 @@ bool wxThread::SetConcurrency(size_t level)
// set it: we can't link to SetProcessAffinityMask() because it doesn't // set it: we can't link to SetProcessAffinityMask() because it doesn't
// exist in Win9x, use RT binding instead // exist in Win9x, use RT binding instead
typedef BOOL (*SETPROCESSAFFINITYMASK)(HANDLE, DWORD *); typedef BOOL (*SETPROCESSAFFINITYMASK)(HANDLE, DWORD);
// can use static var because we're always in the main thread here // can use static var because we're always in the main thread here
static SETPROCESSAFFINITYMASK pfnSetProcessAffinityMask = NULL; static SETPROCESSAFFINITYMASK pfnSetProcessAffinityMask = NULL;
@@ -621,7 +627,7 @@ bool wxThread::SetConcurrency(size_t level)
return FALSE; return FALSE;
} }
if ( pfnSetProcessAffinityMask(hProcess, &dwProcMask) == 0 ) if ( pfnSetProcessAffinityMask(hProcess, dwProcMask) == 0 )
{ {
wxLogLastError(_T("SetProcessAffinityMask")); wxLogLastError(_T("SetProcessAffinityMask"));
@@ -714,11 +720,29 @@ wxThreadError wxThread::Delete(ExitCode *pRc)
ExitCode rc = 0; ExitCode rc = 0;
// Delete() is always safe to call, so consider all possible states // Delete() is always safe to call, so consider all possible states
if ( IsPaused() )
// has the thread started to run?
bool shouldResume = FALSE;
{
wxCriticalSectionLocker lock(m_critsect);
if ( m_internal->GetState() == STATE_NEW )
{
// WinThreadStart() will see it and terminate immediately
m_internal->SetState(STATE_EXITED);
shouldResume = TRUE;
}
}
// is the thread paused?
if ( shouldResume || IsPaused() )
Resume(); Resume();
HANDLE hThread = m_internal->GetHandle(); HANDLE hThread = m_internal->GetHandle();
// does is still run?
if ( IsRunning() ) if ( IsRunning() )
{ {
if ( IsMain() ) if ( IsMain() )

View File

@@ -183,6 +183,7 @@ private:
// wxTreeItemIndirectData. So we have to maintain a list of all items which // wxTreeItemIndirectData. So we have to maintain a list of all items which
// have indirect data inside the listctrl itself. // have indirect data inside the listctrl itself.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class wxTreeItemIndirectData class wxTreeItemIndirectData
{ {
public: public:
@@ -288,6 +289,7 @@ void wxTreeCtrl::Init()
m_imageListNormal = NULL; m_imageListNormal = NULL;
m_imageListState = NULL; m_imageListState = NULL;
m_textCtrl = NULL; m_textCtrl = NULL;
m_hasAnyAttr = FALSE;
} }
bool wxTreeCtrl::Create(wxWindow *parent, bool wxTreeCtrl::Create(wxWindow *parent,
@@ -389,6 +391,18 @@ bool wxTreeCtrl::Create(wxWindow *parent,
wxTreeCtrl::~wxTreeCtrl() wxTreeCtrl::~wxTreeCtrl()
{ {
// delete any attributes
if ( m_hasAnyAttr )
{
for ( wxNode *node = m_attrs.Next(); node; node = m_attrs.Next() )
{
delete (wxTreeItemAttr *)node->Data();
}
// prevent TVN_DELETEITEM handler from deleting the attributes again!
m_hasAnyAttr = FALSE;
}
DeleteTextCtrl(); DeleteTextCtrl();
// delete user data to prevent memory leaks // delete user data to prevent memory leaks
@@ -715,6 +729,53 @@ void wxTreeCtrl::SetItemDropHighlight(const wxTreeItemId& item, bool highlight)
DoSetItem(&tvItem); DoSetItem(&tvItem);
} }
void wxTreeCtrl::SetItemTextColour(const wxTreeItemId& item,
const wxColour& col)
{
m_hasAnyAttr = TRUE;
long id = (long)(WXHTREEITEM)item;
wxTreeItemAttr *attr = (wxTreeItemAttr *)m_attrs.Get(id);
if ( !attr )
{
attr = new wxTreeItemAttr;
m_attrs.Put(id, (wxObject *)attr);
}
attr->SetTextColour(col);
}
void wxTreeCtrl::SetItemBackgroundColour(const wxTreeItemId& item,
const wxColour& col)
{
m_hasAnyAttr = TRUE;
long id = (long)(WXHTREEITEM)item;
wxTreeItemAttr *attr = (wxTreeItemAttr *)m_attrs.Get(id);
if ( !attr )
{
attr = new wxTreeItemAttr;
m_attrs.Put(id, (wxObject *)attr);
}
attr->SetBackgroundColour(col);
}
void wxTreeCtrl::SetItemFont(const wxTreeItemId& item, const wxFont& font)
{
m_hasAnyAttr = TRUE;
long id = (long)(WXHTREEITEM)item;
wxTreeItemAttr *attr = (wxTreeItemAttr *)m_attrs.Get(id);
if ( !attr )
{
attr = new wxTreeItemAttr;
m_attrs.Put(id, (wxObject *)attr);
}
attr->SetFont(font);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Item status // Item status
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1354,23 +1415,23 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
switch ( hdr->code ) switch ( hdr->code )
{ {
case NM_RCLICK: case NM_RCLICK:
{
if ( wxControl::MSWOnNotify(idCtrl, lParam, result) )
return TRUE;
TV_HITTESTINFO tvhti;
::GetCursorPos(&(tvhti.pt));
::ScreenToClient(GetHwnd(),&(tvhti.pt));
if ( TreeView_HitTest(GetHwnd(),&tvhti) )
{ {
if( tvhti.flags & TVHT_ONITEM ) if ( wxControl::MSWOnNotify(idCtrl, lParam, result) )
return TRUE;
TV_HITTESTINFO tvhti;
::GetCursorPos(&(tvhti.pt));
::ScreenToClient(GetHwnd(),&(tvhti.pt));
if ( TreeView_HitTest(GetHwnd(),&tvhti) )
{ {
event.m_item = (WXHTREEITEM) tvhti.hItem; if( tvhti.flags & TVHT_ONITEM )
eventType=wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK; {
event.m_item = (WXHTREEITEM) tvhti.hItem;
eventType = wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK;
}
} }
} }
break; break;
}
case TVN_BEGINDRAG: case TVN_BEGINDRAG:
eventType = wxEVT_COMMAND_TREE_BEGIN_DRAG; eventType = wxEVT_COMMAND_TREE_BEGIN_DRAG;
@@ -1386,8 +1447,8 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
event.m_item = (WXHTREEITEM) tv->itemNew.hItem; event.m_item = (WXHTREEITEM) tv->itemNew.hItem;
event.m_pointDrag = wxPoint(tv->ptDrag.x, tv->ptDrag.y); event.m_pointDrag = wxPoint(tv->ptDrag.x, tv->ptDrag.y);
break;
} }
break;
case TVN_BEGINLABELEDIT: case TVN_BEGINLABELEDIT:
{ {
@@ -1396,17 +1457,23 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
event.m_item = (WXHTREEITEM) info->item.hItem; event.m_item = (WXHTREEITEM) info->item.hItem;
event.m_label = info->item.pszText; event.m_label = info->item.pszText;
break;
} }
break;
case TVN_DELETEITEM: case TVN_DELETEITEM:
{ {
eventType = wxEVT_COMMAND_TREE_DELETE_ITEM; eventType = wxEVT_COMMAND_TREE_DELETE_ITEM;
NM_TREEVIEW *tv = (NM_TREEVIEW *)lParam; NM_TREEVIEW *tv = (NM_TREEVIEW *)lParam;
event.m_item = (WXHTREEITEM) tv->itemOld.hItem; event.m_item = (WXHTREEITEM)tv->itemOld.hItem;
break;
if ( m_hasAnyAttr )
{
delete (wxTreeItemAttr *)m_attrs.
Delete((long)tv->itemOld.hItem);
}
} }
break;
case TVN_ENDLABELEDIT: case TVN_ENDLABELEDIT:
{ {
@@ -1464,8 +1531,8 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
eventType = g_events[expand][ing]; eventType = g_events[expand][ing];
event.m_item = (WXHTREEITEM) tv->itemNew.hItem; event.m_item = (WXHTREEITEM) tv->itemNew.hItem;
break;
} }
break;
case TVN_KEYDOWN: case TVN_KEYDOWN:
{ {
@@ -1483,8 +1550,8 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
GetEventHandler()->ProcessEvent(event2); GetEventHandler()->ProcessEvent(event2);
} }
break;
} }
break;
case TVN_SELCHANGED: case TVN_SELCHANGED:
eventType = wxEVT_COMMAND_TREE_SEL_CHANGED; eventType = wxEVT_COMMAND_TREE_SEL_CHANGED;
@@ -1500,8 +1567,105 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
event.m_item = (WXHTREEITEM) tv->itemNew.hItem; event.m_item = (WXHTREEITEM) tv->itemNew.hItem;
event.m_itemOld = (WXHTREEITEM) tv->itemOld.hItem; event.m_itemOld = (WXHTREEITEM) tv->itemOld.hItem;
break;
} }
break;
#ifdef NM_CUSTOMDRAW
case NM_CUSTOMDRAW:
{
LPNMTVCUSTOMDRAW lptvcd = (LPNMTVCUSTOMDRAW)lParam;
NMCUSTOMDRAW& nmcd = lptvcd->nmcd;
switch( nmcd.dwDrawStage )
{
case CDDS_PREPAINT:
// if we've got any items with non standard attributes,
// notify us before painting each item
*result = m_hasAnyAttr ? CDRF_NOTIFYITEMDRAW
: CDRF_DODEFAULT;
return TRUE;
case CDDS_ITEMPREPAINT:
{
wxTreeItemAttr *attr =
(wxTreeItemAttr *)m_attrs.Get(nmcd.dwItemSpec);
if ( !attr )
{
// nothing to do for this item
return CDRF_DODEFAULT;
}
HFONT hFont;
wxColour colText, colBack;
if ( attr->HasFont() )
{
wxFont font = attr->GetFont();
hFont = (HFONT)font.GetResourceHandle();
}
else
{
hFont = 0;
}
if ( attr->HasTextColour() )
{
colText = attr->GetTextColour();
}
else
{
colText = GetForegroundColour();
}
// selection colours should override ours
if ( nmcd.uItemState & CDIS_SELECTED )
{
DWORD clrBk = ::GetSysColor(COLOR_HIGHLIGHT);
lptvcd->clrTextBk = clrBk;
// try to make the text visible
lptvcd->clrText = wxColourToRGB(colText);
lptvcd->clrText |= ~clrBk;
lptvcd->clrText &= 0x00ffffff;
}
else
{
if ( attr->HasBackgroundColour() )
{
colBack = attr->GetBackgroundColour();
}
else
{
colBack = GetBackgroundColour();
}
lptvcd->clrText = wxColourToRGB(colText);
lptvcd->clrTextBk = wxColourToRGB(colBack);
}
// note that if we wanted to set colours for
// individual columns (subitems), we would have
// returned CDRF_NOTIFYSUBITEMREDRAW from here
if ( hFont )
{
::SelectObject(nmcd.hdc, hFont);
*result = CDRF_NEWFONT;
}
else
{
*result = CDRF_DODEFAULT;
}
return TRUE;
}
default:
*result = CDRF_DODEFAULT;
return TRUE;
}
}
break;
#endif // NM_CUSTOMDRAW
default: default:
return wxControl::MSWOnNotify(idCtrl, lParam, result); return wxControl::MSWOnNotify(idCtrl, lParam, result);