Problem with wxListCtrl::InsertItem()

551 views
Skip to first unread message

Robert Dailey

unread,
Oct 15, 2009, 9:11:29 PM10/15/09
to wx-users
Hello,

I'm trying to insert a string into my wxListCtrl like so:


wxListItem newItem;
newItem.SetId( count );
newItem.SetColumn( 0 );
newItem.SetText( frameName.c_str() );
newItem.SetMask( wxLIST_MASK_TEXT );
m_frameList->InsertItem( newItem );

However, I get an assertion that says:

"m_count should match ListView_GetItemCount"

ListView_InsertItem(), which is a win32 function called inside of the
MSW implementation of wxListCtrl::InsertItem( wxListItem const& ) is
returning -1, which means failure. I am not sure of the details of why
it is failing.

Am I missing something obvious? I have inserted 2 columns into my list
view (which is using report mode) like so:

unsigned const COLUMN_LOOP = 0;
unsigned const COLUMN_FRAME_ID = 1;

m_frameList->InsertColumn( COLUMN_LOOP, "" );
m_frameList->SetColumnWidth( COLUMN_LOOP, 20 );
m_frameList->InsertColumn( COLUMN_FRAME_ID, "Frame" );

Help is appreciated.

Robert Dailey

unread,
Oct 15, 2009, 9:16:40 PM10/15/09
to wx-users
Oh and 'count' above is actually 0 when this is called, so it will be
setting the first item in the list control.

Vadim Zeitlin

unread,
Oct 16, 2009, 10:32:01 AM10/16/09
to wx-u...@googlegroups.com
On Thu, 15 Oct 2009 18:11:29 -0700 (PDT) Robert Dailey <rcda...@gmail.com> wrote:

RD>
RD> I'm trying to insert a string into my wxListCtrl like so:
RD>
RD>
RD> wxListItem newItem;
RD> newItem.SetId( count );
RD> newItem.SetColumn( 0 );
RD> newItem.SetText( frameName.c_str() );
RD> newItem.SetMask( wxLIST_MASK_TEXT );
RD> m_frameList->InsertItem( newItem );

I'd use

m_frameList->InsertItem(0, frameName);

which is more clear IMO. And SetMask() is unnecessary anyhow (and so is
.c_str() call). But it should be harmless...

RD> However, I get an assertion that says:
RD>
RD> "m_count should match ListView_GetItemCount"
RD>
RD> ListView_InsertItem(), which is a win32 function called inside of the
RD> MSW implementation of wxListCtrl::InsertItem( wxListItem const& ) is
RD> returning -1, which means failure. I am not sure of the details of why
RD> it is failing.

The assert probably shouldn't be triggered if inserting the item failed
but OTOH this would just hide the real problem. I don't know neither why
does it fail though, as usual trying to reproduce the problem in the
listctrl sample might be useful.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

Robert Dailey

unread,
Oct 16, 2009, 1:31:34 PM10/16/09
to wx-users


On Oct 16, 9:32 am, Vadim Zeitlin <va...@wxwidgets.org> wrote:
> On Thu, 15 Oct 2009 18:11:29 -0700 (PDT) Robert Dailey <rcdai...@gmail.com> wrote:
>
> RD>
> RD> I'm trying to insert a string into my wxListCtrl like so:
> RD>
> RD>
> RD>     wxListItem newItem;
> RD>     newItem.SetId( count );
> RD>     newItem.SetColumn( 0 );
> RD>     newItem.SetText( frameName.c_str() );
> RD>     newItem.SetMask( wxLIST_MASK_TEXT );
> RD>     m_frameList->InsertItem( newItem );
>
>  I'd use
>
>         m_frameList->InsertItem(0, frameName);

I didn't do this because it wouldn't let me set the column. I need the
item to actually be in column 1, I put 0 there to simplify the
example. However, items added are not always on the first column. I
can't do this with any of the other overloads for InsertItem(),
including the one you are suggesting here.

