]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/treectrl.cpp
use a linked list instead of array for saved messages to fix problems when Dispatch...
[wxWidgets.git] / src / msw / treectrl.cpp
index dcbb70016a71cc106dfdbbcfedad4d08d1714a6e..b7329c5289178ace09ea60d6e6d3b0dc8790acda 100644 (file)
@@ -526,7 +526,7 @@ IMPLEMENT_DYNAMIC_CLASS_XTI(wxTreeCtrl, wxControl,"wx/treectrl.h")
 wxBEGIN_PROPERTIES_TABLE(wxTreeCtrl)
     wxEVENT_PROPERTY( TextUpdated , wxEVT_COMMAND_TEXT_UPDATED , wxCommandEvent )
     wxEVENT_RANGE_PROPERTY( TreeEvent , wxEVT_COMMAND_TREE_BEGIN_DRAG , wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK , wxTreeEvent )
-    wxPROPERTY_FLAGS( WindowStyle , wxTreeCtrlStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
+    wxPROPERTY_FLAGS( WindowStyle , wxTreeCtrlStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
 wxEND_PROPERTIES_TABLE()
 
 wxBEGIN_HANDLERS_TABLE(wxTreeCtrl)
@@ -683,7 +683,7 @@ bool wxTreeCtrl::Create(wxWindow *parent,
 #endif
 
     // Create the tree control.
-    if ( !MSWCreateControl(WC_TREEVIEW, wstyle) )
+    if ( !MSWCreateControl(WC_TREEVIEW, wstyle, pos, size) )
         return false;
 
 #if wxUSE_COMCTL32_SAFELY
@@ -755,8 +755,6 @@ bool wxTreeCtrl::Create(wxWindow *parent,
     }
 #endif // 0
 
-    SetSize(pos.x, pos.y, size.x, size.y);
-
     wxSetCCUnicodeFormat(GetHwnd());
 
     return true;
@@ -888,8 +886,9 @@ void wxTreeCtrl::AssignStateImageList(wxImageList *imageList)
 size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item,
                                     bool recursively) const
 {
-    TraverseCounter counter(this, item, recursively);
+    wxCHECK_MSG( item.IsOk(), 0u, wxT("invalid tree item") );
 
+    TraverseCounter counter(this, item, recursively);
     return counter.GetCount() - 1;
 }
 
@@ -903,7 +902,7 @@ bool wxTreeCtrl::SetBackgroundColour(const wxColour &colour)
     if ( !wxWindowBase::SetBackgroundColour(colour) )
         return false;
 
-    SendMessage(GetHwnd(), TVM_SETBKCOLOR, 0, colour.GetPixel());
+    ::SendMessage(GetHwnd(), TVM_SETBKCOLOR, 0, colour.GetPixel());
 #endif
 
     return true;
@@ -915,7 +914,7 @@ bool wxTreeCtrl::SetForegroundColour(const wxColour &colour)
     if ( !wxWindowBase::SetForegroundColour(colour) )
         return false;
 
-    SendMessage(GetHwnd(), TVM_SETTEXTCOLOR, 0, colour.GetPixel());
+    ::SendMessage(GetHwnd(), TVM_SETTEXTCOLOR, 0, colour.GetPixel());
 #endif
 
     return true;
@@ -927,6 +926,8 @@ bool wxTreeCtrl::SetForegroundColour(const wxColour &colour)
 
 wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), wxT(""), wxT("invalid tree item") );
+
     wxChar buf[512];  // the size is arbitrary...
 
     wxTreeViewItem tvItem(item, TVIF_TEXT);
