virtual void OnInternalIdle();
+ virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
+
protected:
virtual wxSize DoGetBestClientSize() const;
// i.e. if we need to call SetHorizontalExtent() from OnInternalIdle()
bool m_updateHorizontalExtent;
+ // 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;
+
DECLARE_DYNAMIC_CLASS_NO_COPY(wxListBox)
};
{
m_noItems = 0;
m_updateHorizontalExtent = false;
+ m_selectedByKeyboard = false;
}
bool wxListBox::Create(wxWindow *parent,
bool wxListBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
{
wxEventType evtType;
- int n;
+ int n = wxNOT_FOUND;
if ( param == LBN_SELCHANGE )
{
if ( HasMultipleSelection() )
return CalcAndSendEvent();
evtType = wxEVT_COMMAND_LISTBOX_SELECTED;
- n = SendMessage(GetHwnd(), LB_GETCARETINDEX, 0, 0);
- // NB: conveniently enough, LB_ERR is the same as wxNOT_FOUND
+ 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 = HitTest(ScreenToClient(wxGetMousePosition()));
+ }
}
else if ( param == LBN_DBLCLK )
{
return n != wxNOT_FOUND && SendEvent(evtType, n, true /* selection */);
}
+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);
+}
+
// ----------------------------------------------------------------------------
// owner-drawn list boxes support
// ----------------------------------------------------------------------------