+ wxEventType evtType;
+ int n = wxNOT_FOUND;
+ if ( param == LBN_SELCHANGE )
+ {
+ if ( HasMultipleSelection() )
+ return CalcAndSendEvent();
+
+ 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
+ }
+ else if ( param == LBN_DBLCLK )
+ {
+ evtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
+ }
+ 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)));
+ }
+
+ // We get events even when mouse is clicked outside of any valid item from
+ // Windows, just ignore them.
+ if ( n == wxNOT_FOUND )
+ return false;
+
+ if ( param == LBN_SELCHANGE )
+ {
+ if ( !DoChangeSingleSelection(n) )
+ return false;
+ }
+
+ // Do generate an event otherwise.
+ return SendEvent(evtType, n, true /* selection */);