From bdc72a22686ac141e9bc4559a1171d017fdcb094 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Sat, 4 Dec 1999 22:34:54 +0000
Subject: [PATCH] 1. wxGetOsDescription() function added 2.
 wxApp::GetComCtlVersion() slightly updated 3. wxToolBar::AddControl() should
 work on all systems, DeleteTool() added 4. wxListCtrl custom draw changes
 (custom colours/fonts)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4822 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 configure.in                  |   8 +
 docs/changes.txt              |   1 +
 docs/latex/wx/function.tex    |  29 +-
 include/wx/generic/listctrl.h | 144 +---------
 include/wx/listctrl.h         | 243 ++++++++++++++++-
 include/wx/msw/listctrl.h     | 485 ++++++++++++++--------------------
 include/wx/msw/tbar95.h       |  10 +
 include/wx/thread.h           |   2 +
 include/wx/utils.h            |   8 +-
 samples/listctrl/listtest.cpp |  28 +-
 samples/toolbar/test.cpp      |  25 +-
 setup.h.in                    |   3 +
 src/generic/listctrl.cpp      |   2 +-
 src/msw/app.cpp               | 122 ++++++---
 src/msw/listctrl.cpp          | 200 ++++++++++----
 src/msw/tbar95.cpp            | 136 ++++++++--
 src/msw/utils.cpp             | 133 +++++++---
 src/unix/utilsunx.cpp         |  47 ++--
 18 files changed, 1005 insertions(+), 621 deletions(-)

diff --git a/configure.in b/configure.in
index 0884532a69..a3d3da82a4 100644
--- a/configure.in
+++ b/configure.in
@@ -2962,6 +2962,14 @@ if test "$wxUSE_PNM" = "yes" ; then
   AC_DEFINE(wxUSE_PNM)
 fi
 
+dnl ---------------------------------------------------------------------------
+dnl get the string with OS info - used by wxGetOsDescription()
+dnl ---------------------------------------------------------------------------
+
+OSINFO=`uname -s -r -m`
+OSINFO="\"$OSINFO\""
+AC_DEFINE_UNQUOTED(WXWIN_OS_DESCRIPTION, $OSINFO)
+
 dnl ---------------------------------------------------------------------------
 dnl Output the makefiles and such from the results found above
 dnl ---------------------------------------------------------------------------
diff --git a/docs/changes.txt b/docs/changes.txt
index b2bce0816a..1b6a35d396 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -19,6 +19,7 @@ all (GUI):
 
 wxMSW:
 
+- wxTreeCtrl::IsVisible() bug fixed (thanks to Gary Chessun)
 - tooltips work with wxRadioBox
 - arbitrary controls (and not only buttons) can be put into a toolbar
 
diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex
index f522dc3be3..26367bbf94 100644
--- a/docs/latex/wx/function.tex
+++ b/docs/latex/wx/function.tex
@@ -1344,7 +1344,23 @@ Returns the mouse position in screen coordinates.
 
 <wx/utils.h>
 
-\membersection{::wxGetOsVersion}
+\membersection{::wxGetOsDescription}\label{wxgetosdescription}
+
+\func{wxString}{wxGetOsDescription}{\void}
+
+Returns the string containing the description of the current platform in a
+user-readable form. For example, this function may return strings like
+{\tt Windows NT Version 4.0} or {\tt Linux 2.2.2 i386}.
+
+\wxheading{See also}
+
+\helpref{::wxGetOsVersion}{wxgetosversion}
+
+\wxheading{Include files}
+
+<wx/utils.h>
+
+\membersection{::wxGetOsVersion}\label{wxgetosversion}
 
 \func{int}{wxGetOsVersion}{\param{int *}{major = NULL}, \param{int *}{minor = NULL}}
 
@@ -1353,16 +1369,21 @@ Gets operating system version information.
 \begin{twocollist}\itemsep=0pt
 \twocolitemruled{Platform}{Return tyes}
 \twocolitem{Macintosh}{Return value is wxMACINTOSH.}
-\twocolitem{GTK}{Return value is wxGTK, {\it major} is 1, {\it minor} is 0. (for GTK 1.0.X) }
+\twocolitem{GTK}{Return value is wxGTK, For GTK 1.0, {\it major} is 1, {\it minor} is 0. }
 \twocolitem{Motif}{Return value is wxMOTIF\_X, {\it major} is X version, {\it minor} is X revision.}
 \twocolitem{OS/2}{Return value is wxOS2\_PM.}
 \twocolitem{Windows 3.1}{Return value is wxWINDOWS, {\it major} is 3, {\it minor} is 1.}
-\twocolitem{Windows NT}{Return value is wxWINDOWS\_NT, {\it major} is 3, {\it minor} is 1.}
-\twocolitem{Windows 95}{Return value is wxWIN95, {\it major} is 3, {\it minor} is 1.}
+\twocolitem{Windows NT/2000}{Return value is wxWINDOWS\_NT, version is returned in {\it major} and {\it minor}}
+\twocolitem{Windows 98}{Return value is wxWIN95, {\it major} is 4, {\it minor} is 1 or greater.}
+\twocolitem{Windows 95}{Return value is wxWIN95, {\it major} is 4, {\it minor} is 0.}
 \twocolitem{Win32s (Windows 3.1)}{Return value is wxWIN32S, {\it major} is 3, {\it minor} is 1.}
 \twocolitem{Watcom C++ 386 supervisor mode (Windows 3.1)}{Return value is wxWIN386, {\it major} is 3, {\it minor} is 1.}
 \end{twocollist}
 
+\wxheading{See also}
+
+\helpref{::wxGetOsDescription}{wxgetosdescription}
+
 \wxheading{Include files}
 
 <wx/utils.h>
diff --git a/include/wx/generic/listctrl.h b/include/wx/generic/listctrl.h
index 72c6826610..cd0ced7b50 100644
--- a/include/wx/generic/listctrl.h
+++ b/include/wx/generic/listctrl.h
@@ -1,11 +1,11 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        listctrl.h
+// Name:        wx/generic/listctrl.h
 // Purpose:     Generic list control
 // Author:      Robert Roebling
 // Created:     01/02/97
 // Id:
 // Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
-// Licence:   	wxWindows licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef __LISTCTRLH_G__
@@ -51,146 +51,6 @@ class WXDLLEXPORT wxListMainWindow;
 class WXDLLEXPORT wxListRenameTimer;
 class WXDLLEXPORT wxListTextCtrl;
 
-//-----------------------------------------------------------------------------
-// types
-//-----------------------------------------------------------------------------
-
-// type of compare function for wxListCtrl sort operation
-typedef int (*wxListCtrlCompare)(long item1, long item2, long sortData);
-
-//-----------------------------------------------------------------------------
-// wxListCtrl flags
-//-----------------------------------------------------------------------------
-
-#define wxLC_ICON            0x0004
-#define wxLC_SMALL_ICON      0x0008
-#define wxLC_LIST            0x0010
-#define wxLC_REPORT          0x0020
-#define wxLC_ALIGN_TOP       0x0040
-#define wxLC_ALIGN_LEFT      0x0080
-#define wxLC_AUTOARRANGE     0x0100  // not supported in wxGLC
-#define wxLC_USER_TEXT       0x0200  // not supported in wxGLC (how does it work?)
-#define wxLC_EDIT_LABELS     0x0400
-#define wxLC_NO_HEADER       0x0800
-#define wxLC_NO_SORT_HEADER  0x1000  // not supported in wxGLC
-#define wxLC_SINGLE_SEL      0x2000
-#define wxLC_SORT_ASCENDING  0x4000
-#define wxLC_SORT_DESCENDING 0x8000  // not supported in wxGLC
-
-#define wxLC_MASK_TYPE       (wxLC_ICON | wxLC_SMALL_ICON | wxLC_LIST | wxLC_REPORT)
-#define wxLC_MASK_ALIGN      (wxLC_ALIGN_TOP | wxLC_ALIGN_LEFT)
-#define wxLC_MASK_SORT       (wxLC_SORT_ASCENDING | wxLC_SORT_DESCENDING)
-
-// Omitted because (a) too much detail (b) not enough style flags
-// #define wxLC_NO_SCROLL
-// #define wxLC_NO_LABEL_WRAP
-// #define wxLC_OWNERDRAW_FIXED
-// #define wxLC_SHOW_SEL_ALWAYS
-
-// Mask flags to tell app/GUI what fields of wxListItem are valid
-#define wxLIST_MASK_STATE           0x0001
-#define wxLIST_MASK_TEXT            0x0002
-#define wxLIST_MASK_IMAGE           0x0004
-#define wxLIST_MASK_DATA            0x0008
-#define wxLIST_SET_ITEM             0x0010
-#define wxLIST_MASK_WIDTH           0x0020
-#define wxLIST_MASK_FORMAT          0x0040
-
-// State flags for indicating the state of an item
-#define wxLIST_STATE_DONTCARE       0x0000
-#define wxLIST_STATE_DROPHILITED    0x0001  // not supported in wxGLC
-#define wxLIST_STATE_FOCUSED        0x0002
-#define wxLIST_STATE_SELECTED       0x0004
-#define wxLIST_STATE_CUT            0x0008  // not supported in wxGLC
-
-// Hit test flags, used in HitTest // wxGLC suppots 20 and 80
-#define wxLIST_HITTEST_ABOVE            0x0001  // Above the client area.
-#define wxLIST_HITTEST_BELOW            0x0002  // Below the client area.
-#define wxLIST_HITTEST_NOWHERE          0x0004  // In the client area but below the last item.
-#define wxLIST_HITTEST_ONITEMICON       0x0020  // On the bitmap associated with an item.
-#define wxLIST_HITTEST_ONITEMLABEL      0x0080  // On the label (string) associated with an item.
-#define wxLIST_HITTEST_ONITEMRIGHT      0x0100  // In the area to the right of an item.
-#define wxLIST_HITTEST_ONITEMSTATEICON  0x0200  // On the state icon for a tree view item that is in a user-defined state.
-#define wxLIST_HITTEST_TOLEFT           0x0400  // To the right of the client area.
-#define wxLIST_HITTEST_TORIGHT          0x0800  // To the left of the client area.
-
-#define wxLIST_HITTEST_ONITEM (wxLIST_HITTEST_ONITEMICON | wxLIST_HITTEST_ONITEMLABEL | wxLIST_HITTEST_ONITEMSTATEICON)
-
-
-
-// Flags for GetNextItem  // always wxLIST_NEXT_ALL in wxGLC
-enum {
-    wxLIST_NEXT_ABOVE,          // Searches for an item above the specified item
-    wxLIST_NEXT_ALL,            // Searches for subsequent item by index
-    wxLIST_NEXT_BELOW,          // Searches for an item below the specified item
-    wxLIST_NEXT_LEFT,           // Searches for an item to the left of the specified item
-    wxLIST_NEXT_RIGHT           // Searches for an item to the right of the specified item
-};
-
-// Alignment flags for Arrange  // always wxLIST_ALIGN_LEFT in wxGLC
-enum {
-    wxLIST_ALIGN_DEFAULT,
-    wxLIST_ALIGN_LEFT,
-    wxLIST_ALIGN_TOP,
-    wxLIST_ALIGN_SNAP_TO_GRID
-};
-
-// Column format  // always wxLIST_FORMAT_LEFT in wxGLC
-enum {
-    wxLIST_FORMAT_LEFT,
-    wxLIST_FORMAT_RIGHT,
-    wxLIST_FORMAT_CENTRE,
-    wxLIST_FORMAT_CENTER = wxLIST_FORMAT_CENTRE
-};
-
-// Autosize values for SetColumnWidth
-enum {
-    wxLIST_AUTOSIZE = -1,           // width of longest item
-    wxLIST_AUTOSIZE_USEHEADER = -2  // always 80 in wxGLC
-};
-
-// Flag values for GetItemRect
-enum {
-    wxLIST_RECT_BOUNDS,
-    wxLIST_RECT_ICON,
-    wxLIST_RECT_LABEL
-};
-
-// Flag values for FindItem  // not supported by wxGLC
-enum {
-    wxLIST_FIND_UP,
-    wxLIST_FIND_DOWN,
-    wxLIST_FIND_LEFT,
-    wxLIST_FIND_RIGHT
-};
-
-//-----------------------------------------------------------------------------
-// wxListItem
-//-----------------------------------------------------------------------------
-
-class WXDLLEXPORT wxListItem: public wxObject
-{
-public:
-    long            m_mask;     // Indicates what fields are valid
-    long            m_itemId;   // The zero-based item position
-    int             m_col;      // Zero-based column, if in report mode
-    long            m_state;    // The state of the item
-    long            m_stateMask; // Which flags of m_state are valid (uses same flags)
-    wxString        m_text;     // The label/header text
-    int             m_image;    // The zero-based index into an image list
-    long            m_data;     // App-defined data
-    wxColour       *m_colour;   // only wxGLC, not supported by Windows ;->
-
-    // For columns only
-    int             m_format;   // left, right, centre
-    int             m_width;    // width of column
-
-    wxListItem();
-    
-private:
-    DECLARE_DYNAMIC_CLASS(wxListItem)
-};
-
 //-----------------------------------------------------------------------------
 //  wxListItemData (internal)
 //-----------------------------------------------------------------------------
