diff --git a/include/wx/listbox.h b/include/wx/listbox.h index cd4c0fa6f8..01f64a7ab1 100644 --- a/include/wx/listbox.h +++ b/include/wx/listbox.h @@ -101,9 +101,6 @@ public: // send the appropriate event if they differ, otherwise just return false. bool CalcAndSendEvent(); - wxArrayInt m_oldSelections; - void UpdateOldSelections(); - protected: virtual void DoSetFirstItem(int n) = 0; @@ -118,6 +115,16 @@ protected: // Returns true if the event was processed. bool SendEvent(wxEventType evtType, int item, bool selected); + // Array storing the indices of all selected items that we already notified + // the user code about for multi selection list boxes. + // + // TODO-OPT: wxSelectionStore would be more efficient for big list boxes. + wxArrayInt m_oldSelections; + + // Update m_oldSelections with currently selected items (does nothing in + // single selection mode). + void UpdateOldSelections(); + private: wxDECLARE_NO_COPY_CLASS(wxListBoxBase); }; diff --git a/src/msw/listbox.cpp b/src/msw/listbox.cpp index 3e19b2a9f2..53d60ce89b 100644 --- a/src/msw/listbox.cpp +++ b/src/msw/listbox.cpp @@ -686,7 +686,27 @@ bool wxListBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) // We get events even when mouse is clicked outside of any valid item from // Windows, just ignore them. - return n != wxNOT_FOUND && SendEvent(evtType, n, true /* selection */); + if ( n == wxNOT_FOUND ) + return false; + + // As we don't use m_oldSelections in single selection mode, we store the + // last item that we notified the user about in it in this case because we + // need to remember it to be able to filter out the dummy LBN_SELCHANGE + // messages that we get when the user clicks on an already selected item. + if ( param == LBN_SELCHANGE ) + { + if ( !m_oldSelections.empty() && *m_oldSelections.begin() == n ) + { + // Same item as the last time. + return false; + } + + m_oldSelections.clear(); + m_oldSelections.push_back(n); + } + + // Do generate an event otherwise. + return SendEvent(evtType, n, true /* selection */); } WXLRESULT