]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/listctrl.cpp
remove duplicated HitTest implementation from wxCheckListBox, it already inherits...
[wxWidgets.git] / src / generic / listctrl.cpp
index 7a63129ecdfa40806c58caaca9db24c0859673d2..f33e2b1437adc2b1757254fee60d8a0dd947126b 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "wx/listctrl.h"
 
-#if (!defined(__WXMSW__) || defined(__WXUNIVERSAL__)) && !defined(__WXMAC__)
+#if ((!defined(__WXMSW__) && !(defined(__WXMAC__) && wxOSX_USE_CARBON)) || defined(__WXUNIVERSAL__))
     // if we have a native version, its implementation file does all this
     IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject)
     IMPLEMENT_DYNAMIC_CLASS(wxListView, wxListCtrl)
@@ -43,6 +43,7 @@
     #include "wx/dcscreen.h"
     #include "wx/math.h"
     #include "wx/settings.h"
+    #include "wx/sizer.h"
 #endif
 
 #include "wx/imaglist.h"
@@ -50,7 +51,9 @@
 #include "wx/renderer.h"
 
 #ifdef __WXMAC__
-    #include "wx/mac/private.h"
+    #include "wx/osx/private.h"
+    // for themeing support
+    #include <Carbon/Carbon.h>
 #endif
 
 
@@ -77,7 +80,12 @@ static const int EXTRA_WIDTH = 6;
 #else
 static const int EXTRA_WIDTH = 4;
 #endif
+
+#ifdef __WXGTK__
+static const int EXTRA_HEIGHT = 6;
+#else
 static const int EXTRA_HEIGHT = 4;
+#endif
 
 // margin between the window and the items
 static const int EXTRA_BORDER_X = 2;
@@ -243,7 +251,7 @@ private:
 //  wxListLineData (internal)
 //-----------------------------------------------------------------------------
 
-WX_DECLARE_EXPORTED_LIST(wxListItemData, wxListItemDataList);
+WX_DECLARE_LIST(wxListItemData, wxListItemDataList);
 #include "wx/listimpl.cpp"
 WX_DEFINE_LIST(wxListItemDataList)
 
@@ -375,7 +383,7 @@ private:
                            int width);
 };
 
-WX_DECLARE_EXPORTED_OBJARRAY(wxListLineData, wxListLineDataArray);
+WX_DECLARE_OBJARRAY(wxListLineData, wxListLineDataArray);
 #include "wx/arrimpl.cpp"
 WX_DEFINE_OBJARRAY(wxListLineDataArray)
 
@@ -424,6 +432,13 @@ public:
     // needs refresh
     bool m_dirty;
 
+    // Update main window's column later
+    bool m_sendSetColumnWidth;
+    int m_colToSend;
+    int m_widthToSend;
+
+    virtual void OnInternalIdle();
+
 private:
     // common part of all ctors
     void Init();
@@ -432,7 +447,6 @@ private:
     // it wasn't vetoed, i.e. if we should proceed
     bool SendListEvent(wxEventType type, const wxPoint& pos);
 
-    DECLARE_DYNAMIC_CLASS(wxListHeaderWindow)
     DECLARE_EVENT_TABLE()
 };
 
@@ -464,7 +478,7 @@ public:
 
     wxTextCtrl *GetText() const { return m_text; }
 
-    void AcceptChangesAndFinish();
+    void EndEdit( bool discardChanges );
 
 protected:
     void OnChar( wxKeyEvent &event );
@@ -472,14 +486,13 @@ protected:
     void OnKillFocus( wxFocusEvent &event );
 
     bool AcceptChanges();
-    void Finish();
+    void Finish( bool setfocus );
 
 private:
     wxListMainWindow   *m_owner;
     wxTextCtrl         *m_text;
     wxString            m_startValue;
     size_t              m_itemEdited;
-    bool                m_finished;
     bool                m_aboutToFinish;
 
     DECLARE_EVENT_TABLE()
@@ -489,11 +502,11 @@ private:
 //  wxListMainWindow (internal)
 //-----------------------------------------------------------------------------
 
-WX_DECLARE_EXPORTED_LIST(wxListHeaderData, wxListHeaderDataList);
+WX_DECLARE_LIST(wxListHeaderData, wxListHeaderDataList);
 #include "wx/listimpl.cpp"
 WX_DEFINE_LIST(wxListHeaderDataList)
 
-class wxListMainWindow : public wxScrolledWindow
+class wxListMainWindow : public wxWindow
 {
 public:
     wxListMainWindow();
@@ -593,17 +606,12 @@ public:
         return m_textctrlWrapper ? m_textctrlWrapper->GetText() : NULL;
     }
 
-    void FinishEditing(wxTextCtrl *text)
+    void ResetTextControl(wxTextCtrl *text)
     {
         delete text;
         m_textctrlWrapper = NULL;
-        SetFocusIgnoringChildren();
     }
 
-    // suspend/resume redrawing the control
-    void Freeze();
-    void Thaw();
-
     void OnRenameTimer();
     bool OnRenameAccept(size_t itemEdit, const wxString& value);
     void OnRenameCancelled(size_t itemEdit);
@@ -622,6 +630,8 @@ public:
 
     void OnPaint( wxPaintEvent &event );
 
+    void OnChildFocus(wxChildFocusEvent& event);
+
     void DrawImage( int index, wxDC *dc, int x, int y );
     void GetImageSize( int index, int &width, int &height ) const;
     int GetTextLength( const wxString &s ) const;
@@ -646,7 +656,11 @@ public:
     void SetItemState( long item, long state, long stateMask );
     void SetItemStateAll( long state, long stateMask );
     int GetItemState( long item, long stateMask ) const;
-    void GetItemRect( long index, wxRect &rect ) const;
+    bool GetItemRect( long item, wxRect &rect ) const
+    {
+        return GetSubItemRect(item, wxLIST_GETSUBITEMRECT_WHOLEITEM, rect);
+    }
+    bool GetSubItemRect( long item, long subItem, wxRect& rect ) const;
     wxRect GetViewRect() const;
     bool GetItemPosition( long item, wxPoint& pos ) const;
     int GetSelectedItemCount() const;