>
> which is more clear IMO. And SetMask() is unnecessary anyhow (and so is
> .c_str() call). But it should be harmless...

Why is SetMask() unnecessary? And if it is, why does the function
exist? Also, frameName is a std::string, not a wxString object. Since
there is no recognition of STL in wxWidgets's interface, I have to do
this.

>
> RD> However, I get an assertion that says:
> RD>
> RD> "m_count should match ListView_GetItemCount"
> RD>
> RD> ListView_InsertItem(), which is a win32 function called inside of the
> RD> MSW implementation of wxListCtrl::InsertItem( wxListItem const& ) is
> RD> returning -1, which means failure. I am not sure of the details of why
> RD> it is failing.
>
>  The assert probably shouldn't be triggered if inserting the item failed
> but OTOH this would just hide the real problem. I don't know neither why
> does it fail though, as usual trying to reproduce the problem in the
> listctrl sample might be useful.

Why shouldn't it be triggered? Looking at the assertion logic for the
MSW implementation in 2.9.0, it is comparing the number of list items
that the Win32 list control has with what the wxListCtrl class thinks
it has, and thus triggers the assertion. I don't know what you mean.
Here is the logic:

long rv = ListView_InsertItem(GetHwnd(), & item);

m_count++;
wxASSERT_MSG( m_count == ListView_GetItemCount(GetHwnd()),
wxT("m_count should match ListView_GetItemCount"));

Variable 'rv' above will be -1 when ListView_InsertItem() returns.
Also, you should be using prefix increment for m_count here since you
are not using the temporary return value created by postfix.

Robert Dailey

unread,
Oct 16, 2009, 1:44:16 PM10/16/09
to wx-users
I found out something interesting...

As I said before, I'm doing this to setup my columns:


unsigned const COLUMN_LOOP = 0;
unsigned const COLUMN_FRAME_ID = 1;

m_frameList->InsertColumn( COLUMN_LOOP, "" );
m_frameList->SetColumnWidth( COLUMN_LOOP, 20 );
m_frameList->InsertColumn( COLUMN_FRAME_ID, "Frame" );

If I comment out the first call to InsertColumn() and the
SetColumnWidth() right under that, my InsertItem() call succeeds.
Weird.... What is going on here?

Robert Dailey

unread,
Oct 16, 2009, 1:48:29 PM10/16/09
to wx-users
Another follow up...

I think I figured it out. InsertColumn()'s first parameter must not be
zero-based, for reasons I do not understand. I looked over the
documentation and did not see any specifics on column index
requirements. For example, instead of doing this:

m_frameList->InsertColumn( 0, "" );
m_frameList->SetColumnWidth( 0, 20 );

m_frameList->InsertColumn( 1, "Frame" );

I have to do this:

m_frameList->InsertColumn( 1, "" );
m_frameList->SetColumnWidth( 0, 20 );

m_frameList->InsertColumn( 2, "Frame" );

Once I do it this way, InsertItem() will succeed when it is called
later on. Any explanation for this?

Robert Dailey

unread,
Oct 16, 2009, 2:21:09 PM10/16/09
to wx-users
Nope, this doesn't seem to fully fix the problem. While it does let me
insert an item at column 0 now, when I try to insert at column index 1
it fails.

Robert Dailey

unread,
Oct 16, 2009, 2:39:05 PM10/16/09
to wx-users
Sorry for the continuous emails...

It seems like one is unable to insert an item into the list control
report view in a matrix-fashion. In other words, I cannot target a
specific cell and insert text into that cell directly. When I insert
an item, that's basically the same as inserting a row. Once I have
that "row", I can now call wxListCtrl::SetItem() on that index and set
the value of a specific column. This becomes a two step process.

I find it unfortunate that the documentation did not state this and I
had to resolve to looking at sample code and trial/error to figure
this out. I really hope you guys can document both InsertItem() and
SetItem() for wxListCtrl more properly to reflect this.

Vadim Zeitlin

