Search code examples
c++wxwidgets

wxWidgets Drop Files eventhandler initialization problem (invalid static_cast)


I am trying to make a simple program to drop files on a list using C++ with a (wxWidgets) wxListCtrl.

  • Tools I use: Code::Blocks 20.03, MinGW 17.1, wxWidgets 3.1.3, wxFormBuilder 3.9.0.
  • OS: Windows 10 Pro.

I tried the following: (in a function SetupGUI() which is called in the DnD_SimpleFrame class constructor.)

m_listCtrl1 = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_HEADER|wxLC_REPORT );
m_listCtrl1->DragAcceptFiles(true);
m_listCtrl1->Connect(wxEVT_DROP_FILES, wxDropFilesEventHandler(DnD_SimpleFrame::OnDropFiles), NULL, this);

The function to be called on dropping the files (from explorer) is:

bool DnD_SimpleFrame::OnDropFiles(wxArrayString &filenames)
{
    size_t nFiles = filenames.GetCount();
    wxString str;
    str.Printf( "%d files dropped", (int)nFiles);

    m_listCtrl1->DeleteAllItems();
    if (m_listCtrl1 != NULL)
    {
        m_listCtrl1->InsertItem(0, str);
        for ( size_t n = 1; n < (nFiles+1); n++ )
            m_listCtrl1->InsertItem(n, filenames[n]);
    }
    return true;
}

The build messages on the m_listCtrl1->Connect(...); line are:

||=== Build: Debug in DnD_Simple (compiler: GNU GCC Compiler) ===|
F:\Data\__C++\wxApps\DnD_Simple\DnD_SimpleMain.cpp||In member function 'void DnD_SimpleFrame::SetupGUI()':|
F:\SDKs\wx313\include\wx\event.h|149|error: invalid static_cast from type 'bool (DnD_SimpleFrame::*)(wxArrayString&)' to type 'wxDropFilesEventFunction' {aka 'void (wxEvtHandler::*)(wxDropFilesEvent&)'}|
F:\SDKs\wx313\include\wx\event.h|4196|note: in expansion of macro 'wxEVENT_HANDLER_CAST'|
F:\Data\__C++\wxApps\DnD_Simple\DnD_SimpleMain.cpp|92|note: in expansion of macro 'wxDropFilesEventHandler'|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|

What am I doing wrong here (or am forgetting)?


Solution

  • If you carefully look at the error message:

    error: invalid static_cast from type 'bool (DnD_SimpleFrame::*)(wxArrayString&)' to type 'wxDropFilesEventFunction' {aka 'void (wxEvtHandler::*)(wxDropFilesEvent&)'}
    

    you can see that it says that it can't convert something from one type to the other one.

    The types may be difficult to parse if you're new to C++, but you should be able to see that these are function pointers (in fact, pointers to a class member). And looking at your code, you should also be able to see that the first is them is the type of your DnD_SimpleFrame::OnDropFiles function and hence the problem is that it can't be converted to the expected function type.

    Finally, the reason for this is just that your function doesn't have the right parameter type: you're supposed to give wxWidgets something taking wxDropFilesEvent&, but your function takes wxArrayString& instead. You will have to change it to take wxDropFilesEvent& event and then use GetFiles() method of the event object to get the actual files.


    On a completely different topic, you should use Bind() and not Connect() in the new code. If you're following a tutorial which uses the latter, it's a good sign that it's very outdated. Your code still wouldn't have compiled with Bind(), but the error messages would have been slightly simpler.