diff --git a/include/wx/listctrl.h b/include/wx/listctrl.h
index 56139e3b3f..d5817da5bd 100644
--- a/include/wx/listctrl.h
+++ b/include/wx/listctrl.h
@@ -1,24 +1,245 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        wx/listctrl.h
+// Purpose:     wxListCtrl class
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     04.12.99
+// RCS-ID:      $Id$
+// Copyright:   (c) wxWindows team
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
 #ifndef _WX_LISTCTRL_H_BASE_
 #define _WX_LISTCTRL_H_BASE_
 
+// ----------------------------------------------------------------------------
+// types
+// ----------------------------------------------------------------------------
+
+// type of compare function for wxListCtrl sort operation
+typedef int (wxCALLBACK *wxListCtrlCompare)(long item1, long item2, long sortData);
+
+// ----------------------------------------------------------------------------
+// wxListCtrl constants
+// ----------------------------------------------------------------------------
+
+// Mask flags to tell app/GUI what fields of wxListItem are valid
+#define wxLIST_MASK_STATE           0x0001
+#define wxLIST_MASK_TEXT            0x0002
+#define wxLIST_MASK_IMAGE           0x0004
+#define wxLIST_MASK_DATA            0x0008
+#define wxLIST_SET_ITEM             0x0010
+#define wxLIST_MASK_WIDTH           0x0020
+#define wxLIST_MASK_FORMAT          0x0040
+
+// State flags for indicating the state of an item
+#define wxLIST_STATE_DONTCARE       0x0000
+#define wxLIST_STATE_DROPHILITED    0x0001      // MSW only
+#define wxLIST_STATE_FOCUSED        0x0002
+#define wxLIST_STATE_SELECTED       0x0004
+#define wxLIST_STATE_CUT            0x0008      // MSW only
+
+// Hit test flags, used in HitTest
+#define wxLIST_HITTEST_ABOVE            0x0001  // Above the client area.
+#define wxLIST_HITTEST_BELOW            0x0002  // Below the client area.
+#define wxLIST_HITTEST_NOWHERE          0x0004  // In the client area but below the last item.
+#define wxLIST_HITTEST_ONITEMICON       0x0020  // On the bitmap associated with an item.
+#define wxLIST_HITTEST_ONITEMLABEL      0x0080  // On the label (string) associated with an item.
+#define wxLIST_HITTEST_ONITEMRIGHT      0x0100  // In the area to the right of an item.
+#define wxLIST_HITTEST_ONITEMSTATEICON  0x0200  // On the state icon for a tree view item that is in a user-defined state.
+#define wxLIST_HITTEST_TOLEFT           0x0400  // To the left of the client area.
+#define wxLIST_HITTEST_TORIGHT          0x0800  // To the right of the client area.
+
+#define wxLIST_HITTEST_ONITEM (wxLIST_HITTEST_ONITEMICON | wxLIST_HITTEST_ONITEMLABEL | wxLIST_HITTEST_ONITEMSTATEICON)
+
+// Flags for GetNextItem (MSW only except wxLIST_NEXT_ALL)
+enum
+{
+    wxLIST_NEXT_ABOVE,          // Searches for an item above the specified item
+    wxLIST_NEXT_ALL,            // Searches for subsequent item by index
+    wxLIST_NEXT_BELOW,          // Searches for an item below the specified item
+    wxLIST_NEXT_LEFT,           // Searches for an item to the left of the specified item
+    wxLIST_NEXT_RIGHT,          // Searches for an item to the right of the specified item
+};
+
+// Alignment flags for Arrange (MSW only except wxLIST_ALIGN_LEFT)
+enum
+{
+    wxLIST_ALIGN_DEFAULT,
+    wxLIST_ALIGN_LEFT,
+    wxLIST_ALIGN_TOP,
+    wxLIST_ALIGN_SNAP_TO_GRID
+};
+
+// Column format (MSW only except wxLIST_FORMAT_LEFT)
+enum wxListColumnFormat
+{
+    wxLIST_FORMAT_LEFT,
+    wxLIST_FORMAT_RIGHT,
+    wxLIST_FORMAT_CENTRE,
+    wxLIST_FORMAT_CENTER = wxLIST_FORMAT_CENTRE
+};
+
+// Autosize values for SetColumnWidth
+enum
+{
+    wxLIST_AUTOSIZE = -1,
+    wxLIST_AUTOSIZE_USEHEADER = -2      // partly supported by generic version
+};
+
+// Flag values for GetItemRect
+enum
+{
+    wxLIST_RECT_BOUNDS,
+    wxLIST_RECT_ICON,
+    wxLIST_RECT_LABEL
+};
+
+// Flag values for FindItem (MSW only)
+enum
+{
+    wxLIST_FIND_UP,
+    wxLIST_FIND_DOWN,
+    wxLIST_FIND_LEFT,
+    wxLIST_FIND_RIGHT
+};
+
+// ----------------------------------------------------------------------------
+// wxListItemAttr: a structure containing the visual attributes of an item
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListItemAttr
+{
+public:
+    // ctors
+    wxListItemAttr() { }
+    wxListItemAttr(const wxColour& colText,
+                   const wxColour& colBack,
+                   const wxFont& font)
+        : m_colText(colText), m_colBack(colBack), m_font(font) { }
+
+    // setters
+    void SetTextColour(const wxColour& colText) { m_colText = colText; }
+    void SetBackgroundColour(const wxColour& colBack) { m_colBack = colBack; }
+    void SetFont(const wxFont& font) { m_font = font; }
+
+    // accessors
+    const wxColour& GetTextColour() const { return m_colText; }
+    const wxColour& GetBackgroundColour() const { return m_colBack; }
+    const wxFont& GetFont() const { return m_font; }
+
+private:
+    wxColour m_colText,
+             m_colBack;
+    wxFont   m_font;
+};
+
+// ----------------------------------------------------------------------------
+// wxListItem: the item or column info, used to exchange data with wxListCtrl
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListItem : public wxObject
+{
+public:
+    wxListItem();
+
+    // setters
+    void SetMask(long mask) { m_mask = mask; }
+    void SetId(long id) { m_itemId = id; }
+    void SetColumn(int col) { m_col = col; }
+    void SetState(long state) { m_state = state; m_stateMask |= state; }
+    void SetStateMask(long stateMask) { m_stateMask = stateMask; }
+    void SetText(const wxString& text) { m_text = text; }
+    void SetImage(int image) { m_image = image; }
+    void SetData(long data) { m_data = data; }
+    void SetData(void *data) { m_data = (long)data; }
+
+    void SetWidth(int width) { m_width = width; }
+    void SetAlign(wxListColumnFormat align) { m_format = align; }
+
+    void SetTextColour(const wxColour& colText)
+        { Attributes().SetTextColour(colText); }
+    void SetBackgroundColour(const wxColour& colBack)
+        { Attributes().SetBackgroundColour(colBack); }
+    void SetFont(const wxFont& font)
+        { Attributes().SetFont(font); }
+
+    // accessors
+    long GetMask() const { return m_mask; }
+    long GetId() const { return m_itemId; }
+    int GetColumn() const { return m_col; }
+    long GetState() const { return m_state & m_stateMask; }
+    const wxString& GetText() const { return m_text; }
+    int GetImage() const { return m_image; }
+    long GetData() const { return m_data; }
+
+    int GetWidth() const { return m_width; }
+    wxListColumnFormat GetAlign() const { return (wxListColumnFormat)m_format; }
+
+    wxListItemAttr *GetAttributes() const { return m_attr; }
+    bool HasAttributes() const { return m_attr != NULL; }
+
+    const wxColour& GetTextColour() const
+        { return HasAttributes() ? m_attr->GetTextColour() : wxNullColour; }
+    const wxColour& GetBackgroundColour() const
+        { return HasAttributes() ? m_attr->GetBackgroundColour()
+                                 : wxNullColour; }
+    const wxFont& GetFont() const
+        { return HasAttributes() ? m_attr->GetFont() : wxNullFont; }
+
+    // these members are public for compatibility
+
+    long            m_mask;     // Indicates what fields are valid
+    long            m_itemId;   // The zero-based item position
+    int             m_col;      // Zero-based column, if in report mode
+    long            m_state;    // The state of the item
+    long            m_stateMask;// Which flags of m_state are valid (uses same flags)
+    wxString        m_text;     // The label/header text
+    int             m_image;    // The zero-based index into an image list
+    long            m_data;     // App-defined data
+
+    // For columns only
+    int             m_format;   // left, right, centre
+    int             m_width;    // width of column
+
+protected:
+    // creates m_attr if we don't have it yet
+    wxListItemAttr& Attributes()
+    {
+        if ( !m_attr )
+            m_attr = new wxListItemAttr;
+
+        return *m_attr;
+    }
+
+    wxListItemAttr *m_attr;     // optional pointer to the items style
+
+private:
+    DECLARE_DYNAMIC_CLASS(wxListItem)
+};
+
+// ----------------------------------------------------------------------------
+// include the wxListCtrl class declaration
+// ----------------------------------------------------------------------------
+
 #if defined(__WXMSW__)
