Retrieve data from wxUIntPtr

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 4541
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Retrieve data from wxUIntPtr

Post by ONEEYEMAN » Sun Aug 30, 2020 5:17 pm

Hi, ALL,
What is the proper way to retrieve user data from wxListCtrl item?

I have following:

Code: Select all

for( std::vector<Foo *>::iterator it = myVec.begin(); it < myVec.end(); ++it )
{
long item = m_listCtrl->InsertItem( );
m_listCtrl->SetItemPtrData( item, wxUintPtr( (*it) );
}
And now I'm having trouble retrieving "Foo *" from the list control item.

I tried:

Code: Select all

Foo *object = m_listCtrl->GetItemData( pos );
Foo *object = dynamic_cast<Foo *>( m_listCtrl->GetItemData( pos );
Thank you.

User avatar
doublemax
Moderator
Moderator
Posts: 15283
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Retrieve data from wxUIntPtr

Post by doublemax » Sun Aug 30, 2020 7:07 pm

Looks fine to me. I also tested with this small piece of code:

Code: Select all

    long item = m_list_ctrl->InsertItem(0, "hey");
    m_list_ctrl->SetItemPtrData( item, wxUIntPtr(0x12345678) );
    
    wxUIntPtr data = m_list_ctrl->GetItemData(item);
    wxLogMessage("%08x", data);
Check if the value you're putting in is the same you're getting out.
Is the lifetime of the items in the vector long enough?
Use the source, Luke!

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 4541
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Retrieve data from wxUIntPtr

Post by ONEEYEMAN » Sun Aug 30, 2020 7:38 pm

doublemax,
Except both of those lines didn't compile...

Thank you.

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2675
Joined: Sun Jan 03, 2010 5:45 pm

Re: Retrieve data from wxUIntPtr

Post by PB » Sun Aug 30, 2020 7:40 pm

I do not think that dynamic_cast is a good fit here, the proper C++ cast would probably be reinterpret_cast.

This crude example works just fine for me on MSW

Code: Select all

#include <wx/wx.h>
#include <wx/listctrl.h>

#include <vector>

struct Name
{
    Name(const wxString& first, const wxString& last)
        : m_first(first), m_last(last)
    {}

    wxString m_first, m_last;
};

class MyFrame : public wxFrame
{
public:
    MyFrame() : wxFrame(nullptr, wxID_ANY, "Test")
    {
        m_listView = new wxListView(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_LIST);

        for ( int i = 0; i < 50; ++i )
        {
            const long idx = m_listView->InsertItem(m_listView->GetItemCount(), wxString::Format("Item %d", i + 1));
            Name* name = new Name(wxString::Format("First %d", i + 1), wxString::Format("Last %d", i + 1));

            m_names.push_back(name);
            m_listView->SetItemPtrData(idx, wxUIntPtr(m_names[i]));
        }

        m_listView->Bind(wxEVT_LIST_ITEM_ACTIVATED, &MyFrame::OnItemActivated, this);
    }

    ~MyFrame()
    {
        for ( auto name : m_names )
            delete name;
    }

private:
    std::vector<Name*> m_names;
    wxListView* m_listView;

    void OnItemActivated(wxListEvent& evt)
    {
        Name* name = reinterpret_cast<Name*>(m_listView->GetItemData(evt.GetIndex()));

        wxLogMessage("%s %s", name->m_first, name->m_last);
    }
};

class MyApp : public wxApp
{
public:
    bool OnInit() override
    {
        (new MyFrame())->Show();
        return true;
    }
}; wxIMPLEMENT_APP(MyApp);

Post Reply