Page 1 of 1

Issues with Enhanced wxTreeListCtrl

Posted: Sat Jun 07, 2008 5:59 am
by metalogic
First of all, thanks a lot Guru for this enhancement.

I'm looking to build upon what you have done and enhance it further. Hopefully you will be interested in collaborating so that we can have a single "enhanced" version. But that will come later, I'm just beginning to do some proof-of-concept.

As I've started playing with this control I've found a few issues. Here is the first batch:

When adding columns using AddColumn, the first column added ends up being last rather than first. The problem appears to be lines 2276-2277. They are not needed and removing them fixes the problem.

When the text is too wide to fit in a column, ellipsis appear but they truncate the string leaving only the first character rather than fitting as much text as possible before the ellipsis. You can see that in your demo by simply shrinking one of the columns just enough so that the last letter doesn't fit.

Posted: Wed Jun 25, 2008 2:56 pm
by jmason1182
OKay, now it's been a few years since this post was continued. But I am experiencing the same issues with this control as they were in 2004....

I need to get the checkbox to show up in column one... so I changed from an original version to the new version so I can use the new features.

Now, I get HDS_HOTTRACK not declared... so i do as mentioned and added the following:

#ifdef __WXMSW__
#define _WIN32_IE 0x0600
#include <commctrl.h>

Now it sees HDS_HOTTRACK. But now wxGetInstance isn't declared in scope.

Also, I have a number of errors/warnings I'm trying to sift through. I need this to work, so any assistance is appreciated! I'll post updated code once I get this debugged.

warning: int format, float arg (arg 3)
warning: converting to `long int' from `float'
warning: int format, long int arg (arg 2)
warning: int format, float arg (arg 3)
warning: cannot pass objects of non-POD type `class wxString' through `...'; call will abort at runtime

error: `wxGetInstance' was not declared in this scope
warning: unused variable 'bDontFall'
warning: unused variable 'colInfo'
warning: `BeginDrawing' is deprecated (declared at C:/wx/wxWidgets2.8/include/wx/dc.h:392)
warning: `EndDrawing' is deprecated (declared at C:/wx/wxWidgets2.8/include/wx/dc.h:393)
warning: comparison between signed and unsigned integer expressions
warning: comparison between signed and unsigned integer expressions|

error: `wxValidator::wxValidator(const wxValidator&)' is private
error: invalid conversion from `int' to `wxTreeListItemType'

||=== Build finished: 4 errors, 12 warnings ===|