unread,
Oct 16, 2009, 2:49:47 PM10/16/09
to wx-u...@googlegroups.com
On Fri, 16 Oct 2009 11:39:05 -0700 (PDT) Robert Dailey <rcda...@gmail.com> wrote:

RD> It seems like one is unable to insert an item into the list control
RD> report view in a matrix-fashion.

No, you can't do this. But your original example didn't show it so I still
don't understand why didn't it work.

RD> I find it unfortunate that the documentation did not state this and I
RD> had to resolve to looking at sample code and trial/error to figure
RD> this out. I really hope you guys can document both InsertItem() and
RD> SetItem() for wxListCtrl more properly to reflect this.

I think the best would be to enhance wxListView which I started writing a
long time ago. wxListCtrl API is IMO hopeless, with or without
documentation.

Robert Dailey

unread,
Oct 16, 2009, 3:05:52 PM10/16/09
to wx-users


On Oct 16, 1:49 pm, Vadim Zeitlin <va...@wxwidgets.org> wrote:
> On Fri, 16 Oct 2009 11:39:05 -0700 (PDT) Robert Dailey <rcdai...@gmail.com> wrote:
>
> RD> It seems like one is unable to insert an item into the list control
> RD> report view in a matrix-fashion.
>
> No, you can't do this. But your original example didn't show it so I still
> don't understand why didn't it work.

My guess is that the Win32 API will fail if you set the ID *and*
column index at the same time when inserting a new item into the list
control.

>
> RD> I find it unfortunate that the documentation did not state this and I
> RD> had to resolve to looking at sample code and trial/error to figure
> RD> this out. I really hope you guys can document both InsertItem() and
> RD> SetItem() for wxListCtrl more properly to reflect this.
>
> I think the best would be to enhance wxListView which I started writing a
> long time ago. wxListCtrl API is IMO hopeless, with or without
> documentation.

Could you explain why it is hopeless? I would be interested in
learning why so many wxWidgets programmers are unhappy with it. If you
have a wiki article or blog entry on it, I would love to read it.

Vadim Zeitlin

unread,
Oct 16, 2009, 4:03:23 PM10/16/09
to wx-u...@googlegroups.com
On Fri, 16 Oct 2009 12:05:52 -0700 (PDT) Robert Dailey <rcda...@gmail.com> wrote:

RD> On Oct 16, 1:49 pm, Vadim Zeitlin <va...@wxwidgets.org> wrote:


RD> > On Fri, 16 Oct 2009 11:39:05 -0700 (PDT) Robert Dailey <rcdai...@gmail.com> wrote:
RD> >

RD> > RD> It seems like one is unable to insert an item into the list control
RD> > RD> report view in a matrix-fashion.
RD> >
RD> > No, you can't do this. But your original example didn't show it so I still
RD> > don't understand why didn't it work.
RD>
RD> My guess is that the Win32 API will fail if you set the ID and
RD> column index at the same time when inserting a new item into the list
RD> control.

Of course it won't but if column is 0 it doesn't count. I.e. this is what
InsertItem(idx, label) does anyhow.

RD> > RD> I find it unfortunate that the documentation did not state this and I
RD> > RD> had to resolve to looking at sample code and trial/error to figure
RD> > RD> this out. I really hope you guys can document both InsertItem() and
RD> > RD> SetItem() for wxListCtrl more properly to reflect this.
RD> >
RD> > I think the best would be to enhance wxListView which I started writing a
RD> > long time ago. wxListCtrl API is IMO hopeless, with or without
RD> > documentation.
RD>
RD> Could you explain why it is hopeless?

Basically because it's a direct copy of MSW API for the control with the
same name which is bad even as C API go and horrible in C++. I really don't
know if it's worth going into the details, I'd believe that the troubles
you have using it yourself would be reason enough. Anyhow, just look at the
few wxListView methods to see what I mean: do you really prefer writing
SetItemState(n, 0, wxLIST_STATE_SELECTED) to Select(n, false)? And so on...

Reply all
Reply to author
Forward
0 new messages