fixed event generation for wxComboBox to be consistent with the other platforms and also simplified the code by using the existing wxChoice logic instead of reimplementing it in a broken way

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38043 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-03-12 20:53:27 +00:00
parent c11f04122f
commit 7d90194ccb
2 changed files with 37 additions and 110 deletions

View File

@@ -23,7 +23,7 @@
class WXDLLEXPORT wxComboBox: public wxChoice class WXDLLEXPORT wxComboBox: public wxChoice
{ {
public: public:
wxComboBox() { Init(); } wxComboBox() { }
wxComboBox(wxWindow *parent, wxWindowID id, wxComboBox(wxWindow *parent, wxWindowID id,
const wxString& value = wxEmptyString, const wxString& value = wxEmptyString,
@@ -34,8 +34,6 @@ public:
const wxValidator& validator = wxDefaultValidator, const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxComboBoxNameStr) const wxString& name = wxComboBoxNameStr)
{ {
Init();
Create(parent, id, value, pos, size, n, choices, style, validator, name); Create(parent, id, value, pos, size, n, choices, style, validator, name);
} }
wxComboBox(wxWindow *parent, wxWindowID id, wxComboBox(wxWindow *parent, wxWindowID id,
@@ -47,8 +45,6 @@ public:
const wxValidator& validator = wxDefaultValidator, const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxComboBoxNameStr) const wxString& name = wxComboBoxNameStr)
{ {
Init();
Create(parent, id, value, pos, size, choices, style, validator, name); Create(parent, id, value, pos, size, choices, style, validator, name);
} }
@@ -75,7 +71,7 @@ public:
// List functions: see wxChoice // List functions: see wxChoice
// Text field functions // Text field functions
wxString GetValue() const { return m_value; } virtual wxString GetValue() const;
virtual void SetValue(const wxString& value); virtual void SetValue(const wxString& value);
// Clipboard operations // Clipboard operations
@@ -91,19 +87,18 @@ public:
virtual wxTextPos GetLastPosition() const; virtual wxTextPos GetLastPosition() const;
virtual void Replace(long from, long to, const wxString& value); virtual void Replace(long from, long to, const wxString& value);
virtual void Remove(long from, long to); virtual void Remove(long from, long to);
virtual void SetSelection(int n); virtual void SetSelection(int n) { wxChoice::SetSelection(n); }
virtual void SetSelection(long from, long to); virtual void SetSelection(long from, long to);
virtual int GetSelection() const; virtual int GetSelection() const { return wxChoice::GetSelection(); }
virtual void GetSelection(long* from, long* to) const; virtual void GetSelection(long* from, long* to) const;
virtual void SetEditable(bool editable); virtual void SetEditable(bool editable);
virtual void Clear();
virtual void Undo() ; virtual void Undo();
virtual void Redo() ; virtual void Redo();
virtual bool CanUndo() const; virtual bool CanUndo() const;
virtual bool CanRedo() const; virtual bool CanRedo() const;
virtual void SelectAll(); virtual void SelectAll();
virtual bool IsEditable() const ; virtual bool IsEditable() const;
virtual bool HasSelection() const; virtual bool HasSelection() const;
// implementation only from now on // implementation only from now on
@@ -132,17 +127,6 @@ public:
virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const; virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const;
protected:
// common part of all ctors
void Init() { m_selectionOld = -1; }
// the previous selection (see MSWCommand() to see why it is needed)
int m_selectionOld;
// the current selection (also see MSWCommand())
wxString m_value;
private: private:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxComboBox) DECLARE_DYNAMIC_CLASS_NO_COPY(wxComboBox)
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()

View File

@@ -245,15 +245,6 @@ WXLRESULT wxComboBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara
switch ( nMsg ) switch ( nMsg )
{ {
case CB_SETCURSEL:
// Selection was set with SetSelection. Update the value too.
if ((int)wParam > GetCount())
m_value.clear();
else
m_value = GetString(wParam);
m_selectionOld = -1;
break;
case WM_SIZE: case WM_SIZE:
// wxStaticBox can generate this message, when modifying the control's style. // wxStaticBox can generate this message, when modifying the control's style.
// This causes the content of the combobox to be selected, for some reason. // This causes the content of the combobox to be selected, for some reason.
@@ -326,40 +317,27 @@ bool wxComboBox::MSWProcessEditMsg(WXUINT msg, WXWPARAM wParam, WXLPARAM lParam)
bool wxComboBox::MSWCommand(WXUINT param, WXWORD id) bool wxComboBox::MSWCommand(WXUINT param, WXWORD id)
{ {
wxString value;
int sel = -1; int sel = -1;
wxString value;
switch ( param ) switch ( param )
{ {
case CBN_SELENDOK: case CBN_SELENDOK:
case CBN_SELCHANGE: // we need to reset this to prevent the selection from being undone
// by wxChoice, see wxChoice::MSWCommand() and comments there
m_lastAcceptedSelection = wxID_NONE;
// set these variables so that they could be also fixed in
// CBN_EDITCHANGE below
sel = GetSelection(); sel = GetSelection();
value = GetValue();
// we may sometimes get 2 CBN_SELCHANGE events or a CBN_SELENDOK
// before CBN_SELCHANGE with the same index when the user selects
// an item in the combobox -- ignore duplicates
if ( sel > -1 && sel != m_selectionOld )
{ {
m_selectionOld = sel;
// GetValue() would still return the old value from here but
// according to the docs we should return the new value if the
// user calls it in his event handler, so update internal
// m_value
m_value = GetString(sel);
wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, GetId()); wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, GetId());
event.SetInt(sel);
event.SetEventObject(this); event.SetEventObject(this);
event.SetString(m_value); event.SetInt(sel);
event.SetString(value);
ProcessCommand(event); ProcessCommand(event);
} }
else // no valid selection
{
m_selectionOld = sel;
// hence no EVT_TEXT neither
break;
}
// fall through: for compability with wxGTK, also send the text // fall through: for compability with wxGTK, also send the text
// update event when the selection changes (this also seems more // update event when the selection changes (this also seems more
@@ -368,29 +346,15 @@ bool wxComboBox::MSWCommand(WXUINT param, WXWORD id)
case CBN_EDITCHANGE: case CBN_EDITCHANGE:
{ {
wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId()); wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
event.SetEventObject(this);
// if sel != -1, value was initialized above (and we can't use // if sel != -1, value was already initialized above
// GetValue() here as it would return the old selection and we
// want the new one)
if ( sel == -1 ) if ( sel == -1 )
{ {
m_value = wxGetWindowText(GetHwnd()); value = wxGetWindowText(GetHwnd());
m_selectionOld = -1;
}
else // we're synthesizing text updated event from sel change
{
// We need to retrieve the current selection because the
// user may have changed it in the previous handler (for
// CBN_SELCHANGE above).
sel = GetSelection();
if ( sel > -1 )
{
m_value = GetString(sel);
}
} }
event.SetString(m_value); event.SetString(value);
event.SetEventObject(this);
ProcessCommand(event); ProcessCommand(event);
} }
break; break;
@@ -399,10 +363,9 @@ bool wxComboBox::MSWCommand(WXUINT param, WXWORD id)
return wxChoice::MSWCommand(param, id); return wxChoice::MSWCommand(param, id);
} }
// let the def window proc have it by returning false, but do not pass the // skip wxChoice version as it would generate its own events for
// message we've already handled here (notably CBN_SELCHANGE) to the base // CBN_SELENDOK
// class as it would generate another event for them return wxControl::MSWCommand(param, id);
return false;
} }
WXHWND wxComboBox::GetEditHWND() const WXHWND wxComboBox::GetEditHWND() const
@@ -517,15 +480,17 @@ WXDWORD wxComboBox::MSWGetStyle(long style, WXDWORD *exstyle) const
// wxComboBox text control-like methods // wxComboBox text control-like methods
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxString wxComboBox::GetValue() const
{
return wxGetWindowText(m_hWnd);
}
void wxComboBox::SetValue(const wxString& value) void wxComboBox::SetValue(const wxString& value)
{ {
if ( HasFlag(wxCB_READONLY) ) if ( HasFlag(wxCB_READONLY) )
SetStringSelection(value); SetStringSelection(value);
else else
SetWindowText(GetHwnd(), value.c_str()); SetWindowText(GetHwnd(), value.c_str());
m_value = value;
m_selectionOld = GetSelection();
} }
// Clipboard operations // Clipboard operations
@@ -548,7 +513,7 @@ void wxComboBox::Undo()
{ {
if (CanUndo()) if (CanUndo())
{ {
HWND hEditWnd = (HWND) GetEditHWND() ; HWND hEditWnd = (HWND) GetEditHWND();
if ( hEditWnd ) if ( hEditWnd )
::SendMessage(hEditWnd, EM_UNDO, 0, 0); ::SendMessage(hEditWnd, EM_UNDO, 0, 0);
} }
@@ -559,7 +524,7 @@ void wxComboBox::Redo()
if (CanUndo()) if (CanUndo())
{ {
// Same as Undo, since Undo undoes the undo, i.e. a redo. // Same as Undo, since Undo undoes the undo, i.e. a redo.
HWND hEditWnd = (HWND) GetEditHWND() ; HWND hEditWnd = (HWND) GetEditHWND();
if ( hEditWnd ) if ( hEditWnd )
::SendMessage(hEditWnd, EM_UNDO, 0, 0); ::SendMessage(hEditWnd, EM_UNDO, 0, 0);
} }
@@ -575,7 +540,7 @@ bool wxComboBox::CanUndo() const
if (!IsEditable()) if (!IsEditable())
return false; return false;
HWND hEditWnd = (HWND) GetEditHWND() ; HWND hEditWnd = (HWND) GetEditHWND();
if ( hEditWnd ) if ( hEditWnd )
return ::SendMessage(hEditWnd, EM_CANUNDO, 0, 0) != 0; return ::SendMessage(hEditWnd, EM_CANUNDO, 0, 0) != 0;
else else
@@ -587,7 +552,7 @@ bool wxComboBox::CanRedo() const
if (!IsEditable()) if (!IsEditable())
return false; return false;
HWND hEditWnd = (HWND) GetEditHWND() ; HWND hEditWnd = (HWND) GetEditHWND();
if ( hEditWnd ) if ( hEditWnd )
return ::SendMessage(hEditWnd, EM_CANUNDO, 0, 0) != 0; return ::SendMessage(hEditWnd, EM_CANUNDO, 0, 0) != 0;
else else
@@ -609,7 +574,7 @@ bool wxComboBox::CanCopy() const
bool wxComboBox::CanCut() const bool wxComboBox::CanCut() const
{ {
return IsEditable() && CanCopy() ; return IsEditable() && CanCopy();
} }
bool wxComboBox::CanPaste() const bool wxComboBox::CanPaste() const
@@ -647,7 +612,7 @@ void wxComboBox::SetInsertionPoint(long pos)
#ifdef __WIN32__ #ifdef __WIN32__
HWND hWnd = GetHwnd(); HWND hWnd = GetHwnd();
::SendMessage(hWnd, CB_SETEDITSEL, 0, MAKELPARAM(pos, pos)); ::SendMessage(hWnd, CB_SETEDITSEL, 0, MAKELPARAM(pos, pos));
HWND hEditWnd = (HWND) GetEditHWND() ; HWND hEditWnd = (HWND) GetEditHWND();
if ( hEditWnd ) if ( hEditWnd )
{ {
// Scroll insertion point into view // Scroll insertion point into view
@@ -743,28 +708,6 @@ void wxComboBox::GetSelection(long* from, long* to) const
} }
} }
int wxComboBox::GetSelection() const
{
return wxChoice::GetSelection();
}
void wxComboBox::Clear()
{
wxChoice::Clear();
m_selectionOld = -1;
m_value.clear();
}
// ----------------------------------------------------------------------------
// overridden wxChoice methods
// ----------------------------------------------------------------------------
void wxComboBox::SetSelection(int n)
{
wxChoice::SetSelection(n);
m_selectionOld = n;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// standard event handling // standard event handling
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -834,7 +777,7 @@ void wxComboBox::OnUpdateRedo(wxUpdateUIEvent& event)
void wxComboBox::OnUpdateDelete(wxUpdateUIEvent& event) void wxComboBox::OnUpdateDelete(wxUpdateUIEvent& event)
{ {
event.Enable(HasSelection() && IsEditable()) ; event.Enable(HasSelection() && IsEditable());
} }
void wxComboBox::OnUpdateSelectAll(wxUpdateUIEvent& event) void wxComboBox::OnUpdateSelectAll(wxUpdateUIEvent& event)