+void wxVListBox::InitEvent(wxCommandEvent& event, int n)
+{
+ event.SetEventObject(this);
+ event.SetInt(n);
+}
+
+void wxVListBox::SendSelectedEvent()
+{
+ wxASSERT_MSG( m_current != wxNOT_FOUND,
+ _T("SendSelectedEvent() shouldn't be called") );
+
+ wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, GetId());
+ InitEvent(event, m_current);
+ (void)GetEventHandler()->ProcessEvent(event);
+}
+
+void wxVListBox::SetSelection(int selection)
+{
+ wxCHECK_RET( selection == wxNOT_FOUND ||
+ (selection >= 0 && (size_t)selection < GetItemCount()),
+ _T("wxVListBox::SetSelection(): invalid item index") );
+
+ if ( HasMultipleSelection() )
+ {
+ if (selection != wxNOT_FOUND)
+ Select(selection);
+ else
+ DeselectAll();
+ m_anchor = selection;
+ }
+
+ DoSetCurrent(selection);
+}
+
+size_t wxVListBox::GetSelectedCount() const
+{
+ return m_selStore ? m_selStore->GetSelectedCount()
+ : m_current == wxNOT_FOUND ? 0 : 1;
+}
+
+int wxVListBox::GetFirstSelected(unsigned long& cookie) const
+{
+ cookie = 0;
+
+ return GetNextSelected(cookie);
+}
+
+int wxVListBox::GetNextSelected(unsigned long& cookie) const
+{
+ wxCHECK_MSG( m_selStore, wxNOT_FOUND,
+ _T("GetFirst/NextSelected() may only be used with multiselection listboxes") );
+
+ while ( cookie < GetItemCount() )
+ {
+ if ( IsSelected(cookie++) )
+ return cookie - 1;
+ }
+
+ return wxNOT_FOUND;
+}
+
+void wxVListBox::RefreshSelected()
+{
+ // only refresh those items which are currently visible and selected:
+ for ( size_t n = GetVisibleBegin(), end = GetVisibleEnd(); n < end; n++ )
+ {
+ if ( IsSelected(n) )
+ RefreshRow(n);
+ }
+}
+
+wxRect wxVListBox::GetItemRect(size_t n) const
+{
+ wxRect itemrect;
+
+ // check that this item is visible
+ const size_t lineMax = GetVisibleEnd();
+ if ( n >= lineMax )
+ return itemrect;
+ size_t line = GetVisibleBegin();
+ if ( n < line )
+ return itemrect;
+
+ while ( line <= n )
+ {
+ itemrect.y += itemrect.height;
+ itemrect.height = OnGetRowHeight(line);
+
+ line++;