@@ -707,7 +721,7 @@ public:
     // override base class virtual to reset m_lineHeight when the font changes
     virtual bool SetFont(const wxFont& font)
     {
-        if ( !wxScrolledWindow::SetFont(font) )
+        if ( !wxWindow::SetFont(font) )
             return false;
 
         m_lineHeight = 0;
@@ -850,15 +864,11 @@ private:
     wxBrush *m_highlightBrush,
             *m_highlightUnfocusedBrush;
 
-    // if this is > 0, the control is frozen and doesn't redraw itself
-    size_t m_freezeCount;
-
     // wrapper around the text control currently used for in place editing or
     // NULL if no item is being edited
     wxListTextCtrlWrapper *m_textctrlWrapper;
 
 
-    DECLARE_DYNAMIC_CLASS(wxListMainWindow)
     DECLARE_EVENT_TABLE()
 
     friend class wxGenericListCtrl;
@@ -1417,7 +1427,7 @@ bool wxListLineData::SetAttributes(wxDC *dc,
 #ifdef __WXMAC__
     {
         if (m_owner->HasFocus()
-#if !defined(__WXUNIVERSAL__)
+#if !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON
                 && IsControlActive( (ControlRef)m_owner->GetHandle() )
 #endif
         )
@@ -1451,7 +1461,7 @@ bool wxListLineData::SetAttributes(wxDC *dc,
         if ( highlighted )
             dc->SetBrush( *m_owner->GetHighlightBrush() );
         else
-            dc->SetBrush(wxBrush(attr->GetBackgroundColour(), wxSOLID));
+            dc->SetBrush(wxBrush(attr->GetBackgroundColour(), wxBRUSHSTYLE_SOLID));
 
         dc->SetPen( *wxTRANSPARENT_PEN );
 
@@ -1481,7 +1491,7 @@ void wxListLineData::Draw( wxDC *dc )
         {
             int flags = wxCONTROL_SELECTED;
             if (m_owner->HasFocus()
-#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__)
+#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON
                 && IsControlActive( (ControlRef)m_owner->GetHandle() )
 #endif
             )
@@ -1574,6 +1584,9 @@ void wxListLineData::DrawInReportMode( wxDC *dc,
         int xOld = x;
         x += width;
 
+        const int wText = width - 8;
+        wxDCClipper clipper(*dc, xOld, rect.y, wText, rect.height);
+
         if ( item->HasImage() )
         {
             int ix, iy;
@@ -1587,7 +1600,7 @@ void wxListLineData::DrawInReportMode( wxDC *dc,
         }
 
         if ( item->HasText() )
-            DrawTextFormatted(dc, item->GetText(), col, xOld, yMid, width - 8);
+            DrawTextFormatted(dc, item->GetText(), col, xOld, yMid, wText);
     }
 }
 
@@ -1692,8 +1705,6 @@ void wxListLineData::ReverseHighlight( void )
 //  wxListHeaderWindow
 //-----------------------------------------------------------------------------
 
-IMPLEMENT_DYNAMIC_CLASS(wxListHeaderWindow,wxWindow)
-
 BEGIN_EVENT_TABLE(wxListHeaderWindow,wxWindow)
     EVT_PAINT         (wxListHeaderWindow::OnPaint)
     EVT_MOUSE_EVENTS  (wxListHeaderWindow::OnMouse)
@@ -1702,17 +1713,18 @@ END_EVENT_TABLE()
 
 void wxListHeaderWindow::Init()
 {
-    m_currentCursor = (wxCursor *) NULL;
+    m_currentCursor = NULL;
     m_isDragging = false;
     m_dirty = false;
+    m_sendSetColumnWidth = false;
 }
 
 wxListHeaderWindow::wxListHeaderWindow()
 {
     Init();
 
-    m_owner = (wxListMainWindow *) NULL;
-    m_resizeCursor = (wxCursor *) NULL;
+    m_owner = NULL;
+    m_resizeCursor = NULL;
 }
 
 wxListHeaderWindow::wxListHeaderWindow( wxWindow *win,
@@ -1757,11 +1769,13 @@ wxListHeaderWindow::~wxListHeaderWindow()
 // scrollbar: this allows us to always use logical coords
 void wxListHeaderWindow::AdjustDC(wxDC& dc)
 {
+    wxGenericListCtrl *parent = m_owner->GetListCtrl();
+
     int xpix;
-    m_owner->GetScrollPixelsPerUnit( &xpix, NULL );
+    parent->GetScrollPixelsPerUnit( &xpix, NULL );
 
     int view_start;
-    m_owner->GetViewStart( &view_start, NULL );
+    parent->GetViewStart( &view_start, NULL );
 
 
     int org_x = 0;
@@ -1784,9 +1798,10 @@ void wxListHeaderWindow::AdjustDC(wxDC& dc)
 
 void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
 {
+    wxGenericListCtrl *parent = m_owner->GetListCtrl();
+
     wxPaintDC dc( this );
 
-    PrepareDC( dc );
     AdjustDC( dc );
 
     dc.SetFont( GetFont() );
@@ -1794,9 +1809,9 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
     // width and height of the entire header window
     int w, h;
     GetClientSize( &w, &h );
-    m_owner->CalcUnscrolledPosition(w, 0, &w, NULL);
+    parent->CalcUnscrolledPosition(w, 0, &w, NULL);
 
-    dc.SetBackgroundMode(wxTRANSPARENT);
+    dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
     dc.SetTextForeground(GetForegroundColour());
 
     int x = HEADER_OFFSET_X;
@@ -1824,6 +1839,9 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
             flags |= wxCONTROL_SELECTED;
 #endif
 
+        if (i == 0)
+           flags |= wxCONTROL_SPECIAL; // mark as first column
+
         wxRendererNative::Get().DrawHeaderButton
                                 (
                                     this,
@@ -1901,12 +1919,39 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
 
         x += wCol;
     }
+
+    // Fill in what's missing to the right of the columns, otherwise we will
+    // leave an unpainted area when columns are removed (and it looks better)
+    if ( x < w )
+    {
+        wxRendererNative::Get().DrawHeaderButton
+                                (
+                                    this,
+                                    dc,
+                                    wxRect(x, HEADER_OFFSET_Y, w - x, h),
+                                    wxCONTROL_DIRTY // mark as last column
+                                );
+    }
+}
+
+void wxListHeaderWindow::OnInternalIdle()
+{
+    wxWindow::OnInternalIdle();
+
+    if (m_sendSetColumnWidth)
+    {
+        m_owner->SetColumnWidth( m_colToSend, m_widthToSend );
+        m_sendSetColumnWidth = false;
+    }
 }
 
 void wxListHeaderWindow::DrawCurrent()
 {
 #if 1
-    m_owner->SetColumnWidth( m_column, m_currentX - m_minX );
+    // m_owner->SetColumnWidth( m_column, m_currentX - m_minX );
+    m_sendSetColumnWidth = true;
+    m_colToSend = m_column;
+    m_widthToSend = m_currentX - m_minX;
 #else
     int x1 = m_currentX;
     int y1 = 0;
@@ -1935,9 +1980,11 @@ void wxListHeaderWindow::DrawCurrent()
 
 void wxListHeaderWindow::OnMouse( wxMouseEvent &event )
 {
+    wxGenericListCtrl *parent = m_owner->GetListCtrl();
+
     // we want to work with logical coords
     int x;
-    m_owner->CalcUnscrolledPosition(event.GetX(), 0, &x, NULL);
+    parent->CalcUnscrolledPosition(event.GetX(), 0, &x, NULL);
     int y = event.GetY();
 
     if (m_isDragging)
@@ -1948,7 +1995,7 @@ void wxListHeaderWindow::OnMouse( wxMouseEvent &event )
         // there
         int w = 0;
         GetClientSize( &w, NULL );
-        m_owner->CalcUnscrolledPosition(w, 0, &w, NULL);
+        parent->CalcUnscrolledPosition(w, 0, &w, NULL);
         w -= 6;
 
         // erase the line if it was drawn
@@ -2123,12 +2170,13 @@ wxListTextCtrlWrapper::wxListTextCtrlWrapper(wxListMainWindow *owner,
 {
     m_owner = owner;
     m_text = text;
-    m_finished = false;
     m_aboutToFinish = false;
 
+    wxGenericListCtrl *parent = m_owner->GetListCtrl();
+
     wxRect rectLabel = owner->GetLineLabelRect(itemEdit);
 
-    m_owner->CalcScrolledPosition(rectLabel.x, rectLabel.y,
+    parent->CalcScrolledPosition(rectLabel.x, rectLabel.y,
                                   &rectLabel.x, &rectLabel.y);
 
     m_text->Create(owner, wxID_ANY, m_startValue,
@@ -2139,19 +2187,37 @@ wxListTextCtrlWrapper::wxListTextCtrlWrapper(wxListMainWindow *owner,
     m_text->PushEventHandler(this);
 }
 
-void wxListTextCtrlWrapper::Finish()
+void wxListTextCtrlWrapper::EndEdit(bool discardChanges)
 {
-    if ( !m_finished )
+    m_aboutToFinish = true;
+
+    if ( discardChanges )
     {
-        m_finished = true;
+        m_owner->OnRenameCancelled(m_itemEdited);
 
-        m_text->RemoveEventHandler(this);
-        m_owner->FinishEditing(m_text);
+        Finish( true );
+    }
+    else
+    {
+        // Notify the owner about the changes
+        AcceptChanges();
 
-        wxPendingDelete.Append( this );
+        // Even if vetoed, close the control (consistent with MSW)
+        Finish( true );
     }
 }
 
+void wxListTextCtrlWrapper::Finish( bool setfocus )
+{
+    m_text->RemoveEventHandler(this);
+    m_owner->ResetTextControl( m_text );
+
+    wxPendingDelete.Append( this );
+
+    if (setfocus)
+        m_owner->SetFocus();
+}
+
 bool wxListTextCtrlWrapper::AcceptChanges()
 {
     const wxString value = m_text->GetValue();
@@ -2171,28 +2237,16 @@ bool wxListTextCtrlWrapper::AcceptChanges()
     return true;
 }
 
-void wxListTextCtrlWrapper::AcceptChangesAndFinish()
-{
-    m_aboutToFinish = true;
-
-    // Notify the owner about the changes
-    AcceptChanges();
-
-    // Even if vetoed, close the control (consistent with MSW)
-    Finish();
-}
-
 void wxListTextCtrlWrapper::OnChar( wxKeyEvent &event )
 {
     switch ( event.m_keyCode )
     {
         case WXK_RETURN:
-            AcceptChangesAndFinish();
+            EndEdit( false );
             break;
 
         case WXK_ESCAPE:
-            m_owner->OnRenameCancelled( m_itemEdited );
-            Finish();
+            EndEdit( true );
             break;
 
         default:
@@ -2202,35 +2256,32 @@ void wxListTextCtrlWrapper::OnChar( wxKeyEvent &event )
 
 void wxListTextCtrlWrapper::OnKeyUp( wxKeyEvent &event )
 {
-    if (m_finished)
+    if (m_aboutToFinish)
     {
-        event.Skip();
-        return;
+        // auto-grow the textctrl:
+        wxSize parentSize = m_owner->GetSize();
+        wxPoint myPos = m_text->GetPosition();
+        wxSize mySize = m_text->GetSize();
+        int sx, sy;
+        m_text->GetTextExtent(m_text->GetValue() + _T("MM"), &sx, &sy);
+        if (myPos.x + sx > parentSize.x)
+            sx = parentSize.x - myPos.x;
+       if (mySize.x > sx)
+            sx = mySize.x;
+       m_text->SetSize(sx, wxDefaultCoord);
     }
 
-    // auto-grow the textctrl:
-    wxSize parentSize = m_owner->GetSize();
-    wxPoint myPos = m_text->GetPosition();
-    wxSize mySize = m_text->GetSize();
-    int sx, sy;
-    m_text->GetTextExtent(m_text->GetValue() + _T("MM"), &sx, &sy);
-    if (myPos.x + sx > parentSize.x)
-        sx = parentSize.x - myPos.x;
-    if (mySize.x > sx)
-        sx = mySize.x;
-    m_text->SetSize(sx, wxDefaultCoord);
-
     event.Skip();
 }
 
 void wxListTextCtrlWrapper::OnKillFocus( wxFocusEvent &event )
 {
-    if ( !m_finished && !m_aboutToFinish )
+    if ( !m_aboutToFinish )
     {
         if ( !AcceptChanges() )
             m_owner->OnRenameCancelled( m_itemEdited );
 
-        Finish();
+        Finish( false );
     }
 
     // We must let the native text control handle focus
@@ -2241,9 +2292,7 @@ void wxListTextCtrlWrapper::OnKillFocus( wxFocusEvent &event )
 //  wxListMainWindow
 //-----------------------------------------------------------------------------
 
-IMPLEMENT_DYNAMIC_CLASS(wxListMainWindow,wxScrolledWindow)
-
-BEGIN_EVENT_TABLE(wxListMainWindow,wxScrolledWindow)
+BEGIN_EVENT_TABLE(wxListMainWindow,wxScrolledCanvas)
   EVT_PAINT          (wxListMainWindow::OnPaint)
   EVT_MOUSE_EVENTS   (wxListMainWindow::OnMouse)
   EVT_CHAR           (wxListMainWindow::OnChar)
@@ -2252,6 +2301,7 @@ BEGIN_EVENT_TABLE(wxListMainWindow,wxScrolledWindow)
   EVT_SET_FOCUS      (wxListMainWindow::OnSetFocus)
   EVT_KILL_FOCUS     (wxListMainWindow::OnKillFocus)
   EVT_SCROLLWIN      (wxListMainWindow::OnScroll)
+  EVT_CHILD_FOCUS    (wxListMainWindow::OnChildFocus)
 END_EVENT_TABLE()
 
 void wxListMainWindow::Init()
@@ -2265,8 +2315,8 @@ void wxListMainWindow::Init()
     m_headerWidth =
     m_lineHeight = 0;
 
-    m_small_image_list = (wxImageList *) NULL;
-    m_normal_image_list = (wxImageList *) NULL;
+    m_small_image_list = NULL;
+    m_normal_image_list = NULL;
 
     m_small_spacing = 30;
     m_normal_spacing = 40;
@@ -2283,8 +2333,6 @@ void wxListMainWindow::Init()
     m_lineLastClicked =
     m_lineSelectSingleOnUp =
     m_lineBeforeLastClicked = (size_t)-1;
-
-    m_freezeCount = 0;
 }
 
 wxListMainWindow::wxListMainWindow()
@@ -2292,7 +2340,7 @@ wxListMainWindow::wxListMainWindow()
     Init();
 
     m_highlightBrush =
-    m_highlightUnfocusedBrush = (wxBrush *) NULL;
+    m_highlightUnfocusedBrush = NULL;
 }
 
 wxListMainWindow::wxListMainWindow( wxWindow *parent,
@@ -2301,8 +2349,7 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent,
                                     const wxSize& size,
                                     long style,
                                     const wxString &name )
-                : wxScrolledWindow( parent, id, pos, size,
-                                    style | wxHSCROLL | wxVSCROLL, name )
+                : wxWindow( parent, id, pos, size, style, name )
 {
     Init();
 
@@ -2312,7 +2359,7 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent,
                             (
                                 wxSYS_COLOUR_HIGHLIGHT
                             ),
-                            wxSOLID
+                            wxBRUSHSTYLE_SOLID
                          );
 
     m_highlightUnfocusedBrush = new wxBrush
@@ -2321,11 +2368,9 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent,
                                  (
                                      wxSYS_COLOUR_BTNSHADOW
                                  ),
-                                 wxSOLID
+                                 wxBRUSHSTYLE_SOLID
                               );
 
-    SetScrollbars( 0, 0, 0, 0, 0, 0 );
-
     wxVisualAttributes attr = wxGenericListCtrl::GetClassDefaultAttributes();
     SetOwnForegroundColour( attr.colFg );
     SetOwnBackgroundColour( attr.colBg );
@@ -2604,7 +2649,7 @@ void wxListMainWindow::RefreshLine( size_t line )
 
     wxRect rect = GetLineRect(line);
 
-    CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
+    GetListCtrl()->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
     RefreshRect( rect );
 }
 
@@ -2631,7 +2676,7 @@ void wxListMainWindow::RefreshLines( size_t lineFrom, size_t lineTo )
         rect.width = GetClientSize().x;
         rect.height = GetLineY(lineTo) - rect.y + GetLineHeight();
 
-        CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
+        GetListCtrl()->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
         RefreshRect( rect );
     }
     else // !report
@@ -2659,7 +2704,7 @@ void wxListMainWindow::RefreshAfter( size_t lineFrom )
         wxRect rect;
         rect.x = 0;
         rect.y = GetLineY(lineFrom);
-        CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
+        GetListCtrl()->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
 
         wxSize size = GetClientSize();
         rect.width = size.x;
@@ -2703,37 +2748,25 @@ void wxListMainWindow::RefreshSelected()
     }
 }
 
-void wxListMainWindow::Freeze()
-{
-    m_freezeCount++;
-}
-
-void wxListMainWindow::Thaw()
-{
-    wxCHECK_RET( m_freezeCount > 0, _T("thawing unfrozen list control?") );
-
-    if ( --m_freezeCount == 0 )
-        Refresh();
-}
-
 void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
 {
     // Note: a wxPaintDC must be constructed even if no drawing is
     // done (a Windows requirement).
     wxPaintDC dc( this );
 
-    if ( IsEmpty() || m_freezeCount )
+    if ( IsEmpty() )
+    {
         // nothing to draw or not the moment to draw it
         return;
+    }
 
     if ( m_dirty )
-        // delay the repainting until we calculate all the items positions
-        return;
+        RecalculatePositions( false );
 
-    PrepareDC( dc );
+    GetListCtrl()->PrepareDC( dc );
 
     int dev_x, dev_y;
-    CalcScrolledPosition( 0, 0, &dev_x, &dev_y );
+    GetListCtrl()->CalcScrolledPosition( 0, 0, &dev_x, &dev_y );
 
     dc.SetFont( GetFont() );
 
@@ -2779,7 +2812,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
 
         if ( HasFlag(wxLC_HRULES) )
         {
-            wxPen pen(GetRuleColour(), 1, wxSOLID);
+            wxPen pen(GetRuleColour(), 1, wxPENSTYLE_SOLID);
             wxSize clientSize = GetClientSize();
 
             size_t i = visibleFrom;
@@ -2805,7 +2838,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
         // Draw vertical rules if required
         if ( HasFlag(wxLC_VRULES) && !IsEmpty() )
         {
-            wxPen pen(GetRuleColour(), 1, wxSOLID);
+            wxPen pen(GetRuleColour(), 1, wxPENSTYLE_SOLID);
             wxRect firstItemRect, lastItemRect;
 
             GetItemRect(visibleFrom, firstItemRect);
@@ -2874,6 +2907,13 @@ void wxListMainWindow::HighlightAll( bool on )
     }
 }
 
+void wxListMainWindow::OnChildFocus(wxChildFocusEvent& WXUNUSED(event))
+{
+    // Do nothing here.  This prevents the default handler in wxScrolledWindow
+    // from needlessly scrolling the window when the edit control is
+    // dismissed.  See ticket #9563.
+}
+
 void wxListMainWindow::SendNotify( size_t line,
                                    wxEventType command,
                                    const wxPoint& point )
@@ -3005,11 +3045,11 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
     // listctrl because the order of events is different (or something like
     // that), so explicitly end the edit if it is active.
     if ( event.LeftDown() && m_textctrlWrapper )
-        m_textctrlWrapper->AcceptChangesAndFinish();
+        m_textctrlWrapper->EndEdit( false );
 #endif // __WXMAC__
 
     if ( event.LeftDown() )
-        SetFocusIgnoringChildren();
+        SetFocus();
 
     event.SetEventObject( GetParent() );
     if ( GetParent()->GetEventHandler()->ProcessEvent( event) )
@@ -3047,7 +3087,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
 
     int x = event.GetX();
     int y = event.GetY();
-    CalcUnscrolledPosition( x, y, &x, &y );
+    GetListCtrl()->CalcUnscrolledPosition( x, y, &x, &y );
 
     // where did we hit it (if we did)?
     long hitResult = 0;
@@ -3292,9 +3332,9 @@ void wxListMainWindow::MoveToItem(size_t item)
         ResetVisibleLinesRange();
 
         if (rect.y < view_y)
-            Scroll( -1, rect.y / hLine );
+            GetListCtrl()->Scroll( -1, rect.y / hLine );
         if (rect.y + rect.height + 5 > view_y + client_h)
-            Scroll( -1, (rect.y + rect.height - client_h + hLine) / hLine );
+            GetListCtrl()->Scroll( -1, (rect.y + rect.height - client_h + hLine) / hLine );
 
 #ifdef __WXMAC__
         // At least on Mac the visible lines value will get reset inside of
@@ -3309,10 +3349,20 @@ void wxListMainWindow::MoveToItem(size_t item)
     }
     else // !report
     {
+        int sx = -1,
+            sy = -1;
+
         if (rect.x-view_x < 5)
-            Scroll( (rect.x - 5) / SCROLL_UNIT_X, -1 );
+            sx = (rect.x - 5) / SCROLL_UNIT_X;
         if (rect.x + rect.width - 5 > view_x + client_w)
-            Scroll( (rect.x + rect.width - client_w + SCROLL_UNIT_X) / SCROLL_UNIT_X, -1 );
+            sx = (rect.x + rect.width - client_w + SCROLL_UNIT_X) / SCROLL_UNIT_X;
+
+        if (rect.y-view_y < 5)
+            sy = (rect.y - 5) / hLine;
+        if (rect.y + rect.height - 5 > view_y + client_h)
+            sy = (rect.y + rect.height - client_h + hLine) / hLine;
+
+        GetListCtrl()->Scroll(sx, sy);
     }
 }
 
@@ -3334,7 +3384,7 @@ bool wxListMainWindow::ScrollList(int WXUNUSED(dx), int dy)
 
     int hLine = GetLineHeight();
 
-    Scroll(-1, top + dy / hLine);
+    GetListCtrl()->Scroll(-1, top + dy / hLine);
 
 #ifdef __WXMAC__
     // see comment in MoveToItem() for why we do this
@@ -3400,16 +3450,10 @@ void wxListMainWindow::OnKeyDown( wxKeyEvent &event )
     wxWindow *parent = GetParent();
 
     // propagate the key event upwards
-    wxKeyEvent ke( wxEVT_KEY_DOWN );
-    ke.m_shiftDown = event.m_shiftDown;
-    ke.m_controlDown = event.m_controlDown;
-    ke.m_altDown = event.m_altDown;
-    ke.m_metaDown = event.m_metaDown;
-    ke.m_keyCode = event.m_keyCode;
-    ke.m_x = event.m_x;
-    ke.m_y = event.m_y;
+    wxKeyEvent ke(event);
     ke.SetEventObject( parent );
-    if (parent->GetEventHandler()->ProcessEvent( ke )) return;
+    if (parent->GetEventHandler()->ProcessEvent( ke ))
+        return;
 
     event.Skip();
 }
@@ -3419,16 +3463,9 @@ void wxListMainWindow::OnKeyUp( wxKeyEvent &event )
     wxWindow *parent = GetParent();
 
     // propagate the key event upwards
-    wxKeyEvent ke( wxEVT_KEY_UP );
-    ke.m_shiftDown = event.m_shiftDown;
-    ke.m_controlDown = event.m_controlDown;
-    ke.m_altDown = event.m_altDown;
-    ke.m_metaDown = event.m_metaDown;
-    ke.m_keyCode = event.m_keyCode;
-    ke.m_x = event.m_x;
-    ke.m_y = event.m_y;
-    ke.SetEventObject( parent );
-    if (parent->GetEventHandler()->ProcessEvent( ke )) return;
+    wxKeyEvent ke(event);
+    if (parent->GetEventHandler()->ProcessEvent( ke ))
+        return;
 
     event.Skip();
 }
@@ -3448,29 +3485,25 @@ void wxListMainWindow::OnChar( wxKeyEvent &event )
         parent->GetEventHandler()->ProcessEvent( le );
     }
 
-    // propagate the char event upwards
-    wxKeyEvent ke( wxEVT_CHAR );
-    ke.m_shiftDown = event.m_shiftDown;
-    ke.m_controlDown = event.m_controlDown;
-    ke.m_altDown = event.m_altDown;
-    ke.m_metaDown = event.m_metaDown;
-    ke.m_keyCode = event.m_keyCode;
-    ke.m_x = event.m_x;
-    ke.m_y = event.m_y;
-    ke.SetEventObject( parent );
-    if (parent->GetEventHandler()->ProcessEvent( ke )) return;
-
-    if (event.GetKeyCode() == WXK_TAB)
+    if ( (event.GetKeyCode() != WXK_UP) &&
+         (event.GetKeyCode() != WXK_DOWN) &&
+         (event.GetKeyCode() != WXK_RIGHT) &&
+         (event.GetKeyCode() != WXK_LEFT) &&
+         (event.GetKeyCode() != WXK_PAGEUP) &&
+         (event.GetKeyCode() != WXK_PAGEDOWN) &&
+         (event.GetKeyCode() != WXK_END) &&
+         (event.GetKeyCode() != WXK_HOME) )
     {
-        wxNavigationKeyEvent nevent;
-        nevent.SetWindowChange( event.ControlDown() );
-        nevent.SetDirection( !event.ShiftDown() );
-        nevent.SetEventObject( GetParent()->GetParent() );
-        nevent.SetCurrentFocus( m_parent );
-        if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent ))
+        // propagate the char event upwards
+        wxKeyEvent ke(event);
+        ke.SetEventObject( parent );
+        if (parent->GetEventHandler()->ProcessEvent( ke ))
             return;
     }
 
+    if ( HandleAsNavigationKey(event) )
+        return;
+
     // no item -> nothing to do
     if (!HasCurrent())
     {
@@ -3761,6 +3794,7 @@ void wxListMainWindow::SetColumnWidth( int col, int width )
                  _T("SetColumnWidth() can only be called in report mode.") );
 
     m_dirty = true;
+
     wxListHeaderWindow *headerWin = GetListCtrl()->m_headerWin;
     if ( headerWin )
         headerWin->m_dirty = true;
@@ -4129,8 +4163,7 @@ int wxListMainWindow::GetSelectedItemCount() const
 
 wxRect wxListMainWindow::GetViewRect() const
 {
-    wxASSERT_MSG( !HasFlag(wxLC_REPORT | wxLC_LIST),
-                    _T("wxListCtrl::GetViewRect() only works in icon mode") );
+    wxASSERT_MSG( !HasFlag(wxLC_LIST), "not implemented for list view" );
 
     // we need to find the longest/tallest label
     wxCoord xMax = 0, yMax = 0;
@@ -4139,8 +4172,9 @@ wxRect wxListMainWindow::GetViewRect() const
     {
         for ( int i = 0; i < count; i++ )
         {
-            wxRect r;
-            GetItemRect(i, r);
+            // we need logical, not physical, coordinates here, so use
+            // GetLineRect() instead of GetItemRect()
+            wxRect r = GetLineRect(i);
 
             wxCoord x = r.GetRight(),
                     y = r.GetBottom();
@@ -4166,10 +4200,14 @@ wxRect wxListMainWindow::GetViewRect() const
     return wxRect(0, 0, xMax, yMax);
 }
 
-void wxListMainWindow::GetItemRect( long index, wxRect &rect ) const
+bool
+wxListMainWindow::GetSubItemRect(long item, long subItem, wxRect& rect) const
 {
-    wxCHECK_RET( index >= 0 && (size_t)index < GetItemCount(),
-                 _T("invalid index in GetItemRect") );
+    wxCHECK_MSG( subItem == wxLIST_GETSUBITEMRECT_WHOLEITEM || InReportView(),
+                 false,
+                 _T("GetSubItemRect only meaningful in report view") );
+    wxCHECK_MSG( item >= 0 && (size_t)item < GetItemCount(), false,
+                 _T("invalid item in GetSubItemRect") );
 
     // ensure that we're laid out, otherwise we could return nonsense
     if ( m_dirty )
@@ -4178,9 +4216,24 @@ void wxListMainWindow::GetItemRect( long index, wxRect &rect ) const
             RecalculatePositions(true /* no refresh */);
     }
 
-    rect = GetLineRect((size_t)index);
+    rect = GetLineRect((size_t)item);
+
+    // Adjust rect to specified column
+    if ( subItem != wxLIST_GETSUBITEMRECT_WHOLEITEM )
+    {
+        wxCHECK_MSG( subItem >= 0 && subItem < GetColumnCount(), false,
+                     _T("invalid subItem in GetSubItemRect") );
+
+        for (int i = 0; i < subItem; i++)
+        {
+            rect.x += GetColumnWidth(i);
+        }
+        rect.width = GetColumnWidth(subItem);
+    }
+
+    GetListCtrl()->CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y);
 
-    CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y);
+    return true;
 }
 
 bool wxListMainWindow::GetItemPosition(long item, wxPoint& pos) const
@@ -4208,9 +4261,9 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh)
     const size_t count = GetItemCount();
 
     int iconSpacing;
-    if ( HasFlag(wxLC_ICON) )
+    if ( HasFlag(wxLC_ICON) && m_normal_image_list )
         iconSpacing = m_normal_spacing;
-    else if ( HasFlag(wxLC_SMALL_ICON) )
+    else if ( HasFlag(wxLC_SMALL_ICON) && m_small_image_list )
         iconSpacing = m_small_spacing;
     else
         iconSpacing = 0;
@@ -4244,11 +4297,11 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh)
 
         ResetVisibleLinesRange();
 
