From: Vadim Zeitlin Date: Tue, 7 Dec 1999 00:09:40 +0000 (+0000) Subject: 1. fixes for DrawRotatedText(), drawing sample extended to show it X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/696e1ea0b7cee1394693a0e507bbf49c9863952b 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 --- diff --git a/include/wx/mimetype.h b/include/wx/mimetype.h index 6182c2b9d6..ca17706d16 100644 --- a/include/wx/mimetype.h +++ b/include/wx/mimetype.h @@ -190,11 +190,10 @@ public: // read in additional file in mime.types format bool ReadMimeTypes(const wxString& filename); - // enumerate all known file types: the caller is responsible for freeing - // both the array and its elements! The previous value of filetypes is lost + // enumerate all known MIME 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 // MIME types inside the program itself (you may also use diff --git a/include/wx/msw/treectrl.h b/include/wx/msw/treectrl.h index 97078b53e4..32c41d8554 100644 --- a/include/wx/msw/treectrl.h +++ b/include/wx/msw/treectrl.h @@ -478,8 +478,15 @@ private: wxTreeItemIndirectData *data); bool HasIndirectData(const wxTreeItemId& item) const; + // the array storing all item ids which have indirect data 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) }; diff --git a/include/wx/treectrl.h b/include/wx/treectrl.h index 20a7bddcae..4c37eb0877 100644 --- a/include/wx/treectrl.h +++ b/include/wx/treectrl.h @@ -33,14 +33,14 @@ static const int wxTREE_HITTEST_NOWHERE = 0x0004; static const int wxTREE_HITTEST_ONITEMBUTTON = 0x0008; // on the bitmap associated with an item. static const int wxTREE_HITTEST_ONITEMICON = 0x0010; - // on the ident associated with an item. -static const int wxTREE_HITTEST_ONITEMIDENT = 0x0020; + // on the indent associated with an item. +static const int wxTREE_HITTEST_ONITEMINDENT = 0x0020; // on the label (string) associated with an item. static const int wxTREE_HITTEST_ONITEMLABEL = 0x0040; // on the right of the label associated with an item. static const int wxTREE_HITTEST_ONITEMRIGHT = 0x0080; // 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. static const int wxTREE_HITTEST_TOLEFT = 0x0200; // on the right of the wxTreeCtrl. diff --git a/samples/console/console.cpp b/samples/console/console.cpp index 0a08f86c14..52fef9185c 100644 --- a/samples/console/console.cpp +++ b/samples/console/console.cpp @@ -31,8 +31,9 @@ //#define TEST_ARRAYS //#define TEST_LOG +#define TEST_MIME //#define TEST_STRINGS -#define TEST_THREADS +//#define TEST_THREADS //#define TEST_TIME //#define TEST_LONGLONG @@ -40,6 +41,48 @@ // implementation // ============================================================================ +// ---------------------------------------------------------------------------- +// MIME types +// ---------------------------------------------------------------------------- + +#ifdef TEST_MIME + +#include + +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 // ---------------------------------------------------------------------------- @@ -647,7 +690,10 @@ int main(int argc, char **argv) #endif // TEST_LOG #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' ) wxLog::AddTraceMask("thread"); @@ -670,6 +716,10 @@ int main(int argc, char **argv) TestDivision(); #endif // TEST_LONGLONG +#ifdef TEST_MIME + TestMimeEnum(); +#endif // TEST_MIME + #ifdef TEST_TIME TestTimeStatic(); TestTimeSet(); diff --git a/samples/drawing/drawing.cpp b/samples/drawing/drawing.cpp index 5054fea5f7..3309863671 100644 --- a/samples/drawing/drawing.cpp +++ b/samples/drawing/drawing.cpp @@ -212,46 +212,46 @@ void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc ) { dc.SetPen( wxPen( "black", width, wxSOLID) ); 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.DrawLine( x+20, y+20, 390, y+20 ); + dc.DrawLine( x+20, y+20, 100, y+20 ); 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.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.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.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.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.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.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.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.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.DrawLine( x+20, y+120, 390, y+120 ); + dc.DrawLine( x+20, y+120, 100, y+120 ); wxPen ud( "black", width, wxUSER_DASH ); wxDash dash1[1]; dash1[0] = 0; 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; 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; 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; 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.DrawRotatedText( "+90 rotated text", 30, 30, 90 ); - dc.DrawRotatedText( "-90 rotated text", 30, 30, -90 ); + wxString text; + 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 ) ); @@ -289,7 +295,6 @@ void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event)) long height; long 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 ); dc.DrawText( text, 110, 80 ); diff --git a/src/common/gdicmn.cpp b/src/common/gdicmn.cpp index d0f6c4199d..6556626804 100644 --- a/src/common/gdicmn.cpp +++ b/src/common/gdicmn.cpp @@ -360,10 +360,17 @@ void wxInitializeStockObjects () // wxFontPool = new XFontPool; #endif - wxNORMAL_FONT = new wxFont (12, wxMODERN, wxNORMAL, wxNORMAL); - wxSMALL_FONT = new wxFont (10, wxSWISS, wxNORMAL, wxNORMAL); - wxITALIC_FONT = new wxFont (12, wxROMAN, wxITALIC, wxNORMAL); - wxSWISS_FONT = new wxFont (12, wxSWISS, wxNORMAL, wxNORMAL); + // why under MSW fonts shouldn't have the standard system size? +#ifdef __WXMSW__ + static const int sizeFont = 10; +#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); wxCYAN_PEN = new wxPen ("CYAN", 1, wxSOLID); diff --git a/src/common/mimetype.cpp b/src/common/mimetype.cpp index 6ffbf1c33a..0100ef9217 100644 --- a/src/common/mimetype.cpp +++ b/src/common/mimetype.cpp @@ -138,7 +138,7 @@ public: wxFileType *GetFileTypeFromExtension(const wxString& ext); wxFileType *GetFileTypeFromMimeType(const wxString& mimeType); - size_t EnumAllFileTypes(wxFileType **filetypes); + size_t EnumAllFileTypes(wxArrayString& mimetypes); // this are NOPs under Windows bool ReadMailcap(const wxString& filename, bool fallback = TRUE) @@ -167,7 +167,7 @@ public : wxFileType *GetFileTypeFromExtension(const wxString& ext); wxFileType *GetFileTypeFromMimeType(const wxString& mimeType); - size_t EnumAllFileTypes(wxFileType **filetypes); + size_t EnumAllFileTypes(wxArrayString& mimetypes); // this are NOPs under MacOS bool ReadMailcap(const wxString& filename, bool fallback = TRUE) { return TRUE; } @@ -354,7 +354,7 @@ public: wxFileType *GetFileTypeFromExtension(const wxString& ext); wxFileType *GetFileTypeFromMimeType(const wxString& mimeType); - size_t EnumAllFileTypes(wxFileType **filetypes); + size_t EnumAllFileTypes(wxArrayString& mimetypes); bool ReadMailcap(const wxString& filename, bool fallback = FALSE); 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(filetypes); + return m_impl->EnumAllFileTypes(mimetypes); } // ============================================================================ @@ -945,12 +943,22 @@ wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType) return NULL; } -size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxFileType **filetypes) +size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes) { // enumerate all keys under 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__ ) @@ -1069,7 +1077,7 @@ wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType) 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 @@ -1762,17 +1770,11 @@ bool wxMimeTypesManagerImpl::ReadMailcap(const wxString& strFileName, return TRUE; } -size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxFileType **filetypes) +size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes) { - size_t count = m_aTypes.GetCount(); - - *filetypes = new wxFileType[count]; - for ( size_t n = 0; n < count; n++ ) - { - (*filetypes)[n].m_impl->Init(this, n); - } + mimetypes = m_aTypes; - return count; + return m_aTypes.GetCount(); } #endif diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index 7031bf7bd9..9b43f56bb7 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -666,7 +666,7 @@ void wxDC::DrawAnyText(const wxString& text, wxCoord x, wxCoord y) : OPAQUE); if ( ::TextOut(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), - text.c_str(), text.length()) != 0 ) + text.c_str(), text.length()) == 0 ) { wxLogLastError("TextOut"); } @@ -684,28 +684,39 @@ void wxDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, 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); } 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; - wxFillLogFont(&lf, &m_font); + if ( ::GetObject(hfont, sizeof(lf), &lf) == 0 ) + { + wxLogLastError("GetObject(hfont)"); + } // GDI wants the angle in tenth of degree long angle10 = (long)(angle * 10); lf.lfEscapement = angle10; lf. lfOrientation = angle10; - HFONT hfont = ::CreateFontIndirect(&lf); + hfont = ::CreateFontIndirect(&lf); if ( !hfont ) { wxLogLastError("CreateFont"); } else { - HFONT hfontOld = ::SelectObject(GetHdc(), hfont); + HFONT hfontOld = (HFONT)::SelectObject(GetHdc(), hfont); DrawAnyText(text, x, y); diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index 3d4eb964bb..3c11d4448f 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -1280,7 +1280,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) if ( m_hasAnyAttr ) { - delete m_attrs.Delete(hdr->iItem); + delete (wxListItemAttr *)m_attrs.Delete(hdr->iItem); } } break; diff --git a/src/msw/thread.cpp b/src/msw/thread.cpp index df5e9a437f..8bb3c99382 100644 --- a/src/msw/thread.cpp +++ b/src/msw/thread.cpp @@ -363,6 +363,12 @@ private: 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 if ( !::TlsSetValue(gs_tlsThisThread, thread) ) { @@ -430,7 +436,7 @@ bool wxThreadInternal::Create(wxThread *thread) typedef unsigned (__stdcall *RtlThreadStart)(void *); m_hThread = (HANDLE)_beginthreadex(NULL, 0, - (RtlThreadStart) + (RtlThreadStart) wxThreadInternal::WinThreadStart, thread, CREATE_SUSPENDED, (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 // 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 static SETPROCESSAFFINITYMASK pfnSetProcessAffinityMask = NULL; @@ -621,7 +627,7 @@ bool wxThread::SetConcurrency(size_t level) return FALSE; } - if ( pfnSetProcessAffinityMask(hProcess, &dwProcMask) == 0 ) + if ( pfnSetProcessAffinityMask(hProcess, dwProcMask) == 0 ) { wxLogLastError(_T("SetProcessAffinityMask")); @@ -714,11 +720,29 @@ wxThreadError wxThread::Delete(ExitCode *pRc) ExitCode rc = 0; // 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(); HANDLE hThread = m_internal->GetHandle(); + // does is still run? if ( IsRunning() ) { if ( IsMain() ) diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 96818dd14d..a350654153 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -183,6 +183,7 @@ private: // wxTreeItemIndirectData. So we have to maintain a list of all items which // have indirect data inside the listctrl itself. // ---------------------------------------------------------------------------- + class wxTreeItemIndirectData { public: @@ -288,6 +289,7 @@ void wxTreeCtrl::Init() m_imageListNormal = NULL; m_imageListState = NULL; m_textCtrl = NULL; + m_hasAnyAttr = FALSE; } bool wxTreeCtrl::Create(wxWindow *parent, @@ -389,6 +391,18 @@ bool wxTreeCtrl::Create(wxWindow *parent, 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(); // delete user data to prevent memory leaks @@ -715,6 +729,53 @@ void wxTreeCtrl::SetItemDropHighlight(const wxTreeItemId& item, bool highlight) 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 // ---------------------------------------------------------------------------- @@ -1354,23 +1415,23 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) switch ( hdr->code ) { 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; - eventType=wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK; + if( tvhti.flags & TVHT_ONITEM ) + { + event.m_item = (WXHTREEITEM) tvhti.hItem; + eventType = wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK; + } } } break; - } case TVN_BEGINDRAG: 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_pointDrag = wxPoint(tv->ptDrag.x, tv->ptDrag.y); - break; } + break; 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_label = info->item.pszText; - break; } + break; case TVN_DELETEITEM: { eventType = wxEVT_COMMAND_TREE_DELETE_ITEM; NM_TREEVIEW *tv = (NM_TREEVIEW *)lParam; - event.m_item = (WXHTREEITEM) tv->itemOld.hItem; - break; + event.m_item = (WXHTREEITEM)tv->itemOld.hItem; + + if ( m_hasAnyAttr ) + { + delete (wxTreeItemAttr *)m_attrs. + Delete((long)tv->itemOld.hItem); + } } + break; case TVN_ENDLABELEDIT: { @@ -1464,8 +1531,8 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) eventType = g_events[expand][ing]; event.m_item = (WXHTREEITEM) tv->itemNew.hItem; - break; } + break; case TVN_KEYDOWN: { @@ -1483,8 +1550,8 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) GetEventHandler()->ProcessEvent(event2); } - break; } + break; case TVN_SELCHANGED: 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_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: return wxControl::MSWOnNotify(idCtrl, lParam, result);