Fix wxTextCtrl using hints and handling wxEVT_TEXT in wxGTK2 etc
With the generic hint support (used in pre-Vista wxMSW, wxGTK2, ...), defining a wxEVT_TEXT handler not skipping the event completely broke the control functionality as it was cleared, i.e. replaced the user-entered text with the hint, whenever it lost focus. This happened because wxTextEntryHintData::OnTextChanged() was never called in this case, as the user-defined wxEVT_TEXT handler preempted it. Work around this by pushing an event handler to the front of the window event handlers chain instead of just binding to the window events directly -- this could still potentially result in the same problem if the user code pushes their own event handler, but this should be much more rare and, in any case, there is not much we can do about this (the only solution would seem to be to modify all platform-specific code to update wxTextEntryHintData explicitly whenever the text changes).
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
// wxTextEntryHintData
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLIMPEXP_CORE wxTextEntryHintData
|
||||
class WXDLLIMPEXP_CORE wxTextEntryHintData : public wxEvtHandler
|
||||
{
|
||||
public:
|
||||
wxTextEntryHintData(wxTextEntryBase *entry, wxWindow *win)
|
||||
@@ -46,16 +46,26 @@ public:
|
||||
m_win(win),
|
||||
m_text(m_entry->GetValue())
|
||||
{
|
||||
win->Bind(wxEVT_SET_FOCUS, &wxTextEntryHintData::OnSetFocus, this);
|
||||
win->Bind(wxEVT_KILL_FOCUS, &wxTextEntryHintData::OnKillFocus, this);
|
||||
win->Bind(wxEVT_TEXT, &wxTextEntryHintData::OnTextChanged, this);
|
||||
// We push ourselves as the event handler because this allows us to
|
||||
// handle events before the user-defined handlers and notably process
|
||||
// wxEVT_TEXT even if the user code already handles it, which is vital
|
||||
// as if we don't get this event, we would always set the control text
|
||||
// to the hint when losing focus, instead of preserving the text
|
||||
// entered by user. Of course, the same problem could still happen if
|
||||
// the user code pushed their own event handler before this one and
|
||||
// didn't skip wxEVT_TEXT in it, but there doesn't seem anything we can
|
||||
// do about this anyhow and this at least takes care of the much more
|
||||
// common case.
|
||||
m_win->PushEventHandler(this);
|
||||
|
||||
Bind(wxEVT_SET_FOCUS, &wxTextEntryHintData::OnSetFocus, this);
|
||||
Bind(wxEVT_KILL_FOCUS, &wxTextEntryHintData::OnKillFocus, this);
|
||||
Bind(wxEVT_TEXT, &wxTextEntryHintData::OnTextChanged, this);
|
||||
}
|
||||
|
||||
~wxTextEntryHintData()
|
||||
{
|
||||
m_win->Unbind(wxEVT_SET_FOCUS, &wxTextEntryHintData::OnSetFocus, this);
|
||||
m_win->Unbind(wxEVT_KILL_FOCUS, &wxTextEntryHintData::OnKillFocus, this);
|
||||
m_win->Unbind(wxEVT_TEXT, &wxTextEntryHintData::OnTextChanged, this);
|
||||
m_win->PopEventHandler();
|
||||
}
|
||||
|
||||
// Get the real text of the control such as it was before we replaced it
|
||||
|
Reference in New Issue
Block a user