-#ifdef __WIN16__
-#include "wx/generic/listctrl.h"
-#else
-#include "wx/msw/listctrl.h"
-#endif
+    #ifdef __WIN16__
+        #include "wx/generic/listctrl.h"
+    #else
+        #include "wx/msw/listctrl.h"
+    #endif
 #elif defined(__WXMOTIF__)
-#include "wx/generic/listctrl.h"
+    #include "wx/generic/listctrl.h"
 #elif defined(__WXGTK__)
-#include "wx/generic/listctrl.h"
+    #include "wx/generic/listctrl.h"
 #elif defined(__WXQT__)
-#include "wx/generic/listctrl.h"
+    #include "wx/generic/listctrl.h"
 #elif defined(__WXMAC__)
-#include "wx/generic/listctrl.h"
+    #include "wx/generic/listctrl.h"
 #elif defined(__WXPM__)
-#include "wx/generic/listctrl.h"
+    #include "wx/generic/listctrl.h"
 #elif defined(__WXSTUBS__)
-#include "wx/generic/listctrl.h"
+    #include "wx/generic/listctrl.h"
 #endif
 
 // ----------------------------------------------------------------------------
diff --git a/include/wx/msw/listctrl.h b/include/wx/msw/listctrl.h
index ef0a992d06..3fb236e0c2 100644
--- a/include/wx/msw/listctrl.h
+++ b/include/wx/msw/listctrl.h
@@ -1,12 +1,12 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        listctrl.h
+// Name:        wx/msw/listctrl.h
 // Purpose:     wxListCtrl class
 // Author:      Julian Smart
 // Modified by:
 // Created:     01/02/97
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart
-// Licence:   	wxWindows licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_LISTCTRL_H_
@@ -74,362 +74,279 @@
 
  */
 
-// Mask flags to tell app/GUI what fields of wxListItem are valid
-#define wxLIST_MASK_STATE           0x0001
-#define wxLIST_MASK_TEXT            0x0002
-#define wxLIST_MASK_IMAGE           0x0004
-#define wxLIST_MASK_DATA            0x0008
-#define wxLIST_SET_ITEM             0x0010
-#define wxLIST_MASK_WIDTH           0x0020
-#define wxLIST_MASK_FORMAT          0x0040
-
-// State flags for indicating the state of an item
-#define wxLIST_STATE_DONTCARE       0x0000
-#define wxLIST_STATE_DROPHILITED    0x0001
-#define wxLIST_STATE_FOCUSED        0x0002
-#define wxLIST_STATE_SELECTED       0x0004
-#define wxLIST_STATE_CUT            0x0008
-
-// Hit test flags, used in HitTest
-#define wxLIST_HITTEST_ABOVE            0x0001  // Above the client area.
-#define wxLIST_HITTEST_BELOW            0x0002  // Below the client area.
-#define wxLIST_HITTEST_NOWHERE          0x0004  // In the client area but below the last item.
-#define wxLIST_HITTEST_ONITEMICON       0x0020  // On the bitmap associated with an item.
-#define wxLIST_HITTEST_ONITEMLABEL      0x0080  // On the label (string) associated with an item.
-#define wxLIST_HITTEST_ONITEMRIGHT      0x0100  // In the area to the right of an item.
-#define wxLIST_HITTEST_ONITEMSTATEICON  0x0200  // On the state icon for a tree view item that is in a user-defined state.
-#define wxLIST_HITTEST_TOLEFT           0x0400  // To the left of the client area.
-#define wxLIST_HITTEST_TORIGHT          0x0800  // To the right of the client area.
-
-#define wxLIST_HITTEST_ONITEM (wxLIST_HITTEST_ONITEMICON | wxLIST_HITTEST_ONITEMLABEL | wxLIST_HITTEST_ONITEMSTATEICON)
-
-// Flags for GetNextItem
-enum {
-    wxLIST_NEXT_ABOVE,          // Searches for an item above the specified item
-    wxLIST_NEXT_ALL,            // Searches for subsequent item by index
-    wxLIST_NEXT_BELOW,          // Searches for an item below the specified item
-    wxLIST_NEXT_LEFT,           // Searches for an item to the left of the specified item
-    wxLIST_NEXT_RIGHT,          // Searches for an item to the right of the specified item
-};
-
-// Alignment flags for Arrange
-enum {
-    wxLIST_ALIGN_DEFAULT,
-    wxLIST_ALIGN_LEFT,
-    wxLIST_ALIGN_TOP,
-    wxLIST_ALIGN_SNAP_TO_GRID
-};
-
-// Column format
-enum {
-    wxLIST_FORMAT_LEFT,
-    wxLIST_FORMAT_RIGHT,
-    wxLIST_FORMAT_CENTRE,
-    wxLIST_FORMAT_CENTER = wxLIST_FORMAT_CENTRE
-};
-
-// Autosize values for SetColumnWidth
-enum {
-    wxLIST_AUTOSIZE = -1,
-    wxLIST_AUTOSIZE_USEHEADER = -2
-};
-
-// Flag values for GetItemRect
-enum {
-    wxLIST_RECT_BOUNDS,
-    wxLIST_RECT_ICON,
-    wxLIST_RECT_LABEL
-};
-
-// Flag values for FindItem
-enum {
-    wxLIST_FIND_UP,
-    wxLIST_FIND_DOWN,
-    wxLIST_FIND_LEFT,
-    wxLIST_FIND_RIGHT
-};
-
-// wxListItem: data representing an item, or report field.
-// It also doubles up to represent entire column information
-// when inserting or setting a column.
-class WXDLLEXPORT wxListItem: public wxObject
+class WXDLLEXPORT wxListCtrl: public wxControl
 {
- DECLARE_DYNAMIC_CLASS(wxListItem)
 public:
-    long            m_mask;     // Indicates what fields are valid
-    long            m_itemId;   // The zero-based item position
-    int             m_col;      // Zero-based column, if in report mode
-    long            m_state;    // The state of the item
-    long            m_stateMask; // Which flags of m_state are valid (uses same flags)
-    wxString        m_text;     // The label/header text
-    int             m_image;    // The zero-based index into an image list
-    long            m_data;     // App-defined data
-
-    // For columns only
-    int             m_format;   // left, right, centre
-    int             m_width;    // width of column
-
-    wxListItem();
-};
+    /*
+     * Public interface
+     */
 
-// type of compare function for wxListCtrl sort operation
-typedef int (wxCALLBACK *wxListCtrlCompare)(long item1, long item2, long sortData);
+    wxListCtrl() { Init(); }
 