@@ -943,6 +944,8 @@ wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const
 
 void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text)
 {
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
     if ( IS_VIRTUAL_ROOT(item) )
         return;
 
@@ -958,7 +961,7 @@ void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text)
     HWND hwndEdit = TreeView_GetEditControl(GetHwnd());
     if ( hwndEdit )
     {
-        if ( item == GetSelection() )
+        if ( item == m_idEdited )
         {
             ::SetWindowText(hwndEdit, text);
         }
@@ -1018,6 +1021,8 @@ void wxTreeCtrl::DoSetItemImages(const wxTreeItemId& item,
 int wxTreeCtrl::GetItemImage(const wxTreeItemId& item,
                              wxTreeItemIcon which) const
 {
+    wxCHECK_MSG( item.IsOk(), -1, wxT("invalid tree item") );
+
     if ( (HITEM(item) == TVI_ROOT) && (m_windowStyle & wxTR_HIDE_ROOT) )
     {
         // TODO: Maybe a hidden root can still provide images?
@@ -1057,6 +1062,8 @@ int wxTreeCtrl::GetItemImage(const wxTreeItemId& item,
 void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image,
                               wxTreeItemIcon which)
 {
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
     if ( IS_VIRTUAL_ROOT(item) )
     {
         // TODO: Maybe a hidden root can still store images?
@@ -1129,6 +1136,8 @@ void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image,
 
 wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), NULL, wxT("invalid tree item") );
+
     wxTreeViewItem tvItem(item, TVIF_PARAM);
 
     // Hidden root may have data.
@@ -1154,6 +1163,8 @@ wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
 
 void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
 {
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
     if ( IS_VIRTUAL_ROOT(item) )
     {
         GET_VIRTUAL_ROOT()->SetData(data);
@@ -1213,6 +1224,8 @@ bool wxTreeCtrl::HasIndirectData(const wxTreeItemId& item) const
 
 void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
 {
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
     if ( IS_VIRTUAL_ROOT(item) )
         return;
 
@@ -1223,6 +1236,8 @@ void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
 
 void wxTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold)
 {
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
     if ( IS_VIRTUAL_ROOT(item) )
         return;
 
@@ -1255,28 +1270,33 @@ void wxTreeCtrl::RefreshItem(const wxTreeItemId& item)
 
 wxColour wxTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const
 {
-    wxMapTreeAttr::const_iterator it = m_attrs.find(item.m_pItem);
+    wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") );
 
+    wxMapTreeAttr::const_iterator it = m_attrs.find(item.m_pItem);
     return it == m_attrs.end() ? wxNullColour : it->second->GetTextColour();
 }
 
 wxColour wxTreeCtrl::GetItemBackgroundColour(const wxTreeItemId& item) const
 {
-    wxMapTreeAttr::const_iterator it = m_attrs.find(item.m_pItem);
+    wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") );
 
+    wxMapTreeAttr::const_iterator it = m_attrs.find(item.m_pItem);
     return it == m_attrs.end() ? wxNullColour : it->second->GetBackgroundColour();
 }
 
 wxFont wxTreeCtrl::GetItemFont(const wxTreeItemId& item) const
 {
-    wxMapTreeAttr::const_iterator it = m_attrs.find(item.m_pItem);
+    wxCHECK_MSG( item.IsOk(), wxNullFont, wxT("invalid tree item") );
 
+    wxMapTreeAttr::const_iterator it = m_attrs.find(item.m_pItem);
     return it == m_attrs.end() ? wxNullFont : it->second->GetFont();
 }
 
 void wxTreeCtrl::SetItemTextColour(const wxTreeItemId& item,
                                    const wxColour& col)
 {
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
     wxTreeItemAttr *attr;
     wxMapTreeAttr::iterator it = m_attrs.find(item.m_pItem);
     if ( it == m_attrs.end() )
@@ -1299,6 +1319,8 @@ void wxTreeCtrl::SetItemTextColour(const wxTreeItemId& item,
 void wxTreeCtrl::SetItemBackgroundColour(const wxTreeItemId& item,
                                          const wxColour& col)
 {
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
     wxTreeItemAttr *attr;
     wxMapTreeAttr::iterator it = m_attrs.find(item.m_pItem);
     if ( it == m_attrs.end() )
@@ -1320,6 +1342,8 @@ void wxTreeCtrl::SetItemBackgroundColour(const wxTreeItemId& item,
 
 void wxTreeCtrl::SetItemFont(const wxTreeItemId& item, const wxFont& font)
 {
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
     wxTreeItemAttr *attr;
     wxMapTreeAttr::iterator it = m_attrs.find(item.m_pItem);
     if ( it == m_attrs.end() )
@@ -1345,6 +1369,8 @@ void wxTreeCtrl::SetItemFont(const wxTreeItemId& item, const wxFont& font)
 
 bool wxTreeCtrl::IsVisible(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") );
+
     if ( item == wxTreeItemId(TVI_ROOT) )
     {
         // virtual (hidden) root is never visible
@@ -1374,6 +1400,8 @@ bool wxTreeCtrl::IsVisible(const wxTreeItemId& item) const
 
 bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") );
+
     wxTreeViewItem tvItem(item, TVIF_CHILDREN);
     DoGetItem(&tvItem);
 
@@ -1382,8 +1410,7 @@ bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const
 
 bool wxTreeCtrl::IsExpanded(const wxTreeItemId& item) const
 {
-    // probably not a good idea to put it here
-    //wxASSERT( ItemHasChildren(item) );
+    wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") );
 
     wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_EXPANDED);
     DoGetItem(&tvItem);
@@ -1393,6 +1420,8 @@ bool wxTreeCtrl::IsExpanded(const wxTreeItemId& item) const
 
 bool wxTreeCtrl::IsSelected(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") );
+
     wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_SELECTED);
     DoGetItem(&tvItem);
 
@@ -1401,6 +1430,8 @@ bool wxTreeCtrl::IsSelected(const wxTreeItemId& item) const
 
 bool wxTreeCtrl::IsBold(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") );
+
     wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_BOLD);
     DoGetItem(&tvItem);
 
@@ -1430,6 +1461,8 @@ wxTreeItemId wxTreeCtrl::GetSelection() const
 
 wxTreeItemId wxTreeCtrl::GetItemParent(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+
     HTREEITEM hItem;
 
     if ( IS_VIRTUAL_ROOT(item) )
@@ -1453,6 +1486,8 @@ wxTreeItemId wxTreeCtrl::GetItemParent(const wxTreeItemId& item) const
 wxTreeItemId wxTreeCtrl::GetFirstChild(const wxTreeItemId& item,
                                        wxTreeItemIdValue& cookie) const
 {
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+
     // remember the last child returned in 'cookie'
     cookie = TreeView_GetChild(GetHwnd(), HITEM(item));
 
@@ -1462,8 +1497,14 @@ wxTreeItemId wxTreeCtrl::GetFirstChild(const wxTreeItemId& item,
 wxTreeItemId wxTreeCtrl::GetNextChild(const wxTreeItemId& WXUNUSED(item),
                                       wxTreeItemIdValue& cookie) const
 {
-    wxTreeItemId item(TreeView_GetNextSibling(GetHwnd(),
-                                              HITEM(wxTreeItemId(cookie))));
+    wxTreeItemId fromCookie(cookie);
+
+    HTREEITEM hitem = HITEM(fromCookie);
+
+    hitem = TreeView_GetNextSibling(GetHwnd(), hitem);
+
+    wxTreeItemId item(hitem);
+
     cookie = item.m_pItem;
 
     return item;
@@ -1474,6 +1515,8 @@ wxTreeItemId wxTreeCtrl::GetNextChild(const wxTreeItemId& WXUNUSED(item),
 wxTreeItemId wxTreeCtrl::GetFirstChild(const wxTreeItemId& item,
                                        long& cookie) const
 {
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+
     cookie = (long)TreeView_GetChild(GetHwnd(), HITEM(item));
 
     return wxTreeItemId((void *)cookie);
@@ -1482,11 +1525,14 @@ wxTreeItemId wxTreeCtrl::GetFirstChild(const wxTreeItemId& item,
 wxTreeItemId wxTreeCtrl::GetNextChild(const wxTreeItemId& WXUNUSED(item),
                                       long& cookie) const
 {
-    wxTreeItemId item(TreeView_GetNextSibling
-                      (
-                        GetHwnd(),
-                        HITEM(wxTreeItemId((void *)cookie)
-                      )));
+    wxTreeItemId fromCookie((void *)cookie);
+
+    HTREEITEM hitem = HITEM(fromCookie);
+
+    hitem = TreeView_GetNextSibling(GetHwnd(), hitem);
+
+    wxTreeItemId item(hitem);
+
     cookie = (long)item.m_pItem;
 
     return item;
@@ -1496,6 +1542,8 @@ wxTreeItemId wxTreeCtrl::GetNextChild(const wxTreeItemId& WXUNUSED(item),
 
 wxTreeItemId wxTreeCtrl::GetLastChild(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+
     // can this be done more efficiently?
     wxTreeItemIdValue cookie;
 
@@ -1512,11 +1560,13 @@ wxTreeItemId wxTreeCtrl::GetLastChild(const wxTreeItemId& item) const
 
 wxTreeItemId wxTreeCtrl::GetNextSibling(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
     return wxTreeItemId(TreeView_GetNextSibling(GetHwnd(), HITEM(item)));
 }
 
 wxTreeItemId wxTreeCtrl::GetPrevSibling(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
     return wxTreeItemId(TreeView_GetPrevSibling(GetHwnd(), HITEM(item)));
 }
 
@@ -1527,6 +1577,7 @@ wxTreeItemId wxTreeCtrl::GetFirstVisibleItem() const
 
 wxTreeItemId wxTreeCtrl::GetNextVisible(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
     wxASSERT_MSG( IsVisible(item), wxT("The item you call GetNextVisible() for must be visible itself!"));
 
     return wxTreeItemId(TreeView_GetNextVisible(GetHwnd(), HITEM(item)));
@@ -1534,6 +1585,7 @@ wxTreeItemId wxTreeCtrl::GetNextVisible(const wxTreeItemId& item) const
 
 wxTreeItemId wxTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
     wxASSERT_MSG( IsVisible(item), wxT("The item you call GetPrevVisible() for must be visible itself!"));
 
     return wxTreeItemId(TreeView_GetPrevVisible(GetHwnd(), HITEM(item)));
@@ -1545,6 +1597,8 @@ wxTreeItemId wxTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const
 
 bool wxTreeCtrl::IsItemChecked(const wxTreeItemId& item) const
 {
+    wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") );
+
     // receive the desired information.
     wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
     DoGetItem(&tvItem);
@@ -1555,6 +1609,8 @@ bool wxTreeCtrl::IsItemChecked(const wxTreeItemId& item) const
 
 void wxTreeCtrl::SetItemCheck(const wxTreeItemId& item, bool check)
 {
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
     // receive the desired information.
     wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
 
@@ -1599,7 +1655,7 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent,
     }
 
     UINT mask = 0;
-    if ( !text.IsEmpty() )
+    if ( !text.empty() )
     {
         mask |= TVIF_TEXT;
         tvIns.item.pszText = (wxChar *)text.c_str();  // cast is ok
@@ -1967,6 +2023,8 @@ void wxTreeCtrl::DeleteTextCtrl()
         m_textCtrl->SetHWND(0);
         delete m_textCtrl;
         m_textCtrl = NULL;
+
+        m_idEdited.Unset();
     }
 }
 
@@ -1977,6 +2035,7 @@ wxTextCtrl* wxTreeCtrl::EditLabel(const wxTreeItemId& item,
 
     DeleteTextCtrl();
 
+    m_idEdited = item;
     m_textCtrl = (wxTextCtrl *)textControlClass->CreateObject();
     HWND hWnd = (HWND) TreeView_EditLabel(GetHwnd(), HITEM(item));
 
@@ -2103,6 +2162,8 @@ int wxTreeCtrl::OnCompareItems(const wxTreeItemId& item1,
 
 void wxTreeCtrl::SortChildren(const wxTreeItemId& item)
 {
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
     // rely on the fact that TreeView_SortChildren does the same thing as our
     // default behaviour, i.e. sorts items alphabetically and so call it
     // directly if we're not in derived class (much more efficient!)
@@ -2797,7 +2858,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 
         case TVN_DELETEITEM:
             {
-                // NB: we might process this message using wxWindows event
+                // NB: we might process this message using wxWidgets event
                 //     tables, but due to overhead of wxWin event system we
                 //     prefer to do it here ourself (otherwise deleting a tree
                 //     with many items is just too slow)