This is more of a general question:
I noticed strange behaviour using the ID functions in wxWidgets. I have a thread which creates events. At first I used generic IDs like wxID_RETRY
for the events, but as there where more events I had to create my own IDs. So I made a header file with IDs like this:
#ifndef DGPSGUIIDS_H_INCLUDED
#define DGPSGUIIDS_H_INCLUDED
/** \brief ID for a RefreshCoordinates event*/
//@{
const int ID_REFRESH_COORDINATES = 1000;
//@}
/** \brief ID for a RefreshDirection event*/
//@{
const int ID_REFRESH_DIRECTION = 1001;
//@}
const int ID_GNSS_CONNECTION = 1002;;
const int ID_VIBROTAC_CONNECTION = 1003;
#endif // DGPSGUIIDS_H_INCLUDED
All worked fine, but I thought it is not the elegant way to give self chosen numbers to these IDs. So I used wxNewID()
instead of the numbers. Suddenly none of my threads would work anymore and I had a hard time figuring out why. After I remembered I changed the IDs I changed it back to numbers and it worked again (surprise...). But I still wanted to have generated IDs. After searching for wxNewId()
I saw it was deprecated, so I tried with the mentioned wxID_ANY
. Now the threads did something, but not what I expected them to do. The thread using ID_REFRESH_COORDINATES
now did not refresh the coordinates, but first wrote the wxString I set as a payload for another event using ID_GNSS_CONNECTION
to the window and afterwards deletes all text. (I only used wxID_ANY
on ID_REFRESH_COORDINATES
and ID_REFRESH_DIRECTION
)
(This is the function):
void WindowsDgpsGUIFrame::onRefreshCoordinates(wxThreadEvent& event)
{
StaticCoordinatesText->SetLabel(event.GetString());
}
The binding of the events:
WindowsDgpsGUIFrame::WindowsDgpsGUIFrame(wxWindow* parent,wxWindowID id)
{
Bind(wxEVT_THREAD, &WindowsDgpsGUIFrame::onGnssConnection, this, ID_GNSS_CONNECTION);
Bind(wxEVT_THREAD, &WindowsDgpsGUIFrame::onVibroTacConnection, this, ID_VIBROTAC_CONNECTION);
Bind(wxEVT_THREAD, &WindowsDgpsGUIFrame::onRefreshDirections, this, ID_REFRESH_DIRECTION);
Bind(wxEVT_THREAD, &WindowsDgpsGUIFrame::onRefreshCoordinates, this, ID_REFRESH_COORDINATES);
}
And this how I set the string in the thread:
wxThreadEvent coordinatesEvent(wxEVT_THREAD, ID_REFRESH_COORDINATES);
coordinatesEvent.SetString(coordinatesString);
m_parent->GetEventHandler()->AddPendingEvent(coordinatesEvent);
I find all of this very strange and would like to know why none of the ID functions works like I would expect...This is not really a problem, just an interesting behaviour I stumbled across.
You need to use the same ID when generating the event and when binding to it. So you can only use wxID_ANY
if you don't care about the IDs at all, i.e. if you just handle all events of the same event type (wxEVT_THREAD
in your case) in the same way. If you do use an ID when binding, then you must use the same values in both places, which means either using a constant, as you did in the beginning, or using wxNewId()
for dynamic ID allocation but using it only once and assigning the value returned by it to a variable.