-class WXDLLEXPORT wxListCtrl: public wxControl
-{
-  DECLARE_DYNAMIC_CLASS(wxListCtrl)
- public:
-  /*
-   * Public interface
-   */
+    wxListCtrl(wxWindow *parent,
+               wxWindowID id = -1,
+               const wxPoint& pos = wxDefaultPosition,
+               const wxSize& size = wxDefaultSize,
+               long style = wxLC_ICON,
+               const wxValidator& validator = wxDefaultValidator,
+               const wxString& name = _T("wxListCtrl"))
+    {
+        Init();
 
-  wxListCtrl();
+        Create(parent, id, pos, size, style, validator, name);
+    }
 
-  inline wxListCtrl(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
-            long style = wxLC_ICON, const wxValidator& validator = wxDefaultValidator,
-            const wxString& name = "listCtrl")
-  {
-    Create(parent, id, pos, size, style, validator, name);
-  }
-  ~wxListCtrl();
+    virtual ~wxListCtrl();
 
-  bool Create(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
-            long style = wxLC_ICON, const wxValidator& validator = wxDefaultValidator, const wxString& name = "wxListCtrl");
+    bool Create(wxWindow *parent,
+                wxWindowID id = -1,
+                const wxPoint& pos = wxDefaultPosition,
+                const wxSize& size = wxDefaultSize,
+                long style = wxLC_ICON,
+                const wxValidator& validator = wxDefaultValidator,
+                const wxString& name = _T("wxListCtrl"));
 
 
-  // Attributes
-  ////////////////////////////////////////////////////////////////////////////
+    // Attributes
+    ////////////////////////////////////////////////////////////////////////////
 
-  // Sets the background colour (GetBackgroundColour already implicit in
-  // wxWindow class)
-  bool SetBackgroundColour(const wxColour& col);
+    // Sets the background colour (GetBackgroundColour already implicit in
+    // wxWindow class)
+    bool SetBackgroundColour(const wxColour& col);
 
-  // Gets information about this column
-  bool GetColumn(int col, wxListItem& item) const;
+    // Gets information about this column
+    bool GetColumn(int col, wxListItem& item) const;
 
-  // Sets information about this column
-  bool SetColumn(int col, wxListItem& item) ;
+    // Sets information about this column
+    bool SetColumn(int col, wxListItem& item) ;
 
-  // Gets the column width
-  int GetColumnWidth(int col) const;
+    // Gets the column width
+    int GetColumnWidth(int col) const;
 
-  // Sets the column width
-  bool SetColumnWidth(int col, int width) ;
+    // Sets the column width
+    bool SetColumnWidth(int col, int width) ;
 
-  // Gets the number of items that can fit vertically in the
-  // visible area of the list control (list or report view)
-  // or the total number of items in the list control (icon
-  // or small icon view)
-  int GetCountPerPage() const;
+    // Gets the number of items that can fit vertically in the
+    // visible area of the list control (list or report view)
+    // or the total number of items in the list control (icon
+    // or small icon view)
+    int GetCountPerPage() const;
 
-  // Gets the edit control for editing labels.
-  wxTextCtrl* GetEditControl() const;
+    // Gets the edit control for editing labels.
+    wxTextCtrl* GetEditControl() const;
 
-  // Gets information about the item
-  bool GetItem(wxListItem& info) const ;
+    // Gets information about the item
+    bool GetItem(wxListItem& info) const ;
 
-  // Sets information about the item
-  bool SetItem(wxListItem& info) ;
+    // Sets information about the item
+    bool SetItem(wxListItem& info) ;
 
-  // Sets a string field at a particular column
-  long SetItem(long index, int col, const wxString& label, int imageId = -1);
+    // Sets a string field at a particular column
+    long SetItem(long index, int col, const wxString& label, int imageId = -1);
 
-  // Gets the item state
-  int  GetItemState(long item, long stateMask) const ;
+    // Gets the item state
+    int  GetItemState(long item, long stateMask) const ;
 
-  // Sets the item state
-  bool SetItemState(long item, long state, long stateMask) ;
+    // Sets the item state
+    bool SetItemState(long item, long state, long stateMask) ;
 
-  // Sets the item image
-  bool SetItemImage(long item, int image, int selImage) ;
+    // Sets the item image
+    bool SetItemImage(long item, int image, int selImage) ;
 
-  // Gets the item text
-  wxString GetItemText(long item) const ;
+    // Gets the item text
+    wxString GetItemText(long item) const ;
 
-  // Sets the item text
-  void SetItemText(long item, const wxString& str) ;
+    // Sets the item text
+    void SetItemText(long item, const wxString& str) ;
 
-  // Gets the item data
-  long GetItemData(long item) const ;
+    // Gets the item data
+    long GetItemData(long item) const ;
 
-  // Sets the item data
-  bool SetItemData(long item, long data) ;
+    // Sets the item data
+    bool SetItemData(long item, long data) ;
 
-  // Gets the item rectangle
-  bool GetItemRect(long item, wxRect& rect, int code = wxLIST_RECT_BOUNDS) const ;
+    // Gets the item rectangle
+    bool GetItemRect(long item, wxRect& rect, int code = wxLIST_RECT_BOUNDS) const ;
 
-  // Gets the item position
-  bool GetItemPosition(long item, wxPoint& pos) const ;
+    // Gets the item position
+    bool GetItemPosition(long item, wxPoint& pos) const ;
 
-  // Sets the item position
-  bool SetItemPosition(long item, const wxPoint& pos) ;
+    // Sets the item position
+    bool SetItemPosition(long item, const wxPoint& pos) ;
 
-  // Gets the number of items in the list control
-  int GetItemCount() const;
+    // Gets the number of items in the list control
+    int GetItemCount() const;
 
-  // Gets the number of columns in the list control
-  int GetColumnCount() const { return m_colCount; }
+    // Gets the number of columns in the list control
+    int GetColumnCount() const { return m_colCount; }
 
-  // Retrieves the spacing between icons in pixels.
-  // If small is TRUE, gets the spacing for the small icon
-  // view, otherwise the large icon view.
-  int GetItemSpacing(bool isSmall) const;
+    // Retrieves the spacing between icons in pixels.
+    // If small is TRUE, gets the spacing for the small icon
+    // view, otherwise the large icon view.
+    int GetItemSpacing(bool isSmall) const;
 
-  // Gets the number of selected items in the list control
-  int GetSelectedItemCount() const;
+    // Gets the number of selected items in the list control
+    int GetSelectedItemCount() const;
 
-  // Gets the text colour of the listview
-  wxColour GetTextColour() const;
+    // Gets the text colour of the listview
+    wxColour GetTextColour() const;
 
-  // Sets the text colour of the listview
-  void SetTextColour(const wxColour& col);
+    // Sets the text colour of the listview
+    void SetTextColour(const wxColour& col);
 
-  // Gets the index of the topmost visible item when in
-  // list or report view
-  long GetTopItem() const ;
+    // Gets the index of the topmost visible item when in
+    // list or report view
+    long GetTopItem() const ;
 
-  // Add or remove a single window style
-  void SetSingleStyle(long style, bool add = TRUE) ;
+    // Add or remove a single window style
+    void SetSingleStyle(long style, bool add = TRUE) ;
 
-  // Set the whole window style
-  void SetWindowStyleFlag(long style) ;
+    // Set the whole window style
+    void SetWindowStyleFlag(long style) ;
 
-  // Searches for an item, starting from 'item'.
-  // item can be -1 to find the first item that matches the
-  // specified flags.
-  // Returns the item or -1 if unsuccessful.
-  long GetNextItem(long item, int geometry = wxLIST_NEXT_ALL, int state = wxLIST_STATE_DONTCARE) const ;
+    // Searches for an item, starting from 'item'.
+    // item can be -1 to find the first item that matches the
+    // specified flags.
+    // Returns the item or -1 if unsuccessful.
+    long GetNextItem(long item, int geometry = wxLIST_NEXT_ALL, int state = wxLIST_STATE_DONTCARE) const ;
 
-  // Implementation: converts wxWindows style to MSW style.
-  // Can be a single style flag or a bit list.
-  // oldStyle is 'normalised' so that it doesn't contain
-  // conflicting styles.
-  long ConvertToMSWStyle(long& oldStyle, long style) const;
+    // Implementation: converts wxWindows style to MSW style.
+    // Can be a single style flag or a bit list.
+    // oldStyle is 'normalised' so that it doesn't contain
+    // conflicting styles.
+    long ConvertToMSWStyle(long& oldStyle, long style) const;
 
-  // Gets one of the three image lists
-  wxImageList *GetImageList(int which) const ;
+    // Gets one of the three image lists
+    wxImageList *GetImageList(int which) const ;
 
-  // Sets the image list
-  // N.B. There's a quirk in the Win95 list view implementation.
-  // If in wxLC_LIST mode, it'll *still* display images by the labels if
-  // there's a small-icon image list set for the control - even though you
-  // haven't specified wxLIST_MASK_IMAGE when inserting.
-  // So you have to set a NULL small-icon image list to be sure that
-  // the wxLC_LIST mode works without icons. Of course, you may want icons...
-  void SetImageList(wxImageList *imageList, int which) ;
+    // Sets the image list
+    // N.B. There's a quirk in the Win95 list view implementation.
+    // If in wxLC_LIST mode, it'll *still* display images by the labels if
+    // there's a small-icon image list set for the control - even though you
+    // haven't specified wxLIST_MASK_IMAGE when inserting.
+    // So you have to set a NULL small-icon image list to be sure that
+    // the wxLC_LIST mode works without icons. Of course, you may want icons...
+    void SetImageList(wxImageList *imageList, int which) ;
 
-  // Operations
-  ////////////////////////////////////////////////////////////////////////////
+    // Operations
+    ////////////////////////////////////////////////////////////////////////////
 
-  // Arranges the items
-  bool Arrange(int flag = wxLIST_ALIGN_DEFAULT);
+    // Arranges the items
+    bool Arrange(int flag = wxLIST_ALIGN_DEFAULT);
 
-  // Deletes an item
-  bool DeleteItem(long item);
+    // Deletes an item
+    bool DeleteItem(long item);
 
-  // Deletes all items
-  bool DeleteAllItems() ;
+    // Deletes all items
+    bool DeleteAllItems() ;
 
-  // Deletes a column
-  bool DeleteColumn(int col);
+    // Deletes a column
+    bool DeleteColumn(int col);
 
-  // Deletes all columns
-  bool DeleteAllColumns();
+    // Deletes all columns
+    bool DeleteAllColumns();
 
-  // Clears items, and columns if there are any.
-  void ClearAll();
+    // Clears items, and columns if there are any.
+    void ClearAll();
 
-  // Edit the label
-  wxTextCtrl* EditLabel(long item, wxClassInfo* textControlClass = CLASSINFO(wxTextCtrl));
+    // Edit the label
+    wxTextCtrl* EditLabel(long item, wxClassInfo* textControlClass = CLASSINFO(wxTextCtrl));
 
-  // End label editing, optionally cancelling the edit
-  bool EndEditLabel(bool cancel);
+    // End label editing, optionally cancelling the edit
+    bool EndEditLabel(bool cancel);
 
-  // Ensures this item is visible
-  bool EnsureVisible(long item) ;
+    // Ensures this item is visible
+    bool EnsureVisible(long item) ;
 
-  // Find an item whose label matches this string, starting from the item after 'start'
-  // or the beginning if 'start' is -1.
-  long FindItem(long start, const wxString& str, bool partial = FALSE);
+    // Find an item whose label matches this string, starting from the item after 'start'
+    // or the beginning if 'start' is -1.
+    long FindItem(long start, const wxString& str, bool partial = FALSE);
 
-  // Find an item whose data matches this data, starting from the item after 'start'
-  // or the beginning if 'start' is -1.
-  long FindItem(long start, long data);
+    // Find an item whose data matches this data, starting from the item after 'start'
+    // or the beginning if 'start' is -1.
+    long FindItem(long start, long data);
 
-  // Find an item nearest this position in the specified direction, starting from
-  // the item after 'start' or the beginning if 'start' is -1.
-  long FindItem(long start, const wxPoint& pt, int direction);
+    // Find an item nearest this position in the specified direction, starting from
+    // the item after 'start' or the beginning if 'start' is -1.
+    long FindItem(long start, const wxPoint& pt, int direction);
 
-  // Determines which item (if any) is at the specified point,
-  // giving details in 'flags' (see wxLIST_HITTEST_... flags above)
-  long HitTest(const wxPoint& point, int& flags);
+    // Determines which item (if any) is at the specified point,
+    // giving details in 'flags' (see wxLIST_HITTEST_... flags above)
+    long HitTest(const wxPoint& point, int& flags);
 
-  // Inserts an item, returning the index of the new item if successful,
-  // -1 otherwise.
-  // TOD: Should also have some further convenience functions
-  // which don't require setting a wxListItem object
-  long InsertItem(wxListItem& info);
+    // Inserts an item, returning the index of the new item if successful,
+    // -1 otherwise.
+    long InsertItem(wxListItem& info);
 
-  // Insert a string item
-  long InsertItem(long index, const wxString& label);
+    // Insert a string item
+    long InsertItem(long index, const wxString& label);
 
-  // Insert an image item
-  long InsertItem(long index, int imageIndex);
+    // Insert an image item
+    long InsertItem(long index, int imageIndex);
 
-  // Insert an image/string item
-  long InsertItem(long index, const wxString& label, int imageIndex);
+    // Insert an image/string item
+    long InsertItem(long index, const wxString& label, int imageIndex);
 
-  // For list view mode (only), inserts a column.
-  long InsertColumn(long col, wxListItem& info);
+    // For list view mode (only), inserts a column.
+    long InsertColumn(long col, wxListItem& info);
 
-  long InsertColumn(long col, const wxString& heading, int format = wxLIST_FORMAT_LEFT,
-    int width = -1);
+    long InsertColumn(long col,
+                      const wxString& heading,
+                      int format = wxLIST_FORMAT_LEFT,
+                      int width = -1);
 
-  // Scrolls the list control. If in icon, small icon or report view mode,
-  // x specifies the number of pixels to scroll. If in list view mode, x
-  // specifies the number of columns to scroll.
-  // If in icon, small icon or list view mode, y specifies the number of pixels
-  // to scroll. If in report view mode, y specifies the number of lines to scroll.
-  bool ScrollList(int dx, int dy);
+    // Scrolls the list control. If in icon, small icon or report view mode,
+    // x specifies the number of pixels to scroll. If in list view mode, x
+    // specifies the number of columns to scroll.
+    // If in icon, small icon or list view mode, y specifies the number of pixels
+    // to scroll. If in report view mode, y specifies the number of lines to scroll.
+    bool ScrollList(int dx, int dy);
 
-  // Sort items.
+    // Sort items.
 
-  // fn is a function which takes 3 long arguments: item1, item2, data.
-  // item1 is the long data associated with a first item (NOT the index).
-  // item2 is the long data associated with a second item (NOT the index).
-  // data is the same value as passed to SortItems.
-  // The return value is a negative number if the first item should precede the second
-  // item, a positive number of the second item should precede the first,
-  // or zero if the two items are equivalent.
+    // fn is a function which takes 3 long arguments: item1, item2, data.
+    // item1 is the long data associated with a first item (NOT the index).
+    // item2 is the long data associated with a second item (NOT the index).
+    // data is the same value as passed to SortItems.
+    // The return value is a negative number if the first item should precede the second
+    // item, a positive number of the second item should precede the first,
+    // or zero if the two items are equivalent.
 
-  // data is arbitrary data to be passed to the sort function.
-  bool SortItems(wxListCtrlCompare fn, long data);
+    // data is arbitrary data to be passed to the sort function.
+    bool SortItems(wxListCtrlCompare fn, long data);
 
-  // IMPLEMENTATION
-  virtual bool MSWCommand(WXUINT param, WXWORD id);
-  virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
+    // IMPLEMENTATION
+    virtual bool MSWCommand(WXUINT param, WXWORD id);
+    virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
 
-  // bring the control in sync with current m_windowStyle value
-  void UpdateStyle();
+    // bring the control in sync with current m_windowStyle value
+    void UpdateStyle();
 
-  // Add to pool: necessary because Windows needs to have a string
-  // still exist across 3 callbacks.
-  wxChar *AddPool(const wxString& str);
+    // Add to pool: necessary because Windows needs to have a string
+    // still exist across 3 callbacks.
+    wxChar *AddPool(const wxString& str);
 
 protected:
-  wxTextCtrl*       m_textCtrl;        // The control used for editing a label
-  wxImageList *     m_imageListNormal; // The image list for normal icons
-  wxImageList *     m_imageListSmall;  // The image list for small icons
-  wxImageList *     m_imageListState;  // The image list state icons (not implemented yet)
+    // common part of all ctors
+    void Init();
+
+    wxTextCtrl*       m_textCtrl;        // The control used for editing a label
+    wxImageList *     m_imageListNormal; // The image list for normal icons
+    wxImageList *     m_imageListSmall;  // The image list for small icons
+    wxImageList *     m_imageListState;  // The image list state icons (not implemented yet)
 
-  long              m_baseStyle;  // Basic Windows style flags, for recreation purposes
-  wxStringList      m_stringPool; // Pool of 3 strings to satisfy Windows callback
-                                  // requirements
-  int               m_colCount;   // Windows doesn't have GetColumnCount so must
-                                  // keep track of inserted/deleted columns
+    long              m_baseStyle;  // Basic Windows style flags, for recreation purposes
+    wxStringList      m_stringPool; // Pool of 3 strings to satisfy Windows callback requirements
+    int               m_colCount;   // Windows doesn't have GetColumnCount so must
+                                    // keep track of inserted/deleted columns
+
+    // TRUE fi we have any items with custom attributes
+    bool m_hasAnyAttr;
 
 private:
-  bool DoCreateControl(int x, int y, int w, int h);
+    bool DoCreateControl(int x, int y, int w, int h);
+
+    DECLARE_DYNAMIC_CLASS(wxListCtrl)
 };
 
 #endif
