wxMessageBox not showing up when pressing "m_button2". How to fix?

Feb 27, 2020 at 4:29pm
Hello, I'm trying to write my first program in C++, using wxFormBuilder and wxWidgets

I want wxMessageBox to show the value of "string01" when "m_button2" gets clicked (these lines of code are in inheritedgui.cpp), program builds fine with Clang, however nothing happens when I click "m_button2" (the one which says "List")

https://i.postimg.cc/jd6WDc6z/Screenshot-20200227-040106.png

How can I fix the problem? I'm stuck (coming from C# and WinForms). Thanks!



gui.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    ///////////////////////////////////////////////////////////////////////////
    // C++ code generated with wxFormBuilder (version Oct 26 2018)
    // http://www.wxformbuilder.org/
    //
    // PLEASE DO *NOT* EDIT THIS FILE!
    ///////////////////////////////////////////////////////////////////////////
    
    #pragma once
    
    #include <wx/artprov.h>
    #include <wx/xrc/xmlres.h>
    #include <wx/intl.h>
    #include <wx/string.h>
    #include <wx/stattext.h>
    #include <wx/gdicmn.h>
    #include <wx/font.h>
    #include <wx/colour.h>
    #include <wx/settings.h>
    #include <wx/textctrl.h>
    #include <wx/sizer.h>
    #include <wx/statline.h>
    #include <wx/bitmap.h>
    #include <wx/image.h>
    #include <wx/icon.h>
    #include <wx/button.h>
    #include <wx/dialog.h>
    #include <wx/msgdlg.h> 
    
    ///////////////////////////////////////////////////////////////////////////
    
    
    ///////////////////////////////////////////////////////////////////////////////
    /// Class MainDialogBase
    ///////////////////////////////////////////////////////////////////////////////
    class MainDialogBase : public wxDialog
    {
    	private:
    
    	protected:
    		wxStaticText* m_staticText3;
    		wxStaticText* m_staticText1;
    		wxTextCtrl* m_textCtrl1;
    		wxStaticText* m_staticText4;
    		wxTextCtrl* m_textCtrl2;
    		wxStaticLine* m_staticLine;
    		wxButton* m_button1;
    		wxButton* m_button2;
    
    		// Virtual event handlers, overide them in your derived class
    		virtual void OnCloseDialog( wxCloseEvent& event ) { event.Skip(); }
    		virtual void m_button1OnButtonClick( wxCommandEvent& event ) { event.Skip(); }
    		virtual void m_button2OnButtonClick( wxCommandEvent& event ) { event.Skip(); }
    
    
    	public:
    
    		MainDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size =     wxSize( 191,252 ), long style = wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE );
    		~MainDialogBase();
    
    };


