Unresolved external symbol with wxDECLARE_EVENT Topic is solved

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
sw
In need of some credit
In need of some credit
Posts: 9
Joined: Sat Mar 16, 2019 8:09 pm

Unresolved external symbol with wxDECLARE_EVENT

Post by sw » Wed Jul 31, 2019 9:08 am

Hi all,

I have searched through the forums to see if anyone has experienced this issue, but I have not found anything.

I was following the wiki page for creating custom events https://wiki.wxwidgets.org/Custom_Event ... -_Method_4

I am trying to post a event from a dialog to the main (parent) frame. In the dialog header file I have added the macro to declare the event like so:

Code: Select all

wxDECLARE_EVENT(TASK_INSERTED, wxCommandEvent);
This line is placed after all includes and before the class declaration. And in the source file I define the event:

Code: Select all

wxDEFINE_EVENT(TASK_INSERTED, wxCommandEvent);
My main issue is that when I compile the code, the linker complains about a "unresolved external symbol". This is the full error:
LNK2001 unresolved external symbol "class wxEventTypeTag<class wxCommandEvent> const TASK_INSERTED" ([email protected]@[email protected]@@@@B)
This error is coming from the frame obj file.

I don't think I am missing a include as I am including wx/wx.h in both the frame and dialog header files. I am using wxWidgets 3.1.2-1 on Windows 10 with VS2019

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

Re: Unresolved external symbol with wxDECLARE_EVENT

Post by doublemax » Wed Jul 31, 2019 11:37 am

That looks ok to me. Can you show how you use the new event?

https://docs.wxwidgets.org/trunk/overvi ... nts_custom
Use the source, Luke!

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

Re: Unresolved external symbol with wxDECLARE_EVENT

Post by PB » Wed Jul 31, 2019 11:38 am

The code you posted should work, the issue must be elswhere.

FWIW, this works as expected

MyDialog.h

Code: Select all

#pragma once

#include <wx/wx.h>

wxDECLARE_EVENT(TASK_INSERTED, wxCommandEvent);

class MyDialog : public wxDialog
{
public:
    MyDialog(wxWindow* parent);
protected: 
    void OnAddTask(wxCommandEvent&);
};
MyDialog.cpp

Code: Select all

#include "MyDialog.h"

MyDialog::MyDialog(wxWindow* parent) 
    : wxDialog(parent, wxID_ANY, "Add Task Dialog")
{                                                                      
    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
        
    wxButton* button = new wxButton(this, wxID_ANY, "Add Task");
    button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MyDialog::OnAddTask, this);
    mainSizer->Add(button, wxSizerFlags().Expand().DoubleBorder());

    mainSizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Expand().DoubleBorder());
                        
    SetSizerAndFit(mainSizer);
}	

void MyDialog::OnAddTask(wxCommandEvent&)
{
    wxCommandEvent event(TASK_INSERTED, GetId());
    
    event.SetEventObject(this);    
    GetParent()->ProcessWindowEvent(event);
}
MyFrame.cpp

Code: Select all

#include <wx/wx.h>

#include "MyDialog.h"

wxDEFINE_EVENT(TASK_INSERTED, wxCommandEvent);

class MyFrame : public wxFrame
{
public:
    MyFrame() : wxFrame(nullptr, wxID_ANY, "Test", wxDefaultPosition, wxSize(800, 600))          
    {  
        wxPanel* mainPanel = new wxPanel(this);        
        wxBoxSizer* mainPanelSizer = new wxBoxSizer(wxVERTICAL);
        
        wxButton* button = new wxButton(mainPanel, wxID_ANY, "Show Dialog...");
        button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MyFrame::OnShowDialog, this);
        mainPanelSizer->Add(button, wxSizerFlags().Expand().DoubleBorder());
        
        wxTextCtrl* logCtrl = new wxTextCtrl(mainPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 
            wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);     
        wxLog::SetActiveTarget(new wxLogTextCtrl(logCtrl));                                         
        mainPanelSizer->Add(logCtrl, wxSizerFlags().Expand().DoubleBorder().Proportion(5));

        mainPanel->SetSizer(mainPanelSizer);

        Bind(TASK_INSERTED, &MyFrame::OnAddTask, this);
    }   
protected:            

    void OnShowDialog(wxCommandEvent&)
    {   
        MyDialog dlg(this);

        dlg.ShowModal();
    }

    void OnAddTask(wxCommandEvent&)
    {
        wxLogMessage("Task added.");
    }
};

class MyApp : public wxApp
{
public:   
    bool OnInit() override
    {
        (new MyFrame)->Show();
        return true;
    }
}; wxIMPLEMENT_APP(MyApp);;
Not sure whether something like this, i.e., passing the event from the modal dialog, is a good idea....

sw
In need of some credit
In need of some credit
Posts: 9
Joined: Sat Mar 16, 2019 8:09 pm

Re: Unresolved external symbol with wxDECLARE_EVENT

Post by sw » Wed Jul 31, 2019 11:53 am

In the dialog:

Code: Select all

wxCommandEvent taskInsertedEvent(TASK_INSERTED);
wxPostEvent(pParent, taskInsertedEvent);
where pParent is a pointer to the frame class.

In the frame:

Code: Select all

wxBEGIN_EVENT_TABLE(MainFrame, wxFrame)
...
EVT_COMMAND(wxID_ANY, TASK_INSERTED, MainFrame::OnTaskInserted)
...
wxEND_EVENT_TABLE()

void MainFrame::OnTaskInserted(wxCommandEvent& event)
{
    pListCtrl->DeleteAllItems();
    RefreshItems();
}

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

Re: Unresolved external symbol with wxDECLARE_EVENT

Post by PB » Wed Jul 31, 2019 12:36 pm

Do you have wxDEFINE... above the message table definition?

Does the issue persist when you use Bind() instead of the static event table or just comment out the line in the message table in frame source file?

sw
In need of some credit
In need of some credit
Posts: 9
Joined: Sat Mar 16, 2019 8:09 pm

Re: Unresolved external symbol with wxDECLARE_EVENT

Post by sw » Wed Jul 31, 2019 1:17 pm

I'm so embarrassed, but I figured it out. I'm using namespaces in my application and I put the wxDEFINE_EVENT inside the namespace of the dialog source file. The frame is also in a namespace, but in a different one hence why the linker was struggling to find the event. Moving it out of the namespace has resolved the linker problem.

Thank you PB, your comment set me on the right path. And thank you doublemax too.

Post Reply