Page 1 of 1

Custom events passing values back to controls

Posted: Thu Jan 18, 2007 5:12 pm
by imekon
As far as I can see, events can inform other objects about details etc.

How would I write an event that a control issues that expects a value to be returned?

I tried the following:

Code: Select all

class wxNoteCountEvent : public wxEvent
{
public:
    wxNoteCountEvent( const wxNoteCountEvent &original );
    wxNoteCountEvent( wxEventType commandType = wxEVT_NULL, int id = 0 );

    virtual wxEvent *Clone() const { return new wxNoteCountEvent(*this); }

    void SetCount(int value) { count = value; }
    int GetCount() const { return count; }

private:
    int count;
};
In the control, I do the following:

Code: Select all

int wxPianoRoll::GetNoteCount()
{
    wxNoteCountEvent event( wxEVT_NOTE_COUNT, GetId() );

    event.SetEventObject( this );

    GetEventHandler()->ProcessEvent(event);

    return event.GetCount();
}
So the event is updated by the parent control which sets the count as in:

Code: Select all

BEGIN_EVENT_TABLE(MainFrame, wxFrame)
	EVT_MENU(ID_QUIT, MainFrame::OnQuit)
	EVT_MENU(ID_ABOUT, MainFrame::OnAbout)
	EVT_NOTE_COUNT(ID_PIANOROLL, MainFrame::OnNoteCount)
END_EVENT_TABLE()

void MainFrame::OnNoteCount(wxNoteCountEvent &event)
{
    event.SetCount(100);
}
However, the value the gets returned the custom control is always 0, which suggests events don't work that way.

Posted: Thu Jan 18, 2007 6:52 pm
by DavidHart
Hi,

You didn't show your copy constructor implementation, but it needs to contain the line:
this->SetCount( original.GetCount() );

Regards,

David

Posted: Thu Jan 18, 2007 6:53 pm
by clyde729
You have to derive (at least) from wxCommandEvent (or wxNotifyEvent), if you want to catch the event in the frame.

Only wxCommandEvent and its derivates are allowed to climb up the window hierarchy. Since your event only derives from wxEvent, it won't get catched. If you wan't to use it in that way, you have to use "Connect" (wxEvtHandler) on your wxPianoRoll and use your Frame instance as eventSink (last parameter).

Posted: Thu Jan 18, 2007 8:49 pm
by imekon
DavidHart wrote:Hi,

You didn't show your copy constructor implementation, but it needs to contain the line:
this->SetCount( original.GetCount() );

Regards,

David
This is the copy constructor:

Code: Select all

wxNoteCountEvent::wxNoteCountEvent( const wxNoteCountEvent &original )
{
    count = original.count;
}
Still didn't help though.

Posted: Thu Jan 18, 2007 8:52 pm
by imekon
clyde729 wrote:You have to derive (at least) from wxCommandEvent (or wxNotifyEvent), if you want to catch the event in the frame.

Only wxCommandEvent and its derivates are allowed to climb up the window hierarchy. Since your event only derives from wxEvent, it won't get catched. If you wan't to use it in that way, you have to use "Connect" (wxEvtHandler) on your wxPianoRoll and use your Frame instance as eventSink (last parameter).
That was it!

Deriving from wxCommandEvent and hey presto I now get the value set in MainFrame passed back.

Thank you!

Posted: Fri Jan 19, 2007 4:43 am
by vdell
imekon wrote:
clyde729 wrote:You have to derive (at least) from wxCommandEvent (or wxNotifyEvent), if you want to catch the event in the frame.

Only wxCommandEvent and its derivates are allowed to climb up the window hierarchy. Since your event only derives from wxEvent, it won't get catched. If you wan't to use it in that way, you have to use "Connect" (wxEvtHandler) on your wxPianoRoll and use your Frame instance as eventSink (last parameter).
That was it!

Deriving from wxCommandEvent and hey presto I now get the value set in MainFrame passed back.

Thank you!
FYI, this would be same as deriving from wxEvent and doing

Code: Select all

wxEvent::m_propagationLevel = wxEVENT_PROPAGATE_MAX;
in your derived constructor.

Posted: Fri Jan 19, 2007 9:38 am
by imekon
vdell wrote:
FYI, this would be same as deriving from wxEvent and doing

Code: Select all

wxEvent::m_propagationLevel = wxEVENT_PROPAGATE_MAX;
in your derived constructor.
This didn't work - perhaps more settings need to change.

Posted: Fri Jan 19, 2007 1:25 pm
by clyde729
Your implementation on the copy-ctor isn't complete. It must look like:

Code: Select all

wxNoteCountEvent::wxNoteCountEvent( const wxNoteCountEvent &original )
: wxCommandEvent(original)
{
    count = original.count;
}


You have to call the baseclass - version of the copy-ctor in order to copy things like eventobject or eventtype (propagation-level, too).

Posted: Fri Jan 19, 2007 4:10 pm
by imekon
clyde729 wrote: You have to call the baseclass - version of the copy-ctor in order to copy things like eventobject or eventtype (propagation-level, too).
You're right... I had a feeling I was missing something when I wrote it.