diff --git a/include/wx/msw/tbar95.h b/include/wx/msw/tbar95.h
index d137c39693..97f27e9ec5 100644
--- a/include/wx/msw/tbar95.h
+++ b/include/wx/msw/tbar95.h
@@ -18,6 +18,8 @@
 
 #if wxUSE_TOOLBAR
 
+#include "wx/dynarray.h"
+
 #include "wx/tbarbase.h"
 
 class WXDLLEXPORT wxToolBar95 : public wxToolBarBase
@@ -58,6 +60,7 @@ public:
                                    const wxString& helpString2 = wxEmptyString);
     virtual bool AddControl(wxControl *control);
 
+    virtual bool DeleteTool(int toolIndex);
     virtual void ClearTools();
 
     virtual bool Realize() { return CreateTools(); };
@@ -85,6 +88,13 @@ protected:
     // common part of all ctors
     void Init();
 
+    // the array storing the id for each index
+    wxArrayInt m_ids;
+
+    // get index from id (returns wxNOT_FOUND if no such button)
+    int GetIndexFromId(int id) const;
+
+    // the big bitmap containing all bitmaps of the toolbar buttons
     WXHBITMAP m_hBitmap;
 
     DECLARE_EVENT_TABLE()
diff --git a/include/wx/thread.h b/include/wx/thread.h
index 016e2ff2b5..7c9df994de 100644
--- a/include/wx/thread.h
+++ b/include/wx/thread.h
@@ -406,6 +406,7 @@ void WXDLLEXPORT wxMutexGuiLeave();
 // having to take them inside "#if wxUSE_THREADS"
 #define wxENTER_CRIT_SECT(cs)   (cs).Enter()
 #define wxLEAVE_CRIT_SECT(cs)   (cs).Leave()
+#define wxCRIT_SECT_DECLARE(cs) static wxCriticalSection cs
 #define wxCRIT_SECT_LOCKER(name, cs)  wxCriticalSectionLocker name(cs)
 
 #else // !wxUSE_THREADS
@@ -420,6 +421,7 @@ inline void WXDLLEXPORT wxMutexGuiLeave() { }
 // having to take them inside "#if wxUSE_THREADS"
 #define wxENTER_CRIT_SECT(cs)
 #define wxLEAVE_CRIT_SECT(cs)
+#define wxCRIT_SECT_DECLARE(cs)
 #define wxCRIT_SECT_LOCKER(name, cs)
 
 #endif // wxUSE_THREADS
diff --git a/include/wx/utils.h b/include/wx/utils.h
index 73b50a162b..a3c326248b 100644
--- a/include/wx/utils.h
+++ b/include/wx/utils.h
@@ -76,8 +76,12 @@ WXDLLEXPORT bool StringMatch(wxChar *one, wxChar *two, bool subString = TRUE, bo
 // Sound the bell
 WXDLLEXPORT void wxBell();
 
+// Get OS description as a user-readable string
+WXDLLEXPORT wxString wxGetOsDescription();
+
 // Get OS version
-WXDLLEXPORT int wxGetOsVersion(int *majorVsn= (int *) NULL,int *minorVsn= (int *) NULL) ;
+WXDLLEXPORT int wxGetOsVersion(int *majorVsn = (int *) NULL,
+                               int *minorVsn = (int *) NULL);
 
 // Return a string with the current date/time
 WXDLLEXPORT wxString wxNow();
@@ -298,7 +302,7 @@ public:
 
 // Format a message on the standard error (UNIX) or the debugging
 // stream (Windows)
-WXDLLEXPORT void wxDebugMsg(const wxChar *fmt ...) ;
+WXDLLEXPORT void wxDebugMsg(const wxChar *fmt ...);
 
 // Non-fatal error (continues)
 WXDLLEXPORT_DATA(extern const wxChar*) wxInternalErrorStr;
diff --git a/samples/listctrl/listtest.cpp b/samples/listctrl/listtest.cpp
index d7e1acbf4b..ee96736492 100644
--- a/samples/listctrl/listtest.cpp
+++ b/samples/listctrl/listtest.cpp
@@ -279,7 +279,7 @@ void MyFrame::OnReportView(wxCommandEvent& WXUNUSED(event))
         wxChar buf[50];
         wxSprintf(buf, _T("This is item %d"), i);
         long tmp = m_listCtrl->InsertItem(i, buf, 0);
-        m_listCtrl->SetItemData(tmp, i);
+        //m_listCtrl->SetItemData(tmp, i);
 
         wxSprintf(buf, _T("Col 1, item %d"), i);
         tmp = m_listCtrl->SetItem(i, 1, buf);
@@ -287,21 +287,19 @@ void MyFrame::OnReportView(wxCommandEvent& WXUNUSED(event))
         wxSprintf(buf, _T("Item %d in column 2"), i);
         tmp = m_listCtrl->SetItem(i, 2, buf);
     }
-    
-#ifndef __WXMSW__
+
     // we leave all mask fields to 0 and only change the colour
-    wxListItem first;
-    first.m_itemId = 0;
-    first.m_colour = wxBLUE;
-    m_listCtrl->SetItem( first );
-    
-    first.m_itemId = 2;
-    first.m_colour = wxLIGHT_GREY;
-    m_listCtrl->SetItem( first );
-    first.m_itemId = 3;
-    first.m_colour = wxLIGHT_GREY;
-    m_listCtrl->SetItem( first );
-#endif
+    wxListItem item;
+    item.m_itemId = 0;
+    item.SetTextColour(*wxBLUE);
+    m_listCtrl->SetItem( item );
+
+    item.m_itemId = 2;
+    item.SetTextColour(*wxLIGHT_GREY);
+    m_listCtrl->SetItem( item );
+    item.m_itemId = 3;
+    item.SetTextColour(*wxLIGHT_GREY);
+    m_listCtrl->SetItem( item );
 
     m_listCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE );
     m_listCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE );
diff --git a/samples/toolbar/test.cpp b/samples/toolbar/test.cpp
index 75481427fd..84aeb13a20 100644
--- a/samples/toolbar/test.cpp
+++ b/samples/toolbar/test.cpp
@@ -77,6 +77,7 @@ public:
     void OnToggleToolbar(wxCommandEvent& event);
     void OnEnablePrint(wxCommandEvent& event) { DoEnablePrint(); }
     void OnDeletePrint(wxCommandEvent& event) { DoDeletePrint(); }
+    void OnInsertPrint(wxCommandEvent& event);
     void OnToggleHelp(wxCommandEvent& event) { DoToggleHelp(); }
 
     void OnToolLeftClick(wxCommandEvent& event);
@@ -106,6 +107,7 @@ enum
     IDM_TOOLBAR_TOGGLETOOLBAR = 200,
     IDM_TOOLBAR_ENABLEPRINT,
     IDM_TOOLBAR_DELETEPRINT,
+    IDM_TOOLBAR_INSERTPRINT,
     IDM_TOOLBAR_TOGGLEHELP,
 
     ID_COMBO = 1000
@@ -125,6 +127,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(IDM_TOOLBAR_TOGGLETOOLBAR, MyFrame::OnToggleToolbar)
     EVT_MENU(IDM_TOOLBAR_ENABLEPRINT, MyFrame::OnEnablePrint)
     EVT_MENU(IDM_TOOLBAR_DELETEPRINT, MyFrame::OnDeletePrint)
+    EVT_MENU(IDM_TOOLBAR_INSERTPRINT, MyFrame::OnInsertPrint)
     EVT_MENU(IDM_TOOLBAR_TOGGLEHELP, MyFrame::OnToggleHelp)
 
     EVT_MENU(-1, MyFrame::OnToolLeftClick)
