\twocolitem{{\bf EVT\_LIST\_ITEM\_DESELECTED(id, func)}}{The item has been deselected.}
 \twocolitem{{\bf EVT\_LIST\_ITEM\_ACTIVATED(id, func)}}{The item has been activated (ENTER or double click).}
 \twocolitem{{\bf EVT\_LIST\_ITEM\_FOCUSED(id, func)}}{The currently focused item has changed.}
-\twocolitem{{\bf EVT\_LIST\_ITEM\_RIGHT\_CLICK(id, func)}}{An item has been right-clicked.}
+\twocolitem{{\bf EVT\_LIST\_ITEM\_MIDDLE\_CLICK(id, func)}}{The middle mouse button has been clicked on an item.}
+\twocolitem{{\bf EVT\_LIST\_ITEM\_RIGHT\_CLICK(id, func)}}{The right mouse button has been clicked on an item.}
 \twocolitem{{\bf EVT\_LIST\_KEY\_DOWN(id, func)}}{A key has been pressed.}
 \twocolitem{{\bf EVT\_LIST\_INSERT\_ITEM(id, func)}}{An item has been inserted.}
 \twocolitem{{\bf EVT\_LIST\_COL\_CLICK(id, func)}}{A column ({\bf m\_col}) has been left-clicked.}
 
 \twocolitem{{\bf EVT\_LIST\_ITEM\_DESELECTED(id, func)}}{The item has been deselected.}
 \twocolitem{{\bf EVT\_LIST\_ITEM\_ACTIVATED(id, func)}}{The item has been activated (ENTER or double click).}
 \twocolitem{{\bf EVT\_LIST\_ITEM\_FOCUSED(id, func)}}{The currently focused item has changed.}
-\twocolitem{{\bf EVT\_LIST\_ITEM\_RIGHT\_CLICK(id, func)}}{An item has been right-clicked.}
+\twocolitem{{\bf EVT\_LIST\_ITEM\_MIDDLE\_CLICK(id, func)}}{The middle mouse button has been clicked on an item.}
+\twocolitem{{\bf EVT\_LIST\_ITEM\_RIGHT\_CLICK(id, func)}}{The right mouse button has been clicked on an item.}
 \twocolitem{{\bf EVT\_LIST\_KEY\_DOWN(id, func)}}{A key has been pressed.}
 \twocolitem{{\bf EVT\_LIST\_INSERT\_ITEM(id, func)}}{An item has been inserted.}
 \twocolitem{{\bf EVT\_LIST\_COL\_CLICK(id, func)}}{A column ({\bf m\_col}) has been left-clicked.}
 
 #endif
 
 #include "wx/frame.h"
+#include "wx/image.h"
+#include "wx/settings.h"
 
 // For ::UpdateWindow
 #ifdef __WXMSW__
     }
 }
 
