Backport for for #12143: Click anywhere inside wxListBox generates wxEVT_COMMAND_LISTBOX_SELECTED event

Needs wxUSE_LISTBOX_SELECTION_FIX to be set to 1 in include/wx/msw/listbox.h since it is not binary compatible.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@66941 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
2011-02-17 11:01:22 +00:00
parent 0dc14e5fc5
commit 689839ed87
2 changed files with 75 additions and 1 deletions

View File

@@ -14,6 +14,10 @@
#if wxUSE_LISTBOX
// Fixing spurious selection events breaks binary compatibility, so this is normally 0.
// See ticket #12143
#define wxUSE_LISTBOX_SELECTION_FIX 0
// ----------------------------------------------------------------------------
// simple types
// ----------------------------------------------------------------------------
@@ -133,6 +137,10 @@ public:
return GetCompositeControlsDefaultAttributes(variant);
}
#if wxUSE_LISTBOX_SELECTION_FIX
virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
#endif
protected:
virtual void DoSetSelection(int n, bool select);
virtual int DoAppend(const wxString& item);
@@ -158,6 +166,13 @@ protected:
wxListBoxItemsArray m_aItems;
#endif
#if wxUSE_LISTBOX_SELECTION_FIX
// flag set to true when we get a keyboard event and reset to false when we
// get a mouse one: this is used to find the correct item for the selection
// event
bool m_selectedByKeyboard;
#endif
private:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxListBox)
};

View File

@@ -145,6 +145,9 @@ wxListBox::wxListBox()
{
m_noItems = 0;
m_selected = 0;
#if wxUSE_LISTBOX_SELECTION_FIX
m_selectedByKeyboard = false;
#endif
}
bool wxListBox::Create(wxWindow *parent,
@@ -702,7 +705,46 @@ wxSize wxListBox::DoGetBestSize() const
bool wxListBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
{
wxEventType evtType;
int n;
int n = wxNOT_FOUND;
#if wxUSE_LISTBOX_SELECTION_FIX
if ( param == LBN_SELCHANGE )
{
evtType = wxEVT_COMMAND_LISTBOX_SELECTED;
if ( m_selectedByKeyboard )
{
// We shouldn't use the mouse position to find the item as mouse
// can be anywhere, ask the listbox itself. Notice that this can't
// be used when the item is selected using the mouse however as
// LB_GETCARETINDEX will always return a valid item, even if the
// mouse is clicked below all the items, which is why we find the
// item ourselves below in this case.
n = SendMessage(GetHwnd(), LB_GETCARETINDEX, 0, 0);
}
//else: n will be determined below from the mouse position
// NB: conveniently enough, LB_ERR is the same as wxNOT_FOUND
}
else if ( param == LBN_DBLCLK )
{
evtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
n = HitTest(ScreenToClient(wxGetMousePosition()));
}
else
{
// some event we're not interested in
return false;
}
// Find the item position if it was a mouse-generated selection event or a
// double click event (which is always generated using the mouse)
if ( n == wxNOT_FOUND )
{
const DWORD pos = ::GetMessagePos();
const wxPoint pt(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
n = HitTest(ScreenToClient(wxPoint(pt)));
}
#else
if ( param == LBN_SELCHANGE )
{
evtType = wxEVT_COMMAND_LISTBOX_SELECTED;
@@ -720,6 +762,7 @@ bool wxListBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
// some event we're not interested in
return false;
}
#endif
// retrieve the affected item
if ( n == wxNOT_FOUND )
@@ -740,6 +783,22 @@ bool wxListBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
return GetEventHandler()->ProcessEvent(event);
}
#if wxUSE_LISTBOX_SELECTION_FIX
WXLRESULT
wxListBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
// Remember whether there was a keyboard or mouse event before
// LBN_SELCHANGE: this allows us to correctly determine the item affected
// by it in MSWCommand() above in any case.
if ( WM_KEYFIRST <= nMsg && nMsg <= WM_KEYLAST )
m_selectedByKeyboard = true;
else if ( WM_MOUSEFIRST <= nMsg && nMsg <= WM_MOUSELAST )
m_selectedByKeyboard = false;
return wxListBoxBase::MSWWindowProc(nMsg, wParam, lParam);
}
#endif
// ----------------------------------------------------------------------------
// wxCheckListBox support
// ----------------------------------------------------------------------------