-        SetScrollbars( SCROLL_UNIT_X, lineHeight,
+        GetListCtrl()->SetScrollbars( SCROLL_UNIT_X, lineHeight,
                        GetHeaderWidth() / SCROLL_UNIT_X,
                        (entireHeight + lineHeight - 1) / lineHeight,
-                       GetScrollPos(wxHORIZONTAL),
-                       GetScrollPos(wxVERTICAL),
+                       GetListCtrl()->GetScrollPos(wxHORIZONTAL),
+                       GetListCtrl()->GetScrollPos(wxVERTICAL),
                        true );
     }
     else // !report
@@ -4297,14 +4350,14 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh)
                 }
             }
 
-            SetScrollbars
+            GetListCtrl()->SetScrollbars
             (
                 SCROLL_UNIT_X,
                 lineHeight,
                 (x + SCROLL_UNIT_X) / SCROLL_UNIT_X,
                 (y + lineHeight) / lineHeight,
-                GetScrollPos( wxHORIZONTAL ),
-                GetScrollPos( wxVERTICAL ),
+                GetListCtrl()->GetScrollPos( wxHORIZONTAL ),
+                GetListCtrl()->GetScrollPos( wxVERTICAL ),
                 true
             );
         }
@@ -4378,13 +4431,13 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh)
                 }
             }
 