+///////////// button-label rendering helpers //////////////////
+
+#define MIN_COLOR_DIFF 10
+
+#define IS_IN_ARRAY(x,y) ( (x) < width && (y) < height && (x) >= 0 && (y) >= 0 )
+
+#define IS_GREATER(red1,green1,blue1, red2,green2,blue2) ( ( red1 > red2 + MIN_COLOR_DIFF ) && \
+                                ( green1 > green2 + MIN_COLOR_DIFF ) &&  \
+                                ( blue1 > blue2 + MIN_COLOR_DIFF )     \
+                              )
+
+// Helper function, used by wxCreateGreyedImage
+
+static void wxGreyOutImage( const wxImage& src, wxImage& dest,
+    const wxColour& darkCol, const wxColour& lightCol, const wxColour& bgCol)
+{
+    int x = 0;
+    int y = 1;
+
+    int width = src.GetWidth();
+    int height = src.GetHeight();
+
+    unsigned int redCur, greenCur, blueCur;
+
+    do
+    {
+        redCur = src.GetRed(x, y);
+        greenCur = src.GetGreen(x, y);
+        blueCur = src.GetBlue(x, y);     
+
+        if ( IS_IN_ARRAY(x-1,y-1) )
+        {
+            unsigned int redUpper = src.GetRed(x-1, y-1);
+            unsigned int greenUpper = src.GetGreen(x-1, y-1);
+            unsigned int blueUpper = src.GetBlue(x-1, y-1);     
+
+            // if the upper element is lighter than current
+            if ( IS_GREATER(redUpper, greenUpper, blueUpper, redCur, greenCur, blueCur) )
+            {
+                dest.SetRGB(x,y, darkCol.Red(), darkCol.Green(), darkCol.Blue());
+            }
+            // if the current element is ligher than the upper
+            else if ( IS_GREATER(redCur, greenCur, blueCur, redUpper, greenUpper, blueUpper) )
+            {
+                dest.SetRGB(x,y, lightCol.Red(), lightCol.Green(), lightCol.Blue());
+            }
+            else
+            {
+                unsigned int red1 = dest.GetRed(x-1, y-1);
+                unsigned int green1 = dest.GetGreen(x-1, y-1);
+                unsigned int blue1 = dest.GetBlue(x-1, y-1);     
+
+                if ( red1 == lightCol.Red() && green1 == lightCol.Green() && blue1 == lightCol.Blue() )
+                    dest.SetRGB(x, y, bgCol.Red(), bgCol.Green(), bgCol.Blue());
+                else if ( red1 == darkCol.Red() && green1 == darkCol.Green() && blue1 == darkCol.Blue() )
+                    dest.SetRGB(x, y, darkCol.Red(), darkCol.Green(), darkCol.Blue());
+                else
+                    dest.SetRGB(x, y, bgCol.Red(), bgCol.Green(), bgCol.Blue());
+            }
+        }
+
+        // go zig-zag
+
+        if ( IS_IN_ARRAY(x+1,y-1) ) 
+        {
+            ++x;
+            --y;
+        }
+        else
+        {
+            while ( IS_IN_ARRAY(x-1,y+1) ) 
+            {
+                --x;
+                ++y;
+            }
+
+            if ( IS_IN_ARRAY(x,y+1) )
+            {
+                ++y;
+                continue;
+            }
+            else
+            {
+                if ( IS_IN_ARRAY(x+1,y) )
+                {
+                    ++x;
+                    continue;
+                }
+                else break;
+            }
+        }
+
+    } while (1);
+}
+
+/*
+ * Make a greyed-out image suitable for disabled buttons.
+ * This code is adapted from wxNewBitmapButton in FL.
+ */
+
+bool wxCreateGreyedImage(const wxImage& in, wxImage& out)
+{
+    out = in.Copy();
+
+    // assuming the pixels along the edges are of the background color
+    wxColour bgCol(in.GetRed(0, 0), in.GetGreen(0, 0), in.GetBlue(0, 0));
+
+    wxColour darkCol = wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW) ;
+    wxColour lightCol = wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT) ;
+
+    wxGreyOutImage(in, out, darkCol, lightCol, bgCol);
+
+    return TRUE;
+}
+
 #endif // wxUSE_TOOLBAR
 
 #endif
 
 #include "wx/toolbar.h"
-#include "wx/validate.h"
+#include "wx/image.h"
 
 //-----------------------------------------------------------------------------
 // wxToolBar
 
 void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool enable)
 {
+    // Created disabled-state bitmap on demand
+    if (!enable && !m_bitmap2.Ok())
+    {
+        wxImage in(m_bitmap1);
+        wxImage out(m_bitmap1);
+
+        wxCreateGreyedImage(in, out);
+
+        m_bitmap2 = out.ConvertToBitmap();
+    }
+    RefreshTool(tool);    
 }
 
 void wxToolBar::DoToggleTool(wxToolBarToolBase *tool, bool toggle)
 
 void wxToolBar::DrawToolBarTool( wxToolBarTool *tool, wxDC &dc, bool down )
 {
+    wxBitmap& bitmap = (tool->IsEnabled() || !tool->GetBitmap1().Ok()) ? tool->GetBitmap1() : tool->GetBitmap2() ;
     if (down)
     {
-        dc.DrawBitmap( tool->GetBitmap1(), tool->m_x+4, tool->m_y+4, TRUE );
+        dc.DrawBitmap( bitmap, tool->m_x+4, tool->m_y+4, TRUE );
         
         dc.SetPen( *wxGREY_PEN );
         dc.DrawLine( tool->m_x, tool->m_y, tool->m_x+m_defaultWidth+5, tool->m_y );
     }
     else
     {
-        dc.DrawBitmap( tool->GetBitmap1(), tool->m_x+3, tool->m_y+3, TRUE );
+        dc.DrawBitmap( bitmap, tool->m_x+3, tool->m_y+3, TRUE );
         
         dc.SetPen( *wxWHITE_PEN );
         dc.DrawLine( tool->m_x, tool->m_y, tool->m_x+m_defaultWidth+5, tool->m_y );
         }
     }
     
-    if (event.LeftDown() && (hit))
+    if (event.LeftDown() && (hit) && hit->Enabled())
     {
         CaptureMouse();
         m_captured = hit;