Unbind inheritance issue 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
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 517
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Unbind inheritance issue

Post by mael15 »

Code: Select all

class One {
public:
	void bindUnbindFunction(wxKeyEvent &evt){}
};

class Two : public wxEvtHandler, public One {
public:
	Two() {
		Bind(wxEVT_KEY_DOWN, &One::bindUnbindFunction, this);
	}
};

class Three : public Two {
public:
	Three() : Two(){}
};

Code: Select all

Two* second = new Two();
bool success = second->Unbind(wxEVT_KEY_DOWN, &One::bindUnbindFunction, second);	// TRUE
Three* third = new Three();
success = third->Unbind(wxEVT_KEY_DOWN, &One::bindUnbindFunction, third);	// FALSE?!?!?!
Why does third->Unbind fail and how can I make it succeed?
Last edited by mael15 on Sun Jan 22, 2023 4:19 pm, edited 1 time in total.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 6551
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Unbind inheritance issue

Post by ONEEYEMAN »

Hi,
Please define what do you mean by saying "fail"? We don't have access to your machine, nor crystall ball to have a look.

Thank you.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 517
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: Unbind inheritance issue

Post by mael15 »

hi,
like shown in the last code line, the return value is false. and when tested it actually is not unbound.
User avatar
doublemax
Moderator
Moderator
Posts: 18004
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Unbind inheritance issue

Post by doublemax »

It fails because the event sink parameters in the Bind() and Unbind() calls are of different types in the second case.

For the Bind() call the event sink parameter is a "Two *".
But for the Unbind call it's a "Three *".

If you cast "third" to "Two *", it will work:

Code: Select all

success = third->Unbind(wxEVT_KEY_DOWN, &One::bindUnbindFunction, (Two *)third);	
In this sample code, the cleanest solution might be to move the Unbind() call into the "Two" class.
But in your "real" code the situation might be different.

However, the whole issue is a little "smelly". But as i don't know the real application, it's only a guess.
Use the source, Luke!
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 517
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: Unbind inheritance issue

Post by mael15 »

doublemax wrote: Sun Jan 22, 2023 5:36 pmIf you cast "third" to "Two *", it will work
It does, thanx! [-o<
doublemax wrote: Sun Jan 22, 2023 5:36 pmHowever, the whole issue is a little "smelly". But as i don't know the real application, it's only a guess.
The real life situation is as follows: I have a user interface with a lot of different controls and I handle key and mouse events in the uppermost class of my nested UI. For the events to get propagated to the uppermost wxFrame, I use a simple base class

Code: Select all

class propagatorBase {
public:
	void propagate(wxKeyEvent& evt) {
		evt.ResumePropagation(levelsToPropagate);
		evt.Skip();
	}

	void propagateMouse(wxMouseEvent& evt) {
		evt.ResumePropagation(levelsToPropagate);
		evt.Skip();
	}
protected:
	static const int levelsToPropagate = 100;
};
For every control type, I made an inheriting class like this:

Code: Select all

class DECLDIR_CONF textCtrlPropagator : public wxTextCtrl, public propagatorBase {
public:
	textCtrlPropagator(wxWindow *par, int height, long style = 0)
		: wxTextCtrl(par, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1, height), style | wxTE_PROCESS_ENTER),
		propagatorBase() {
		Bind(wxEVT_KEY_DOWN, &propagatorBase::propagate, this);
		Bind(wxEVT_KEY_UP, &propagatorBase::propagate, this);
		Bind(wxEVT_MOUSEWHEEL, &propagatorBase::propagateMouse, this);
	}
};
9 out of 10 times this works well, but I have one special class that needs individual key event handling. So I keep only the mousewheel event and unbind the key events in only this one class so it can make special things for special key events.
Is there a less smelly way to do it?
User avatar
[email protected]
Super wx Problem Solver
Super wx Problem Solver
Posts: 283
Joined: Wed Jul 29, 2020 6:06 pm

Re: Unbind inheritance issue

Post by [email protected] »

Are you aware of wxAppConsole::FilterEvent?
https://docs.wxwidgets.org/trunk/classw ... c6f602e20c

All events pass through this function, maybe this would make things easier for you?
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 517
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: Unbind inheritance issue

Post by mael15 »

[email protected] wrote: Mon Jan 23, 2023 9:59 amAre you aware of wxAppConsole::FilterEvent?
It´s funny that I actually found this in my code, I must have written it years ago, forgotten about it and the built this propagate solution on top. I will stick to the FilterEvent solution only.

It works fine with most controls, only wxRadioBox seems to block key events. I cannot see anything in the source code, could someone check this please?
To be more precise: when a wxRadioButton in a wxRadioBox has the focus, wxAppConsole::FilterEvent is not triggered for a wxEVT_KEY_DOWN event.
User avatar
[email protected]
Super wx Problem Solver
Super wx Problem Solver
Posts: 283
Joined: Wed Jul 29, 2020 6:06 pm

Re: Unbind inheritance issue

Post by [email protected] »

mael15 wrote: Tue Jan 24, 2023 3:20 pm To be more precise: when a wxRadioButton in a wxRadioBox has the focus, wxAppConsole::FilterEvent is not triggered for a wxEVT_KEY_DOWN event.
But it does work when you Bind the event handler directly to the control?
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 517
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: Unbind inheritance issue

Post by mael15 »

[email protected] wrote: Tue Jan 24, 2023 4:09 pmBut it does work when you Bind the event handler directly to the control?
Not the wxEVT_KEY_DOWN handler, but the wxEVT_RADIOBOX works as expected.

Code: Select all

bearingBox = new wxRadioBox(ctrlScroller, wxID_ANY, _i("Lage der Bündel"), wxDefaultPosition, wxDefaultSize, bearingChoices, 2, wxRA_SPECIFY_COLS | wxWANTS_CHARS | wxTAB_TRAVERSAL);
bearingBox->Bind(wxEVT_RADIOBOX, &CreatorPanel::onBearingChanged, this);
bearingBox->Bind(wxEVT_KEY_DOWN, &CreatorPanel::onKeyDownTest, this);
maybe it has to got directly to wxRadioButton?
User avatar
doublemax
Moderator
Moderator
Posts: 18004
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Unbind inheritance issue

Post by doublemax »

Try wxEVT_CHAR_HOOK.
Use the source, Luke!
Post Reply