-            SetScrollbars
+            GetListCtrl()->SetScrollbars
             (
                 SCROLL_UNIT_X,
                 lineHeight,
                 (entireWidth + SCROLL_UNIT_X) / SCROLL_UNIT_X,
                 0,
-                GetScrollPos( wxHORIZONTAL ),
+                GetListCtrl()->GetScrollPos( wxHORIZONTAL ),
                 0,
                 true
             );
@@ -4687,7 +4740,7 @@ long wxListMainWindow::FindItem( const wxPoint& pt )
 
 long wxListMainWindow::HitTest( int x, int y, int &flags ) const
 {
-    CalcUnscrolledPosition( x, y, &x, &y );
+    GetListCtrl()->CalcUnscrolledPosition( x, y, &x, &y );
 
     size_t count = GetItemCount();
 
@@ -4837,8 +4890,8 @@ int wxListMainWindow::GetItemWidthWithImage(wxListItem * item)
 // sorting
 // ----------------------------------------------------------------------------
 
-wxListCtrlCompare list_ctrl_compare_func_2;
-long              list_ctrl_compare_data;
+static wxListCtrlCompare list_ctrl_compare_func_2;
+static long              list_ctrl_compare_data;
 
 int LINKAGEMODE list_ctrl_compare_func_1( wxListLineData **arg1, wxListLineData **arg2 )
 {
@@ -4871,13 +4924,6 @@ void wxListMainWindow::SortItems( wxListCtrlCompare fn, long data )
 
 void wxListMainWindow::OnScroll(wxScrollWinEvent& event)
 {
-    // FIXME
-#if ( defined(__WXGTK__) || defined(__WXMAC__) ) && !defined(__WXUNIVERSAL__)
-    wxScrolledWindow::OnScroll(event);
-#else
-    HandleOnScroll( event );
-#endif
-
     // update our idea of which lines are shown when we redraw the window the
     // next time
     ResetVisibleLinesRange();
@@ -4949,21 +4995,22 @@ IMPLEMENT_DYNAMIC_CLASS(wxGenericListCtrl, wxControl)
 
 BEGIN_EVENT_TABLE(wxGenericListCtrl,wxControl)
   EVT_SIZE(wxGenericListCtrl::OnSize)
+  EVT_SCROLLWIN(wxGenericListCtrl::OnScroll)
 END_EVENT_TABLE()
 
-wxGenericListCtrl::wxGenericListCtrl()
+void wxGenericListCtrl::Init()
 {
-    m_imageListNormal = (wxImageList *) NULL;
-    m_imageListSmall = (wxImageList *) NULL;
-    m_imageListState = (wxImageList *) NULL;
+    m_imageListNormal = NULL;
+    m_imageListSmall = NULL;
+    m_imageListState = NULL;
 
     m_ownsImageListNormal =
     m_ownsImageListSmall =
     m_ownsImageListState = false;
 
-    m_mainWin = (wxListMainWindow*) NULL;
-    m_headerWin = (wxListHeaderWindow*) NULL;
-    m_headerHeight = 0;
+    m_mainWin = NULL;
+    m_headerWin = NULL;
+    m_headerHeight = wxRendererNative::Get().GetHeaderButtonHeight(this);
 }
 
 wxGenericListCtrl::~wxGenericListCtrl()
@@ -4976,43 +5023,44 @@ wxGenericListCtrl::~wxGenericListCtrl()
         delete m_imageListState;
 }
 
-void wxGenericListCtrl::CalculateAndSetHeaderHeight()
+void wxGenericListCtrl::CreateOrDestroyHeaderWindowAsNeeded()
 {
-    if ( m_headerWin )
-    {
-#ifdef __WXMAC__
-        SInt32 h;
-        GetThemeMetric( kThemeMetricListHeaderHeight, &h );
-#else
-        // we use 'g' to get the descent, too
-        int w, h, d;
-        m_headerWin->GetTextExtent(wxT("Hg"), &w, &h, &d);
-        h += d + 2 * HEADER_OFFSET_Y + EXTRA_HEIGHT;
-#endif
+    bool needs_header = HasHeader();
+    bool has_header = (m_headerWin != NULL);
 
-        // only update if changed
-        if ( h != m_headerHeight )
-        {
-            m_headerHeight = h;
-
-            if ( HasHeader() )
-                ResizeReportView(true);
-            else    //why is this needed if it doesn't have a header?
-                m_headerWin->SetSize(m_headerWin->GetSize().x, m_headerHeight);
-        }
-    }
-}
+    if (needs_header == has_header)
+        return;
 
-void wxGenericListCtrl::CreateHeaderWindow()
-{
-    m_headerWin = new wxListHeaderWindow
+    if (needs_header)
+    {
+        m_headerWin = new wxListHeaderWindow
                       (
                         this, wxID_ANY, m_mainWin,
                         wxPoint(0,0),
                         wxSize(GetClientSize().x, m_headerHeight),
                         wxTAB_TRAVERSAL
                       );
-    CalculateAndSetHeaderHeight();
+
+#if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON
+        wxFont font;
+#if wxOSX_USE_ATSU_TEXT
+        font.MacCreateFromThemeFont( kThemeSmallSystemFont );
+#else
+        font.MacCreateFromUIFont( kCTFontSystemFontType );
+#endif
+        m_headerWin->SetFont( font );
+#endif
+
+        GetSizer()->Prepend( m_headerWin, 0, wxGROW );
+    }
+    else
+    {
+        GetSizer()->Detach( m_headerWin );
+
+        delete m_headerWin;
+
+        m_headerWin = NULL;
+    }
 }
 
 bool wxGenericListCtrl::Create(wxWindow *parent,
@@ -5023,66 +5071,81 @@ bool wxGenericListCtrl::Create(wxWindow *parent,
                         const wxValidator &validator,
                         const wxString &name)
 {
-    m_imageListNormal =
-    m_imageListSmall =
-    m_imageListState = (wxImageList *) NULL;
-    m_ownsImageListNormal =
-    m_ownsImageListSmall =
-    m_ownsImageListState = false;
-
-    m_mainWin = (wxListMainWindow*) NULL;
-    m_headerWin = (wxListHeaderWindow*) NULL;
-
-    m_headerHeight = 0;
+    Init();
 
-    if ( !(style & wxLC_MASK_TYPE) )
-    {
-        style = style | wxLC_LIST;
-    }
+    // just like in other ports, an assert will fail if the user doesn't give any type style:
+    wxASSERT_MSG( (style & wxLC_MASK_TYPE),
+                  _T("wxListCtrl style should have exactly one mode bit set") );
 
-    if ( !wxControl::Create( parent, id, pos, size, style, validator, name ) )
+    if ( !wxControl::Create( parent, id, pos, size, style|wxVSCROLL|wxHSCROLL, validator, name ) )
         return false;
 
-    // this window itself shouldn't get the focus, only m_mainWin should
-    SetCanFocus(false);
-
-    // don't create the inner window with the border
+#ifdef __WXGTK__
     style &= ~wxBORDER_MASK;
+    style |= wxBORDER_THEME;
+#endif
 
     m_mainWin = new wxListMainWindow( this, wxID_ANY, wxPoint(0, 0), size, style );
 
-#ifdef __WXMAC__
-    // Human Interface Guidelines ask us for a special font in this case
-    if ( GetWindowVariant() == wxWINDOW_VARIANT_NORMAL )
+    SetTargetWindow( m_mainWin );
+
+    wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
+    sizer->Add( m_mainWin, 1, wxGROW );
+    SetSizer( sizer );
+
+    CreateOrDestroyHeaderWindowAsNeeded();
+
+    SetInitialSize(size);
+
+    return true;
+}
+
+wxBorder wxGenericListCtrl::GetDefaultBorder() const
+{
+    return wxBORDER_THEME;
+}
+
+#ifdef __WXMSW__
+WXLRESULT wxGenericListCtrl::MSWWindowProc(WXUINT nMsg,
+                                       WXWPARAM wParam,
+                                       WXLPARAM lParam)
+{
+    WXLRESULT rc = wxControl::MSWWindowProc(nMsg, wParam, lParam);
+
+#ifndef __WXWINCE__
+    // we need to process arrows ourselves for scrolling
+    if ( nMsg == WM_GETDLGCODE )
     {
-        wxFont font;
-        font.MacCreateFromThemeFont( kThemeViewsFont );
-        SetFont( font );
+        rc |= DLGC_WANTARROWS;
     }
 #endif
 
-    if ( InReportView() )
-    {
-        CreateHeaderWindow();
-
-#ifdef __WXMAC__
-        if (m_headerWin)
-        {
-            wxFont font;
-            font.MacCreateFromThemeFont( kThemeSmallSystemFont );
-            m_headerWin->SetFont( font );
-            CalculateAndSetHeaderHeight();
-        }
+    return rc;
+}
 #endif
 
-        if ( HasFlag(wxLC_NO_HEADER) )
-            // VZ: why do we create it at all then?
-            m_headerWin->Show( false );
-    }
+wxSize wxGenericListCtrl::GetSizeAvailableForScrollTarget(const wxSize& size)
+{
+    wxSize newsize = size;
+    if (m_headerWin)
+       newsize.y -= m_headerWin->GetSize().y;
 
-    SetInitialSize(size);
+    return newsize;
+}
 
-    return true;
+void wxGenericListCtrl::OnScroll(wxScrollWinEvent& event)
+{
+    // update our idea of which lines are shown when we redraw
+    // the window the next time
+    m_mainWin->ResetVisibleLinesRange();
+
+    HandleOnScroll( event );
+
+    if ( event.GetOrientation() == wxHORIZONTAL && HasHeader() )
+    {
+        m_headerWin->Refresh();
+        m_headerWin->Update();
+    }
 }
 
 void wxGenericListCtrl::SetSingleStyle( long style, bool add )
@@ -5107,45 +5170,28 @@ void wxGenericListCtrl::SetSingleStyle( long style, bool add )
     else
         flag &= ~style;
 
-    SetWindowStyleFlag( flag );
+    // some styles can be set without recreating everything (as happens in
+    // SetWindowStyleFlag() which calls wxListMainWindow::DeleteEverything())
+    if ( !(style & ~(wxLC_HRULES | wxLC_VRULES)) )
+    {
+        Refresh();
+        wxWindow::SetWindowStyleFlag(flag);
+    }
+    else
+    {
+        SetWindowStyleFlag( flag );
+    }
 }
 
 void wxGenericListCtrl::SetWindowStyleFlag( long flag )
 {
     if (m_mainWin)
     {
-        m_mainWin->DeleteEverything();
+        // m_mainWin->DeleteEverything();  wxMSW doesn't do that
 
-        // has the header visibility changed?
-        bool hasHeader = HasHeader();
-        bool willHaveHeader = (flag & wxLC_REPORT) && !(flag & wxLC_NO_HEADER);
-
-        if ( hasHeader != willHaveHeader )
-        {
-            // toggle it
-            if ( hasHeader )
-            {
-                if ( m_headerWin )
-                {
-                    // don't delete, just hide, as we can reuse it later
-                    m_headerWin->Show(false);
-                }
-                //else: nothing to do
-            }
-            else // must show header
-            {
-                if (!m_headerWin)
-                {
-                    CreateHeaderWindow();
-                }
-                else // already have it, just show
-                {
-                    m_headerWin->Show( true );
-                }
-            }
+        CreateOrDestroyHeaderWindowAsNeeded();
 
-            ResizeReportView(willHaveHeader);
-        }
+        GetSizer()->Layout();
     }
 
     wxWindow::SetWindowStyleFlag( flag );
@@ -5271,11 +5317,22 @@ wxRect wxGenericListCtrl::GetViewRect() const
     return m_mainWin->GetViewRect();
 }
 
-bool wxGenericListCtrl::GetItemRect( long item, wxRect &rect, int WXUNUSED(code) ) const
+bool wxGenericListCtrl::GetItemRect(long item, wxRect& rect, int code) const
+{
+    return GetSubItemRect(item, wxLIST_GETSUBITEMRECT_WHOLEITEM, rect, code);
+}
+
+bool wxGenericListCtrl::GetSubItemRect(long item,
+                                       long subItem,
+                                       wxRect& rect,
+                                       int WXUNUSED(code)) const
 {
-    m_mainWin->GetItemRect( item, rect );
+    if ( !m_mainWin->GetSubItemRect( item, subItem, rect ) )
+        return false;
+
     if ( m_mainWin->HasHeader() )
         rect.y += m_headerHeight + 1;
+
     return true;
 }
 
@@ -5287,7 +5344,7 @@ bool wxGenericListCtrl::GetItemPosition( long item, wxPoint& pos ) const
 
 bool wxGenericListCtrl::SetItemPosition( long WXUNUSED(item), const wxPoint& WXUNUSED(pos) )
 {
-    return 0;
+    return false;
 }
 
 int wxGenericListCtrl::GetItemCount() const
@@ -5351,16 +5408,6 @@ wxColour wxGenericListCtrl::GetItemBackgroundColour( long item ) const
     return info.GetBackgroundColour();
 }
 
-int wxGenericListCtrl::GetScrollPos( int orient ) const
-{
-    return m_mainWin->GetScrollPos( orient );
-}
-
-void wxGenericListCtrl::SetScrollPos( int orient, int pos, bool refresh )
-{
-    m_mainWin->SetScrollPos( orient, pos, refresh );
-}
-
 void wxGenericListCtrl::SetItemFont( long item, const wxFont &f )
 {
     wxListItem info;
@@ -5413,7 +5460,7 @@ wxImageList *wxGenericListCtrl::GetImageList(int which) const
     else if (which == wxIMAGE_LIST_STATE)
         return m_imageListState;
 
-    return (wxImageList *) NULL;
+    return NULL;
 }
 
 void wxGenericListCtrl::SetImageList( wxImageList *imageList, int which )
@@ -5489,8 +5536,8 @@ bool wxGenericListCtrl::DeleteColumn( int col )
     m_mainWin->DeleteColumn( col );
 
     // if we don't have the header any longer, we need to relayout the window
-    if ( !GetColumnCount() )
-        ResizeReportView(false /* no header */);
+    // if ( !GetColumnCount() )
+
     return true;
 }
 