@@ -274,6 +277,7 @@ MyFrame::MyFrame(wxFrame* parent,
     tbarMenu->Append(IDM_TOOLBAR_TOGGLETOOLBAR, "&Toggle toolbar", "Change the toolbar kind");
     tbarMenu->Append(IDM_TOOLBAR_ENABLEPRINT, "&Enable print button", "");
     tbarMenu->Append(IDM_TOOLBAR_DELETEPRINT, "&Delete print button", "");
+    tbarMenu->Append(IDM_TOOLBAR_INSERTPRINT, "&Insert print button", "");
     tbarMenu->Append(IDM_TOOLBAR_TOGGLEHELP, "Toggle &help button", "");
 
     wxMenu *fileMenu = new wxMenu;
@@ -374,9 +378,9 @@ void MyFrame::DoDeletePrint()
 {
     wxToolBar *tb = GetToolBar();
 
-    // only implemented in wxGTK for now
-#ifndef __WXGTK__
-    wxMessageBox("Sorry, wxToolBar::DeleteTool is not implemented under Windows.");
+    // only implemented in wxGTK and wxMSW for now
+#if !defined(__WXGTK__) && !defined(__WXMSW__)
+    wxMessageBox("Sorry, wxToolBar::DeleteTool is not implemented.");
 #else
     tb->DeleteTool( wxID_PRINT );
 #endif
@@ -388,6 +392,21 @@ void MyFrame::DoToggleHelp()
     tb->ToggleTool( wxID_HELP, !tb->GetToolState( wxID_HELP ) );
 }
 
+void MyFrame::OnInsertPrint(wxCommandEvent& WXUNUSED(event))
+{
+#ifdef __WXMSW__
+    wxBitmap bmp("icon7");
+#else
+    wxBitmap bmp(print_xpm);
+#endif
+
+    GetToolBar()->AddTool(wxID_PRINT, bmp, wxNullBitmap,
+                          FALSE, 0, -1,
+                          (wxObject *) NULL, "Delete this tool");
+
+    GetToolBar()->Realize();
+}
+
 void MyFrame::OnToolEnter(wxCommandEvent& event)
 {
   if (event.GetSelection() > -1)
diff --git a/setup.h.in b/setup.h.in
index 06f21b865e..d9db44da8d 100644
--- a/setup.h.in
+++ b/setup.h.in
@@ -19,6 +19,9 @@
 
 #endif /* __cplusplus */
 
+/* fill in with the string wxGetOsDescription() will return */
+#undef WXWIN_OS_DESCRIPTION
+
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #undef gid_t
 
diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp
index 7e251dbf37..145da41d04 100644
--- a/src/generic/listctrl.cpp
+++ b/src/generic/listctrl.cpp
@@ -1302,7 +1302,7 @@ void wxListMainWindow::OnRenameAccept()
     info.m_mask = wxLIST_MASK_TEXT;
     info.m_itemId = le.m_itemIndex;
     info.m_text = m_renameRes;
-    info.m_colour = le.m_item.m_colour;
+    info.m_colour = le.m_item.GetTextColour();
     SetItem( info );
 }
 
diff --git a/src/msw/app.cpp b/src/msw/app.cpp
index b3da445a29..2bb095e842 100644
--- a/src/msw/app.cpp
+++ b/src/msw/app.cpp
@@ -85,10 +85,32 @@
 
 #if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__) || defined(wxUSE_NORLANDER_HEADERS)
     #include <commctrl.h>
+    #include <shlwapi.h>
 #endif
 
 #include "wx/msw/msvcrt.h"
 
+// ----------------------------------------------------------------------------
+// conditional compilation
+// ----------------------------------------------------------------------------
+
+// The macro _WIN32_IE is defined by commctrl.h (unless it had already been
+// defined before) and shows us what common control features are available
+// during the compile time (it doesn't mean that they will be available during
+// the run-time, use GetComCtl32Version() to test for them!). The possible
+// values are:
+//
+// 0x0200     for comctl32.dll 4.00 shipped with Win95/NT 4.0
+// 0x0300                      4.70              IE 3.x
+// 0x0400                      4.71              IE 4.0
+// 0x0401                      4.72              IE 4.01 and Win98
+// 0x0500                      5.00              IE 5.x and NT 5.0 (Win2000)
+
+#ifndef _WIN32_IE
+    // minimal set of features by default
+    #define _WIN32_IE 0x0200
+#endif
+
 // ---------------------------------------------------------------------------
 // global variables
 // ---------------------------------------------------------------------------
@@ -1139,52 +1161,84 @@ bool wxApp::InitRichEdit(int version)
 /* static */
 int wxApp::GetComCtl32Version()
 {
-    // TODO should use DllGetVersion() instead of this hack
-
     // cache the result
-    static int s_verComCtl32 = -1;      // MT-FIXME
+    static int s_verComCtl32 = -1;
+
+    wxCRIT_SECT_DECLARE(csComCtl32);
+    wxCRIT_SECT_LOCKER(lock, csComCtl32);
 
     if ( s_verComCtl32 == -1 )
     {
+        // initally assume no comctl32.dll at all
         s_verComCtl32 = 0;
 
-        // have we loaded COMCTL32 yet?
-        HMODULE theModule = ::GetModuleHandle(wxT("COMCTL32"));
+        // do we have it?
+        HMODULE hModuleComCtl32 = ::GetModuleHandle(wxT("COMCTL32"));
 
         // if so, then we can check for the version
-        if (theModule)
+        if ( hModuleComCtl32 )
         {
-            // InitCommonControlsEx is unique to 4.7 and later
-            FARPROC theProc = ::GetProcAddress(theModule,
-                                               _T("InitCommonControlsEx"));
-
-            if ( !theProc )
-            {                    // not found, must be 4.00
-                s_verComCtl32 = 400;
-            }
-            else
-            {
-                // The following symbol are unique to 4.71
-                //   DllInstall
-                //   FlatSB_EnableScrollBar FlatSB_GetScrollInfo FlatSB_GetScrollPos
-                //   FlatSB_GetScrollProp FlatSB_GetScrollRange FlatSB_SetScrollInfo
-                //   FlatSB_SetScrollPos FlatSB_SetScrollProp FlatSB_SetScrollRange
-                //   FlatSB_ShowScrollBar
-                //   _DrawIndirectImageList _DuplicateImageList
-                //   InitializeFlatSB
-                //   UninitializeFlatSB
-                // we could check for any of these - I chose DllInstall
-                FARPROC theProc = ::GetProcAddress(theModule, _T("DllInstall"));
-                if ( !theProc )
+            // try to use DllGetVersion() if available in _headers_
+            #ifdef DLLVER_PLATFORM_WINDOWS // defined in shlwapi.h
+                DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)
+                    ::GetProcAddress(hModuleComCtl32, _T("DllGetVersion"));
+                if ( pfnDllGetVersion )
                 {
-                    // not found, must be 4.70
-                    s_verComCtl32 = 470;
+                    DLLVERSIONINFO dvi;
+                    dvi.cbSize = sizeof(dvi);
+
+                    HRESULT hr = (*pfnDllGetVersion)(&dvi);
+                    if ( FAILED(hr) )
+                    {
+                        wxLogApiError(_T("DllGetVersion"), hr);
+                    }
+                    else
+                    {
+                        // this is incompatible with _WIN32_IE values, but
+                        // compatible with the other values returned by
+                        // GetComCtl32Version()
+                        s_verComCtl32 = 100*dvi.dwMajorVersion +
+                                            dvi.dwMinorVersion;
+                    }
                 }
-                else
-                {                         // found, must be 4.71
-                    s_verComCtl32 = 471;
+            #endif
+                // DllGetVersion() unavailable either during compile or
+                // run-time, try to guess the version otherwise
+                if ( !s_verComCtl32 )
+                {
+                    // InitCommonControlsEx is unique to 4.70 and later
+                    FARPROC theProc = ::GetProcAddress
+                                        (
+                                         hModuleComCtl32,
+                                         _T("InitCommonControlsEx")
+                                        );
+
+                    if ( !theProc )
+                    {
+                        // not found, must be 4.00
+                        s_verComCtl32 = 400;
+                    }
+                    else
+                    {
+                        // many symbols appeared in comctl32 4.71, could use
+                        // any of them except may be DllInstall
+                        theProc = ::GetProcAddress
+                                    (
+                                     hModuleComCtl32,
+                                     _T("InitializeFlatSB")
+                                    );
+                        if ( !theProc )
+                        {
+                            // not found, must be 4.70
+                            s_verComCtl32 = 470;
+                        }
+                        else
+                        {
+                            // found, must be 4.71
+                            s_verComCtl32 = 471;
+                        }
+                    }
                 }
-            }
         }
     }
 
diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp
index e6a6f0f08e..5bb0d8f862 100644
--- a/src/msw/listctrl.cpp
+++ b/src/msw/listctrl.cpp
@@ -45,6 +45,11 @@
     #include <commctrl.h>
 #endif
 
+#ifndef LVHT_ONITEM
+    #define LVHT_ONITEM \
+                (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON)
+#endif
+
 // ----------------------------------------------------------------------------
 // private functions
 // ----------------------------------------------------------------------------
@@ -69,7 +74,7 @@ static void wxConvertFromMSWListItem(const wxListCtrl *ctrl, wxListItem& info, L
 // wxListCtrl construction
 // ----------------------------------------------------------------------------
 
-wxListCtrl::wxListCtrl()
+void wxListCtrl::Init()
 {
     m_imageListNormal = NULL;
     m_imageListSmall = NULL;
@@ -77,6 +82,7 @@ wxListCtrl::wxListCtrl()
     m_baseStyle = 0;
     m_colCount = 0;
     m_textCtrl = NULL;
+    m_hasAnyAttr = FALSE;
 }
 
 bool wxListCtrl::Create(wxWindow *parent,
@@ -87,12 +93,6 @@ bool wxListCtrl::Create(wxWindow *parent,
                         const wxValidator& validator,
                         const wxString& name)
 {
-    m_imageListNormal = NULL;
-    m_imageListSmall = NULL;
-    m_imageListState = NULL;
-    m_textCtrl = NULL;
-    m_colCount = 0;
-
     SetValidator(validator);
     SetName(name);
 
@@ -545,6 +545,25 @@ bool wxListCtrl::SetItem(wxListItem& info)
 {
     LV_ITEM item;
     wxConvertToMSWListItem(this, info, item);
+
+    // check whether it has any custom attributes
+    if ( info.HasAttributes() )
+    {
+        // FIXME it should be...
+        wxASSERT_MSG( !info.GetData(),
+                      _T("can't have custom attributes and client data") );
+
+        item.mask |= LVIF_PARAM;
+        item.lParam = (long)info.GetAttributes();
+
+        m_hasAnyAttr = TRUE;
+    }
+    else if ( m_hasAnyAttr )
+    {
+        item.mask |= LVIF_PARAM;
+        item.lParam = 0;
+    }
+
     item.cchTextMax = 0;
     bool ok = ListView_SetItem(GetHwnd(), &item) != 0;
     if ( ok && (info.m_mask & wxLIST_MASK_IMAGE) )
@@ -1026,6 +1045,24 @@ long wxListCtrl::InsertItem(wxListItem& info)
     LV_ITEM item;
     wxConvertToMSWListItem(this, info, item);
 
+    // check whether it has any custom attributes
+    if ( info.HasAttributes() )
+    {
+        // FIXME it should be...
+        wxASSERT_MSG( !info.GetData(),
+                      _T("can't have custom attributes and client data") );
+
+        item.mask |= LVIF_PARAM;
+        item.lParam = (long)info.GetAttributes();
+
+        m_hasAnyAttr = TRUE;
+    }
+    else if ( m_hasAnyAttr )
+    {
+        item.mask |= LVIF_PARAM;
+        item.lParam = 0;
+    }
+
     return (long) ListView_InsertItem(GetHwnd(), & item);
 }
 
@@ -1119,8 +1156,10 @@ long wxListCtrl::InsertColumn(long col, wxListItem& item)
     return success;
 }
 
-long wxListCtrl::InsertColumn(long col, const wxString& heading, int format,
-        int width)
+long wxListCtrl::InsertColumn(long col,
+                              const wxString& heading,
+                              int format,
+                              int width)
 {
     wxListItem item;
     item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
@@ -1187,13 +1226,16 @@ bool wxListCtrl::MSWCommand(WXUINT cmd, WXWORD id)
 
 bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
+    // prepare the event
+    // -----------------
+
     wxListEvent event(wxEVT_NULL, m_windowId);
     wxEventType eventType = wxEVT_NULL;
-    NMHDR *hdr1 = (NMHDR *) lParam;
-    switch ( hdr1->code )
+    NMHDR *nmhdr = (NMHDR *)lParam;
+    switch ( nmhdr->code )
     {
         case LVN_BEGINRDRAG:
-        eventType = wxEVT_COMMAND_LIST_BEGIN_RDRAG;
+            eventType = wxEVT_COMMAND_LIST_BEGIN_RDRAG;
             // fall through
 
         case LVN_BEGINDRAG:
@@ -1237,17 +1279,31 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 
             // return TRUE to suppress all additional LVN_DELETEITEM
             // notifications - this makes deleting all items from a list ctrl
-            // much faster
-            *result = TRUE;
-            return TRUE;
+            // much faster (but we can't do it if we have any custom drawn
+            // items because we need to delete their attributes in
+            // LVN_DELETEITEM below)
+            if ( !m_hasAnyAttr )
+            {
+                *result = TRUE;
+
+                return TRUE;
+            }
+            break;
 
         case LVN_DELETEITEM:
             {
                 eventType = wxEVT_COMMAND_LIST_DELETE_ITEM;
                 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
                 event.m_itemIndex = hdr->iItem;
-                break;
+
+                if ( m_hasAnyAttr )
+                {
+                    wxListItemAttr *attr = (wxListItemAttr *)hdr->lParam;
+                    delete attr;
+                }
             }
+            break;
+
         case LVN_ENDLABELEDIT:
             {
                 eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT;
@@ -1255,11 +1311,18 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 wxConvertFromMSWListItem(this, event.m_item, info->item);
                 if ( info->item.pszText == NULL || info->item.iItem == -1 )
                     return FALSE;
-                break;
             }
-        case LVN_GETDISPINFO:
-                return FALSE;
+            break;
+
+        case LVN_SETDISPINFO:
+            {
+                eventType = wxEVT_COMMAND_LIST_SET_INFO;
+                LV_DISPINFO *info = (LV_DISPINFO *)lParam;
+                wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd());
+            }
+            break;
 
+        case LVN_GETDISPINFO:
                 // this provokes stack overflow: indeed, wxConvertFromMSWListItem()
                 // sends us WM_NOTIFY! As it doesn't do anything for now, just leave
                 // it out.
@@ -1274,6 +1337,8 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 break;
             }
 #endif // 0
+                return FALSE;
+
 
         case LVN_INSERTITEM:
             {
@@ -1282,6 +1347,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 event.m_itemIndex = hdr->iItem;
                 break;
             }
+
         case LVN_ITEMCHANGED:
             {
                 // This needs to be sent to wxListCtrl as a rather more
@@ -1364,11 +1430,6 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
             ::ScreenToClient(GetHwnd(),&(lvhti.pt));
             if ( ListView_HitTest(GetHwnd(),&lvhti) != -1 )
             {
-                // older headers don't have this symbol
-#ifndef LVHT_ONITEM
-    #define LVHT_ONITEM \
-                (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON)
-#endif
                 if ( lvhti.flags & LVHT_ONITEM )
                 {
                     eventType = wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK;
@@ -1378,43 +1439,86 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
         }
             break;
 
-        /*
-          case NM_MCLICK: // ***** THERE IS NO NM_MCLICK. Subclass anyone? ******
-          {
-          // if the user processes it in wxEVT_COMMAND_MIDDLE_CLICK(), don't do
-          // anything else
-          if ( wxControl::MSWOnNotify(idCtrl, lParam, result) )
-          {
-          return TRUE;
-          }
-
-          // else translate it into wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK event
-          eventType = wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK;
-          NMITEMACTIVATE* hdr = (NMITEMACTIVATE*)lParam;
-          event.m_itemIndex = hdr->iItem;
-          }
-          break;
-        */
+#if 0
+        case NM_MCLICK: // ***** THERE IS NO NM_MCLICK. Subclass anyone? ******
+            {
+                // if the user processes it in wxEVT_COMMAND_MIDDLE_CLICK(), don't do
+                // anything else
+                if ( wxControl::MSWOnNotify(idCtrl, lParam, result) )
+                {
+                    return TRUE;
+                }
 
-        case LVN_SETDISPINFO:
+                // else translate it into wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK event
+                eventType = wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK;
+                NMITEMACTIVATE* hdr = (NMITEMACTIVATE*)lParam;
+                event.m_itemIndex = hdr->iItem;
+            }
+            break;
+#endif // 0
+
+#ifdef NM_CUSTOMDRAW
+        case NM_CUSTOMDRAW:
             {
-                eventType = wxEVT_COMMAND_LIST_SET_INFO;
-                LV_DISPINFO *info = (LV_DISPINFO *)lParam;
-                wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd());
-                break;
+                LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
+                NMCUSTOMDRAW& nmcd = lplvcd->nmcd;
+                switch( nmcd.dwDrawStage )
+                {
+                    case CDDS_PREPAINT :
+                        // if we've got any items with non standard attributes,
+                        // notify us before painting each item
+                        *result = m_hasAnyAttr ? CDRF_NOTIFYITEMDRAW
+                                               : CDRF_DODEFAULT;
+                        return TRUE;
+
+                    case CDDS_ITEMPREPAINT:
+                        {
+                            if ( !nmcd.lItemlParam )
+                            {
+                                // nothing to do for this item
+                                return CDRF_DODEFAULT;
+                            }
+
+                            wxListItemAttr *attr =
+                                (wxListItemAttr *)nmcd.lItemlParam;
+
+                            ::SelectObject(nmcd.hdc,
+                                (HFONT)((wxFont &)attr->GetFont()).
+                                    GetResourceHandle());
+                            lplvcd->clrText =
+                                wxColourToRGB(attr->GetTextColour());
+                            lplvcd->clrTextBk =
+                                wxColourToRGB(attr->GetBackgroundColour());
+
+                            // if we wanted to set colours for individual
+                            // columns (subitems), we would have returned
+                            // CDRF_NOTIFYSUBITEMREDRAW from here
+                            *result = CDRF_NEWFONT;
+
+                            return TRUE;
+                        }
+                }
             }
+            break;
+#endif // NM_CUSTOMDRAW
 
         default:
             return wxControl::MSWOnNotify(idCtrl, lParam, result);
     }
 
+    // process the event
+    // -----------------
+
     event.SetEventObject( this );
     event.SetEventType(eventType);
 
     if ( !GetEventHandler()->ProcessEvent(event) )
         return FALSE;
 
-    switch ((int)hdr1->code)
+    // post processing
+    // ---------------
+
+    switch ( (int)nmhdr->code )
     {
         case LVN_GETDISPINFO:
             {
@@ -1474,6 +1578,8 @@ wxListItem::wxListItem()
 
     m_format = wxLIST_FORMAT_CENTRE;
     m_width = 0;
+
+    m_attr = NULL;
 }
 
 static void wxConvertFromMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& lvItem, HWND getFullInfo)
diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp
index 5982c8b8b7..5de02a4437 100644
--- a/src/msw/tbar95.cpp
+++ b/src/msw/tbar95.cpp
@@ -191,6 +191,10 @@ wxToolBar95::~wxToolBar95()
     }
 }
 
+// ----------------------------------------------------------------------------
+// adding/removing buttons
+// ----------------------------------------------------------------------------
+
 void wxToolBar95::ClearTools()
 {
     // TODO: Don't know how to reset the toolbar bitmap, as yet.
@@ -199,6 +203,27 @@ void wxToolBar95::ClearTools()
     wxToolBarBase::ClearTools();
 }
 
+bool wxToolBar95::DeleteTool(int id)
+{
+    int index = GetIndexFromId(id);
+    wxASSERT_MSG( index != wxNOT_FOUND, _T("invalid toolbar button id") );
+
+    if ( !SendMessage(GetHwnd(), TB_DELETEBUTTON, index, 0) )
+    {
+        wxLogLastError("TB_DELETEBUTTON");
+
+        return FALSE;
+    }
+
+    wxNode *node = m_tools.Nth(index);
+    delete (wxToolBarTool *)node->Data();
+    m_tools.DeleteNode(node);
+
+    m_ids.RemoveAt(index);
+
+    return TRUE;
+}
+
 bool wxToolBar95::AddControl(wxControl *control)
 {
     wxCHECK_MSG( control, FALSE, _T("toolbar: can't insert NULL control") );
@@ -209,6 +234,7 @@ bool wxToolBar95::AddControl(wxControl *control)
     wxToolBarTool *tool = new wxToolBarTool(control);
 
     m_tools.Append(control->GetId(), tool);
+    m_ids.Add(control->GetId());
 
     return TRUE;
 }
@@ -240,6 +266,7 @@ wxToolBarTool *wxToolBar95::AddTool(int index,
     tool->SetSize(GetToolSize().x, GetToolSize().y);
 
     m_tools.Append((long)index, tool);
+    m_ids.Add(index);
 
     return tool;
 }
@@ -399,8 +426,6 @@ bool wxToolBar95::CreateTools()
 
     delete [] buttons;
 
-    // TBBUTTONINFO struct declaration is new (comctl32.dll 4.70+)
-#if !defined(__GNUWIN32__) && !defined(__WATCOMC__) && !defined(__BORLANDC__)
     // adjust the controls size to fit nicely in the toolbar
     size_t nControls = controlIds.GetCount();
     for ( size_t nCtrl = 0; nCtrl < nControls; nCtrl++ )
@@ -411,17 +436,69 @@ bool wxToolBar95::CreateTools()
 
         wxSize size = control->GetSize();
 
-        // set the (underlying) separators width to be that of the control
-        TBBUTTONINFO tbbi;
-        tbbi.cbSize = sizeof(tbbi);
-        tbbi.dwMask = TBIF_SIZE;
-        tbbi.cx = size.x;
-        if ( !SendMessage(GetHwnd(), TB_SETBUTTONINFO,
-                          tool->m_index, (LPARAM)&tbbi) )
-        {
-            // the index is probably invalid
-            wxLogLastError("TB_SETBUTTONINFO");
-        }
+        // the position of the leftmost controls corner
+        int left = -1;
+
+        // TB_SETBUTTONINFO message is only supported by comctl32.dll 4.71+
+        #if defined(_WIN32_IE) && (_WIN32_IE >= 0x400 )
+            // available in headers, now check whether it is available now
+            // (during run-time)
+            if ( wxTheApp->GetComCtl32Version() >= 471 )
+            {
+                // set the (underlying) separators width to be that of the
+                // control
+                TBBUTTONINFO tbbi;
+                tbbi.cbSize = sizeof(tbbi);
+                tbbi.dwMask = TBIF_SIZE;
+                tbbi.cx = size.x;
+                if ( !SendMessage(GetHwnd(), TB_SETBUTTONINFO,
+                                  tool->m_index, (LPARAM)&tbbi) )
+                {
+                    // the index is probably invalid
+                    wxLogLastError("TB_SETBUTTONINFO");
+                }
+
+            }
+            else
+        #endif // comctl32.dll 4.71
+            // TB_SETBUTTONINFO unavailable
+            {
+                int index = GetIndexFromId(tool->m_index);
+                wxASSERT_MSG( index != wxNOT_FOUND,
+                              _T("control wasn't added to the tbar?") );
+
+                // try adding several separators to fit the controls width
+                RECT r;
+                if ( !SendMessage(GetHwnd(), TB_GETRECT,
+                                  tool->m_index, (LPARAM)(LPRECT)&r) )
+                {
+                    wxLogLastError("TB_GETITEMRECT");
+                }
+
+                int widthSep = r.right - r.left;
+                left = r.left;
+
+                TBBUTTON tbb;
+                wxZeroMemory(tbb);
+                tbb.idCommand = 0;
+                tbb.fsState = TBSTATE_ENABLED;
+                tbb.fsStyle = TBSTYLE_SEP;
+
+                size_t nSeparators = size.x / widthSep;
+                for ( size_t nSep = 0; nSep < nSeparators; nSep++ )
+                {
+                    m_ids.Insert(0, (size_t)index);
+
+                    if ( !SendMessage(GetHwnd(), TB_INSERTBUTTON,
+                                      index, (LPARAM)&tbb) )
+                    {
+                        wxLogLastError("TB_INSERTBUTTON");
+                    }
+                }
+
+                // adjust the controls width to exactly cover the separators
+                control->SetSize((nSeparators + 1)*widthSep, -1);
+            }
 
         // and position the control itself correctly vertically
         RECT r;
@@ -441,9 +518,8 @@ bool wxToolBar95::CreateTools()
             diff = 2;
         }
 
-        control->Move(r.left, r.top + diff / 2);
+        control->Move(left == -1 ? r.left : left, r.top + diff / 2);
     }