Posted: Wed Jun 25, 2008 3:00 pm
by jmason1182
First off, I found a post ( that said wxGetInstance is in an undocumented header (and undocumented function)

Code: Select all

ifdef __WXMSW__
     #nclude "wx/msw/private.h"
So that takes care of 1 error.

Posted: Wed Jun 25, 2008 3:02 pm
by jmason1182
Second error is the validator private error...

Thanks to phlox81, I just altered the treelistctrl.cpp file with this:

Code: Select all

class wxEditLongValidator : public wxValidator
     long *val;
     wxEditLongValidator(long* val);
     wxEditLongValidator(const  wxEditLongValidator& copy):val(val){};
     wxObject* Clone() const;
     bool TransferFromWindow();
     bool TransferToWindow();
     bool Validate(wxWindow* parent);
Now no error there.

Next is a conversion from int to wxTreeListItemType....

Posted: Wed Jun 25, 2008 3:10 pm
by jmason1182
And I figured that the intent was to return a wxTreeListItemType that made sense for an incomplete item... which tells me that the 0 needs to be a blank wxTreeListItemType(). ( I could be wrong... guru would know)

This took care of the invalid cast error:

Code: Select all

wxCHECK_MSG (itemId.IsOk(), wxTreeListItemType(), _T("invalid tree item") );
But now that all the errors are gone, I now have an undefined reference:
5916|undefined reference to `wxTreeListMainWindow::SetItemChecked(wxTreeItemId const&, int, bool)'|

SO now to track this one down....

Posted: Wed Jun 25, 2008 3:30 pm
by jmason1182
I changed the format strings of some sscanf's and some wxString::Format from %d to %ld and changed the float t to a long int t to get rid of the
warning: int format, float arg (arg 3)
warning: converting to `long int' from `float'
warning: int format, long int arg (arg 2)
warning: int format, float arg (arg 3)
Next, I looked up BeginDrawing and EndDrawing... not only deprecated, but empty. So I just commented them out.

Now I have only 2 errors and no warnings left.

5918|undefined reference to `wxTreeListMainWindow::SetItemChecked(wxTreeItemId const&, int, bool)'
5923|undefined reference to `wxTreeListMainWindow::GetItemChecked(wxTreeItemId const&, int)'

So here goes....

Posted: Wed Jun 25, 2008 3:38 pm
by jmason1182
And plain and simply the functions were defined, but not implemented.

SO I added them... they are simple -

Code: Select all

void wxTreeListMainWindow::SetItemChecked (const wxTreeItemId& itemId, const int column, bool checked)
    wxCHECK_RET (itemId.IsOk(), _T("invalid tree item"));
    wxClientDC dc (this);
    wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
    item->SetItemChecked(column, checked);
    CalculateSize (item, dc);
    RefreshLine (item);

bool wxTreeListMainWindow::GetItemChecked (const wxTreeItemId& itemId, const int column)
    wxCHECK_MSG (itemId.IsOk(), false, _T("invalid tree item") );
    wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
    return item->GetItemChecked(column);
And now it works... or at least it builds and now I'll post again in a bit after testing the functionality of it.

Re: Issues with Enhanced wxTreeListCtrl

Posted: Thu Jun 26, 2008 6:47 am
by metalogic
metalogic wrote:When the text is too wide to fit in a column, ellipsis appear but they truncate the string leaving only the first character rather than fitting as much text as possible before the ellipsis.
I got to the bottom of this one.

Line 4128:

Code: Select all

text = MakeShortString(dc,text,col_w-x,0);
Should simply be:

Code: Select all

text = MakeShortString(dc,text,col_w,0);
BTW, guru, if you are around, please chime in or send me a PM. I would like to collaborate if you are interested. If you are not interested I guess I'll do a fork but I'd rather enhance the same control.


Re: Issues with Enhanced wxTreeListCtrl

Posted: Mon Jun 30, 2008 1:29 am
by rex666
metalogic wrote:I got to the bottom of this one.
This may sound dumb, but is there anywhere I can download the current version of the wxTreeListCtrl files? I went to your website, but the files there are still from last year (the version I am currently using) and there are some issues using it on wxMac (using wxMac 2.6.4 -- yes I'm stuck in a time warp, but I can't update now, or it will push my release date back too far, and everything else is working fine on Windows and Linux, so why fix what ain't broke?)

I want to update to the latest build possible, to see if those issues have been resolved, or to at least be as up-to-date as possible to fix them.

BTW, the issue is a strange refresh issue causing a section of the window to be erased to the background color underneath an open item. It does not happen upon opening up the item, but my program goes through and updates a running time on the top level items, and somewhere in this update of the parent item, it is causing the background to be erased on a portion of the window below and to the right of the open item. I haven't debugged it much further than that yet.

Thanks for your help

Posted: Fri Sep 26, 2008 3:22 pm
by jmason1182
WHOAH! Quick note... ok... IMPORTANT NOTE:

The wxTreeListCtrl uses the Idle events for some of its updates.

In my app, the refreshing BROKE because I was needing to use the idle events:


And so if you need to use the idle events for anything (like I was doing) DON'T FORGET TO PUT wxWS_EX_PROCESS_IDLE for your frame holding you wxTreeListCtrl (or the control itself I guess) because otherwise you will NOT get a refreshing window!

Posted: Mon Sep 28, 2009 7:26 am
by borr_1
Why can't get item from event

Code: Select all

Tree = new wxTreeListCtrl(this,ID_TREE,wxDefaultPosition,wxDefaultSize,
	wxDefaultValidator, _T("ID_TREE"));
Tree->Connect(ID_TREE, wxEVT_COMMAND_TREE_KEY_DOWN, (wxObjectEventFunction)&OrgStruct::OnTreeKeyDown, NULL, this);
	Tree->SetDropTarget(new TreeDropTarget(Tree)); 
	Connect(ID_TREE, wxEVT_COMMAND_TREE_BEGIN_DRAG, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &OrgStruct::OnDragAvailTree); 
void OrgStruct::OnDragAvailTree(wxTreeEvent&event)
  wxTreeItemId nod = event.GetItem();
  if(!nod.IsOk()/*Always false*/)

void OrgStruct::OnTreeKeyDown(wxTreeEvent &event)
  wxTreeItemId nod = event.GetItem();
  nod.IsOk() /*Always false*/
The same code works well for wxTreeCtrl

performance of GetNextSibling

Posted: Wed May 26, 2010 11:10 am
by BuschnicK
The documentation states GetNextChild is obsolete and one should prefer GetNextSibling instead. This is very bad advice in my experience. Reason: GetNextSibling doesn't use the cookie value for iterating over the items. It'll instead iterate the whole child array in order to find the item's index (using wxArray::Index) and then increment that. In other words: The runtime behaviour for GetNextSibling is O(n^2) where n is the number of child items. This is _very_ noticeable with big trees, especially since you typically use GetNextSibling to iterate all of them.

Summary: don't trust the documentation on this one. Prefer GetNextChild.



Posted: Wed Sep 29, 2010 1:04 pm
by duarteroso
It seemed to me that there was no wxEVT_COMMAND_CHECKBOX_CLICKED event sent, so I add it.
I don't know if it was the right place to do or the right thing, but it did the trick to me. Hope it help.

treelistctrl: line 4952

Code: Select all

if (item->GetItemType(m_curColumn) == wxCheckboxItemType)
    item->SetItemChecked(m_curColumn,! m_curItem->GetItemChecked(m_curColumn));
    wxCommandEvent event( wxEVT_COMMAND_CHECKBOX_CLICKED, m_owner->GetId() );
    event.SetEventObject( m_owner );
    event.SetInt(m_curColumn); // Send column number. Get the checkbox status using GetItemChecked.
    m_owner->ProcessEvent( event );