@@ -5575,8 +5622,7 @@ long wxGenericListCtrl::InsertColumn( long col, wxListItem &item )
 
     // if we hadn't had a header before but have one now
     // then we need to relayout the window
-    if ( GetColumnCount() == 1 && m_mainWin->HasHeader() )
-        ResizeReportView(true /* have header */);
+    // if ( GetColumnCount() == 1 && m_mainWin->HasHeader() )
 
     m_headerWin->Refresh();
 
@@ -5627,43 +5673,28 @@ bool wxGenericListCtrl::SortItems( wxListCtrlCompare fn, long data )
 
 void wxGenericListCtrl::OnSize(wxSizeEvent& WXUNUSED(event))
 {
-    if ( !m_mainWin )
-        return;
+    if (!m_mainWin) return;
 
-    ResizeReportView(m_mainWin->HasHeader());
-    m_mainWin->RecalculatePositions();
-}
+    // We need to override OnSize so that our scrolled
+    // window a) does call Layout() to use sizers for
+    // positioning the controls but b) does not query
+    // the sizer for their size and use that for setting
+    // the scrollable area as set that ourselves by
+    // calling SetScrollbar() further down.
 
-void wxGenericListCtrl::ResizeReportView(bool showHeader)
-{
-    int cw, ch;
-    GetClientSize( &cw, &ch );
+    Layout();
 
-    if ( showHeader )
-    {
-        m_headerWin->SetSize( 0, 0, cw, m_headerHeight );
-        if(ch > m_headerHeight)
-            m_mainWin->SetSize( 0, m_headerHeight + 1,
-                                   cw, ch - m_headerHeight - 1 );
-        else
-            m_mainWin->SetSize( 0, m_headerHeight + 1,
-                                   cw, 0);
-    }
-    else // no header window
-    {
-        m_mainWin->SetSize( 0, 0, cw, ch );
-    }
+    m_mainWin->RecalculatePositions();
+
+    AdjustScrollbars();
 }
 
 void wxGenericListCtrl::OnInternalIdle()
 {
     wxWindow::OnInternalIdle();
 
-    // do it only if needed
-    if ( !m_mainWin->m_dirty )
-        return;
-
-    m_mainWin->RecalculatePositions();
+    if (m_mainWin->m_dirty)
+        m_mainWin->RecalculatePositions();
 }
 
 // ----------------------------------------------------------------------------
@@ -5712,7 +5743,7 @@ bool wxGenericListCtrl::SetFont( const wxFont &font )
     if (m_headerWin)
     {
         m_headerWin->SetFont( font );
-        CalculateAndSetHeaderHeight();
+        // CalculateAndSetHeaderHeight();
     }
 
     Refresh();
@@ -5730,7 +5761,7 @@ wxGenericListCtrl::GetClassDefaultAttributes(wxWindowVariant variant)
 #else
     wxUnusedVar(variant);
     wxVisualAttributes attr;
-    attr.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
+    attr.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXTEXT);
     attr.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX);
     attr.font  = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
     return attr;
@@ -5910,14 +5941,4 @@ void wxGenericListCtrl::Refresh(bool eraseBackground, const wxRect *rect)
     }
 }
 
-void wxGenericListCtrl::Freeze()
-{
-    m_mainWin->Freeze();
-}
-
-void wxGenericListCtrl::Thaw()
-{
-    m_mainWin->Thaw();
-}
-
 #endif // wxUSE_LISTCTRL