-#endif // __GNUWIN32__
 
     (void)::SendMessage(GetHwnd(), TB_AUTOSIZE, (WPARAM)0, (LPARAM) 0);
 
@@ -623,7 +699,11 @@ void wxToolBar95::ToggleTool(int toolIndex, bool toggle)
 
 bool wxToolBar95::GetToolState(int toolIndex) const
 {
-    return (::SendMessage(GetHwnd(), TB_ISBUTTONCHECKED, (WPARAM)toolIndex, (LPARAM)0) != 0);
+    wxASSERT_MSG( GetIndexFromId(toolIndex) != wxNOT_FOUND,
+                  _T("invalid toolbar button id") );
+
+    return ::SendMessage(GetHwnd(), TB_ISBUTTONCHECKED,
+                         (WPARAM)toolIndex, (LPARAM)0) != 0;
 }
 
 // ----------------------------------------------------------------------------
@@ -659,15 +739,31 @@ void wxToolBar95::OnMouseEvent(wxMouseEvent& event)
     }
 }
 
+
+// ----------------------------------------------------------------------------
+// helpers
+// ----------------------------------------------------------------------------
+
+int wxToolBar95::GetIndexFromId(int id) const
+{
+    size_t count = m_ids.GetCount();
+    for ( size_t n = 0; n < count; n++ )
+    {
+        if ( m_ids[n] == id )
+            return n;
+    }
+
+    return wxNOT_FOUND;
+}
+
 // ----------------------------------------------------------------------------
 // private functions
 // ----------------------------------------------------------------------------
 
