Eventhandler messing things up(?) wxWidgets 2.8.12 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
Tapsa
Earned some good credits
Earned some good credits
Posts: 144
Joined: Tue Dec 06, 2011 5:52 pm
Location: Helsinki

Eventhandler messing things up(?) wxWidgets 2.8.12

Post by Tapsa » Sat Nov 17, 2012 10:12 pm

I have these classes and stuff:

Code: Select all

class TextCtrl_Short: public wxTextCtrl
{
	public:

	TextCtrl_Short(wxWindow *parent):
	wxTextCtrl(parent, wxID_ANY, "0", wxDefaultPosition, wxSize(0, 20))
	{
		Container = NULL;
		SetBackgroundColour(wxColour(210, 230, 255));
		Connect(GetId(), wxEVT_KILL_FOCUS, wxFocusEventHandler(TextCtrl_Short::OnKillFocus));
	}

//	Events

	void OnKillFocus(wxFocusEvent &Event){SaveEdits();}
	bool SaveEdits();

//	Member Variables

	int16_t *Container;
	void *LinkedBox;
};

class CheckBox_Short: public wxCheckBox
{
	public:

	CheckBox_Short(wxWindow *parent, string label, TextCtrl_Short *Pointer):
	wxCheckBox(parent, wxID_ANY, label, wxDefaultPosition, wxSize(0, 20))
	{
		TextBox = Pointer;
		TextBox->LinkedBox = this;
		TextBox->Disconnect(TextBox->GetId(), wxEVT_KILL_FOCUS, wxFocusEventHandler(TextCtrl_Short::OnKillFocus));
		TextBox->Connect(TextBox->GetId(), wxEVT_KILL_FOCUS, wxFocusEventHandler(CheckBox_Short::OnKillFocus));

		Connect(GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CheckBox_Short::OnUpdate));
	}

//	Events

	void OnUpdate(wxCommandEvent &Event);
	void OnKillFocus(wxFocusEvent &Event){SaveEdits();}
	bool SaveEdits();

//	Member Variables

	TextCtrl_Short *TextBox;
};

bool TextCtrl_Short::SaveEdits()
{
	if(Container == NULL) return false;
	wxString Value = GetValue().c_str();
	if(Value.size() > 0)
	{
		try
		{
			if(*Container != lexical_cast<int16_t>(Value))
			{
				*Container = lexical_cast<int16_t>(Value);
				return true;
			}
		}
		catch(bad_lexical_cast e)
		{
			wxMessageBox("Invalid entry!\nPlease enter a number from -32 768 to 32 767");
			SetFocus();
		}
	}
	else
	{
		ChangeValue(lexical_cast<string>(*Container));
	}
	return false;
}

void CheckBox_Short::OnUpdate(wxCommandEvent &Event)
{
	TextBox->ChangeValue(lexical_cast<string>(GetValue()));
	TextBox->SaveEdits();
}

bool CheckBox_Short::SaveEdits()
{
	if(TextBox->SaveEdits())
	{
		SetValue(lexical_cast<short>(TextBox->GetValue()));
		return true;
	}
	return false;
}
The problem is that calling TextBox->SaveEdits() works inside CheckBox_Short::OnUpdate(wxCommandEvent &Event) but not in CheckBox_Short::SaveEdits().
I can see no logical reason for this. TextCtrl_Short::SaveEdits() crashes as soon as it's called from within CheckBox_Short::SaveEdits().

A working workaround is changing TextBox to ((TextCtrl_Short*)Event.GetEventObject()) but it's not very appealing.

I'm also wondering whether I should always disconnect existing event handlers when I add new one?

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

Re: Eventhandler messing things up(?) wxWidgets 2.8.12

Post by doublemax » Sat Nov 17, 2012 10:47 pm

Change:

Code: Select all

TextBox->Connect(TextBox->GetId(), wxEVT_KILL_FOCUS, wxFocusEventHandler(CheckBox_Short::OnKillFocus));
To:

Code: Select all

TextBox->Connect(TextBox->GetId(), wxEVT_KILL_FOCUS, wxFocusEventHandler(CheckBox_Short::OnKillFocus), NULL, this);
This is necessary, when the event handler method (CheckBox_Short::OnKillFocus) belongs to another class than the object its connected to (TextBox). Then you need to set the "event sink" parameter accordingly.
Use the source, Luke!

Tapsa
Earned some good credits
Earned some good credits
Posts: 144
Joined: Tue Dec 06, 2011 5:52 pm
Location: Helsinki

Re: Eventhandler messing things up(?) wxWidgets 2.8.12

Post by Tapsa » Sun Nov 18, 2012 7:33 am

Well thank you, that certainly solved my problem.

Post Reply