gui.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
    ///////////////////////////////////////////////////////////////////////////
    // C++ code generated with wxFormBuilder (version Oct 26 2018)
    // http://www.wxformbuilder.org/
    //
    // PLEASE DO *NOT* EDIT THIS FILE!
    ///////////////////////////////////////////////////////////////////////////
    
    #include "gui.h"
    
    ///////////////////////////////////////////////////////////////////////////
    
    MainDialogBase::MainDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
    {
    	this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
    
    	wxBoxSizer* mainSizer;
    	mainSizer = new wxBoxSizer( wxVERTICAL );
    
    	wxBoxSizer* bSizer8;
    	bSizer8 = new wxBoxSizer( wxHORIZONTAL );
    
    	wxBoxSizer* bSizer2;
    	bSizer2 = new wxBoxSizer( wxVERTICAL );
    
    	m_staticText3 = new wxStaticText( this, wxID_ANY, _("Patient's data"), wxDefaultPosition, wxSize( 105,-1 ), 0 );
    	m_staticText3->Wrap( -1 );
    	m_staticText3->SetFont( wxFont( 10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxT("Sans") ) );
    
    	bSizer2->Add( m_staticText3, 0, wxALL, 5 );
    
    	wxBoxSizer* bSizer3;
    	bSizer3 = new wxBoxSizer( wxHORIZONTAL );
    
    	m_staticText1 = new wxStaticText( this, wxID_ANY, _("First Name:"), wxDefaultPosition, wxDefaultSize, 0 );
    	m_staticText1->Wrap( -1 );
    	bSizer3->Add( m_staticText1, 0, wxALL, 5 );
    
    	m_textCtrl1 = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
    	bSizer3->Add( m_textCtrl1, 0, wxALL, 5 );
    
    
    	bSizer2->Add( bSizer3, 1, wxEXPAND, 5 );
    
    	wxBoxSizer* bSizer4;
    	bSizer4 = new wxBoxSizer( wxHORIZONTAL );
    
    	m_staticText4 = new wxStaticText( this, wxID_ANY, _("Last Name:"), wxDefaultPosition, wxDefaultSize, 0 );
    	m_staticText4->Wrap( -1 );
    	bSizer4->Add( m_staticText4, 0, wxALL, 5 );
    
    	m_textCtrl2 = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
    	bSizer4->Add( m_textCtrl2, 0, wxALL, 5 );
    
    
    	bSizer2->Add( bSizer4, 1, wxEXPAND, 5 );
    
    
    	bSizer8->Add( bSizer2, 1, 0, 5 );
    
    
    	mainSizer->Add( bSizer8, 1, wxEXPAND, 5 );
    
    	m_staticLine = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
    	mainSizer->Add( m_staticLine, 0, wxEXPAND | wxALL, 5 );
    
    	m_button1 = new wxButton( this, wxID_ANY, _("Record Data"), wxDefaultPosition, wxDefaultSize, 0 );
    	mainSizer->Add( m_button1, 0, wxALL|wxEXPAND, 5 );
    
    	m_button2 = new wxButton( this, wxID_ANY, _("List"), wxDefaultPosition, wxDefaultSize, 0 );
    	mainSizer->Add( m_button2, 0, wxALL|wxEXPAND, 5 );
    
    	wxBoxSizer* bSizer9;
    	bSizer9 = new wxBoxSizer( wxHORIZONTAL );
    
    
    	mainSizer->Add( bSizer9, 1, wxEXPAND, 5 );
    
    
    	this->SetSizer( mainSizer );
    	this->Layout();
    
    	this->Centre( wxBOTH );
    
    	// Connect Events
    	this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainDialogBase::OnCloseDialog ) );
    	m_button1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogBase::m_button1OnButtonClick ), NULL, this );
    	m_button2->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogBase::m_button2OnButtonClick ), NULL, this );
    }
    
    MainDialogBase::~MainDialogBase()
    {
    	// Disconnect Events
    	this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainDialogBase::OnCloseDialog ) );
    	m_button1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogBase::m_button1OnButtonClick ), NULL, this );
    	m_button2->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogBase::m_button2OnButtonClick ), NULL, this );
    
    }


inheritedgui.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    #ifndef __inheritedgui__
    #define __inheritedgui__
    
    /**
    @file
    Subclass of MainDialogBase, which is generated by wxFormBuilder.
    */
    
    #include "gui.h"
    
    //// end generated include
    
    /** Implementing MainDialogBase */
    class inheritedgui : public MainDialogBase
    {
    	protected:
    		// Handlers for MainDialogBase events.
    		void OnCloseDialog( wxCloseEvent& event );
            void m_button1OnButtonClick(wxCommandEvent& event) override;
            void m_button2OnButtonClick(wxCommandEvent& event) override;
    	public:
    		/** Constructor */
    		inheritedgui( wxWindow* parent );
    	//// end generated class members
    
    };
    
    #endif // __inheritedgui__


inheritedgui.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    #include "inheritedgui.h"
    
    inheritedgui::inheritedgui( wxWindow* parent )
    :
    MainDialogBase( parent )
    {   
    
    }

    wxString string01;
    
    void inheritedgui::m_button1OnButtonClick(wxCommandEvent& event)
    {
     
    string01 = m_textCtrl1->GetValue().ToStdString();
    
    }
    
    void inheritedgui::m_button2OnButtonClick(wxCommandEvent& event)
    {
    
    wxMessageBox( string01, wxT("This is the title"), wxICON_INFORMATION );
    
    }
    
    void inheritedgui::OnCloseDialog( wxCloseEvent& event )
    {
    // TODO: Implement OnCloseDialog
    }