-// These are the default colors used to map the bitmap colors
-// to the current system colors
+// These are the default colors used to map the bitmap colors to the current
+// system colors. Note that they are in BGR format because this is what Windows
+// wants (and not RGB)
 
-// VZ: why are they BGR and not RGB? just to confuse the people or is there a
-//     deeper reason?
 #define BGR_BUTTONTEXT      (RGB(000,000,000))  // black
 #define BGR_BUTTONSHADOW    (RGB(128,128,128))  // dark grey
 #define BGR_BUTTONFACE      (RGB(192,192,192))  // bright grey
diff --git a/src/msw/utils.cpp b/src/msw/utils.cpp
index d2a2872995..53db01e6d8 100644
--- a/src/msw/utils.cpp
+++ b/src/msw/utils.cpp
@@ -480,50 +480,101 @@ void wxBell()
     ::MessageBeep((UINT)-1);        // default sound
 }
 
-// Chris Breeze 27/5/98: revised WIN32 code to
-// detect WindowsNT correctly
-int wxGetOsVersion(int *majorVsn, int *minorVsn)
+wxString wxGetOsDescription()
 {
-  if (majorVsn) *majorVsn = 0;
-  if (minorVsn) *minorVsn = 0;
+#ifdef __WIN32__
+    wxString str;
+
+    OSVERSIONINFO info;
+    wxZeroMemory(info);
+
+    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    if ( ::GetVersionEx(&info) )
+    {
+        switch ( info.dwPlatformId )
+        {
+            case VER_PLATFORM_WIN32s:
+                str = _("Win32s on Windows 3.1");
+                break;
+
+            case VER_PLATFORM_WIN32_WINDOWS:
+                str.Printf(_("Windows 9%c"),
+                           info.dwMinorVersion == 0 ? _T('5') : _T('9'));
+                if ( !wxIsEmpty(info.szCSDVersion) )
+                {
+                    str << _T(" (") << info.szCSDVersion << _T(')');
+                }
+                break;
 
+            case VER_PLATFORM_WIN32_NT:
+                str.Printf(_T("Windows NT %lu.%lu (build %lu"),
+                           info.dwMajorVersion,
+                           info.dwMinorVersion,
+                           info.dwBuildNumber);
+                if ( !wxIsEmpty(info.szCSDVersion) )
+                {
+                    str << _T(", ") << info.szCSDVersion;
+                }
+                str << _T(')');
+                break;
+        }
+    }
+    else
+    {
+        wxFAIL_MSG( _T("GetVersionEx() failed") ); // should never happen
+    }
+
+    return str;
+#else // Win16
+    return _("Windows 3.1");
+#endif // Win32/16
+}
+
+int wxGetOsVersion(int *majorVsn, int *minorVsn)
+{
 #if defined(__WIN32__) && !defined(__SC__)
-  OSVERSIONINFO info;
-  memset(&info, 0, sizeof(OSVERSIONINFO));
-  info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-  if (GetVersionEx(&info))
-  {
-    if (majorVsn) *majorVsn = info.dwMajorVersion;
-    if (minorVsn) *minorVsn = info.dwMinorVersion;
-    switch (info.dwPlatformId)
-  {
-  case VER_PLATFORM_WIN32s:
-    return wxWIN32S;
-    break;
-  case VER_PLATFORM_WIN32_WINDOWS:
-    return wxWIN95;
-    break;
-  case VER_PLATFORM_WIN32_NT:
-    return wxWINDOWS_NT;
-    break;
-  }
-  }
-  return wxWINDOWS; // error if we get here, return generic value
-#else
-  // Win16 code...
-  int retValue = 0;
-#  ifdef __WINDOWS_386__
-  retValue = wxWIN386;
-#  else
-#    if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
-  extern HANDLE g_hPenWin;
-  retValue = g_hPenWin ? wxPENWINDOWS : wxWINDOWS ;
-#    endif
-#  endif
-  // @@@@ To be completed. I don't have the manual here...
-  if (majorVsn) *majorVsn = 3 ;
-  if (minorVsn) *minorVsn = 1 ;
-  return retValue ;
+    OSVERSIONINFO info;
+    wxZeroMemory(info);
+
+    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    if ( ::GetVersionEx(&info) )
+    {
+        if (majorVsn)
+            *majorVsn = info.dwMajorVersion;
+        if (minorVsn)
+            *minorVsn = info.dwMinorVersion;
+
+        switch ( info.dwPlatformId )
+        {
+            case VER_PLATFORM_WIN32s:
+                return wxWIN32S;
+
+            case VER_PLATFORM_WIN32_WINDOWS:
+                return wxWIN95;
+
+            case VER_PLATFORM_WIN32_NT:
+                return wxWINDOWS_NT;
+        }
+    }
+
+    return wxWINDOWS; // error if we get here, return generic value
+#else // Win16
+    int retValue = wxWINDOWS;
+    #ifdef __WINDOWS_386__
+        retValue = wxWIN386;
+    #else
+        #if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
+            extern HANDLE g_hPenWin;
+            retValue = g_hPenWin ? wxPENWINDOWS : wxWINDOWS;
+        #endif
+    #endif
+
+    if (majorVsn)
+        *majorVsn = 3;
+    if (minorVsn)
+        *minorVsn = 1;
+
+    return retValue;
 #endif
 }
 
diff --git a/src/unix/utilsunx.cpp b/src/unix/utilsunx.cpp
index c8bdafd3bf..2082e6bca1 100644
--- a/src/unix/utilsunx.cpp
+++ b/src/unix/utilsunx.cpp
@@ -23,6 +23,7 @@
 
 #include "wx/utils.h"
 #include "wx/process.h"
+#include "wx/thread.h"
 
 #include "wx/unix/execute.h"
 
@@ -64,20 +65,21 @@
         #ifdef __SUN__
             int usleep(unsigned int usec);
         #else // !Sun
-        #ifdef __EMX__
-            /* I copied this from the XFree86 diffs. AV. */
-            #define INCL_DOSPROCESS
-            #include <os2.h>
-            void usleep(unsigned long delay)
-            {
-                DosSleep(delay ? (delay/1000l) : 1l);
-            }
-        #else
-            void usleep(unsigned long usec);
-        #endif
+            #ifdef __EMX__
+                /* I copied this from the XFree86 diffs. AV. */
+                #define INCL_DOSPROCESS
+                #include <os2.h>
+                inline void usleep(unsigned long delay)
+                {
+                    DosSleep(delay ? (delay/1000l) : 1l);
+                }
+            #else // !Sun && !EMX
+                void usleep(unsigned long usec);
+            #endif
         #endif // Sun/EMX/Something else
     };
-#define HAVE_USLEEP 1
+
+    #define HAVE_USLEEP 1
 #endif // Unices without usleep()
 
 // ============================================================================
@@ -219,17 +221,19 @@ void wxHandleProcessTermination(wxEndProcessData *proc_data)
     int status = 0;
     int rc;
 
+    // wait for child termination and if waitpid() was interrupted, try again
     do
+    {
        rc = waitpid(pid, &status, 0);
-    while(rc == -1 && ( /* errno == ERESTARTSYS || */ errno == EINTR) );
-    // waitpid() was interrupted, try again
+    }
+    while ( rc == -1 && errno == EINTR );
+
 
-       
     if( rc == -1 || ! (WIFEXITED(status) || WIFSIGNALED(status)) )
     {
        wxLogSysError(_("Waiting for subprocess termination failed"));
        /* AFAIK, this can only happen if something went wrong within
-          wxGTK, i.e. due to a racecondition or some serious bug.
+          wxGTK, i.e. due to a race condition or some serious bug.
           After having fixed the order of statements in
           GTK_EndProcessDetector(). (KB)
        */
@@ -251,7 +255,7 @@ void wxHandleProcessTermination(wxEndProcessData *proc_data)
         {
            // wxExecute() will know about it
            proc_data->exitcode = status;
-           
+
            proc_data->pid = 0;
         }
     }
@@ -580,6 +584,15 @@ bool wxGetUserName(wxChar *buf, int sz)
     return FALSE;
 }
 
+wxString wxGetOsDescription()
+{
+#ifndef WXWIN_OS_DESCRIPTION
+    #error WXWIN_OS_DESCRIPTION should be defined in config.h by configure
+#else
+    return WXWIN_OS_DESCRIPTION;
+#endif
+}
+
 // ----------------------------------------------------------------------------
 // error and debug output routines (deprecated, use wxLog)
 // ----------------------------------------------------------------------------
-- 
2.50.0