Last edited on Feb 27, 2020 at 4:30pm
Feb 27, 2020 at 5:16pm
What I don't see is the code which creates the wxDialog derivative.

My suspicion is that what is actually being created is a MainDialogBase, not an inheritedgui.

As such, the base button close functions are being called, as in that scenario there is no inheritedgui object to override them.

I would also point out that m_ prefix typically applies to member data, not member functions. Even then it is a questionable habit to prefix with m_ (see Stroustrup in a variety of writings about style). Some insist, and it is not particularly harmful, but not really functional. It is expected to be data, however, not a function.
Feb 27, 2020 at 5:42pm
Hello, thank you very much for your reply

Looks like by default wxFormBuilder adds a "m_" prefix to everything

This is jut a minimal test program, however I'll have in mind what you mentioned and read Stroustrup before giving the final touches to the definitive program

Right now there are too many things that I can't figure out how to make them work in C++, so currently I'm giving priority to trying to make the functional part work (for example, making the wxMessageBox show up... this is an essential part, because the logic of the full program will basically be taking user input from wxTextCtrls, wxComboBoxes, wxDatePickerCtrls, wxRadioButtons, storing the values in variables and displaying the values in a messagebox, and after this is done I'll start reading about how to do the connection to a SQLite db)

What I don't see is the code which creates the wxDialog derivative.

My suspicion is that what is actually being created is a MainDialogBase, not an inheritedgui.

As such, the base button close functions are being called, as in that scenario there is no inheritedgui object to override them.


I just used the wxFormBuilder option to generate an inherited class named "inheritedgui", to work there on the logic of the program, since wxFormBuilder will make changes to gui.cpp and gui.h (I'm following the advice from the first reply: https://stackoverflow.com/questions/31647051/what-is-the-suggested-way-to-use-wxformbuilder-for-generating-c-code)

What changes to the code do you think I should make to fix the wxMessageBox issue?

Regards



Last edited on Feb 27, 2020 at 5:52pm
Feb 27, 2020 at 7:33pm
As an experiment, put the code you have in "inheritedgui" into their base MainDialogBase counterparts (perhaps just the button 2 that you're focused on) to see if that "fires" correctly. If it does, then my theory has support.

Search the generated code for MainDialogBase, and then for inheritedgui. I do this in Visual Studio by using the "find in files" text search feature, but your IDE may have a different method.

Looking through that, look for something which creates either a MainDialogBase or an inheritedgui object representing the dialog when it is created. I sense it is making a MainDialogBase, and not an inheritedgui instantiation.

An alternative method of exploration depends on how well you can use a debugger.

I would set breakpoints in the button 2 response functions, both the base (which just calls skip) in MainDialogBase and in the inheritedgui version.

See which one "breaks" when you press the button. In either case, no matter which function breaks, check "this" to see what type it is. The debugger, if it is good, should recognize that even if you're in the MainDialogBase function, if the type of the "this" object is actually inheritedgui, it should show that to you. I know this happens in Visual Studio, but I don't know which debugger/IDE you're using.

I have a vague memory here, but it could be that the "connect" feature is making an explicit call to the MainDialogBase version, as in "this->MainDialogBase::func()", which is an explicit means of calling the base and not the virtual descendent. If this is the case, you may need to make the initialization code which performs the "connect" calls to these functions in a virtual function where inhertedgui makes the connections, not MainDialogBase.
Last edited on Feb 27, 2020 at 7:37pm
Feb 28, 2020 at 1:51am
Hello, thanks again for trying to help me

I gave up with this code generated by wxFormBuilder and I'm now using wxCrafter, which seems it generates code a bit more simpler

Have a different problem now, I'm going to open a new thread
Last edited on Feb 28, 2020 at 2:16am
Topic archived. No new replies allowed.