]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/themes/win32.cpp
only work on the focus if the control is shown
[wxWidgets.git] / src / univ / themes / win32.cpp
index b7d8482bb124047bfd5709171f9a2f6503cc8424..0b8499f906dd7df67dcf26b623b76e04530c877b 100644 (file)
@@ -5,7 +5,7 @@
 // Created:     06.08.00
 // RCS-ID:      $Id$
 // Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
 // Created:     06.08.00
 // RCS-ID:      $Id$
 // Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 // ===========================================================================
 ///////////////////////////////////////////////////////////////////////////////
 
 // ===========================================================================
@@ -38,6 +38,7 @@
     #include "wx/scrolbar.h"
     #include "wx/slider.h"
     #include "wx/textctrl.h"
     #include "wx/scrolbar.h"
     #include "wx/slider.h"
     #include "wx/textctrl.h"
+    #include "wx/toolbar.h"
 
     #ifdef __WXMSW__
         // for COLOR_* constants
 
     #ifdef __WXMSW__
         // for COLOR_* constants
 #include "wx/spinbutt.h"
 #include "wx/settings.h"
 #include "wx/menu.h"
 #include "wx/spinbutt.h"
 #include "wx/settings.h"
 #include "wx/menu.h"
+#include "wx/artprov.h"
+#include "wx/toplevel.h"
 
 #include "wx/univ/scrtimer.h"
 
 #include "wx/univ/scrtimer.h"
-#include "wx/toplevel.h"
 #include "wx/univ/renderer.h"
 #include "wx/univ/inphand.h"
 #include "wx/univ/colschem.h"
 #include "wx/univ/renderer.h"
 #include "wx/univ/inphand.h"
 #include "wx/univ/colschem.h"
@@ -78,6 +80,10 @@ static const size_t WIDTH_STATUSBAR_GRIP_BAND = 4;
 static const size_t STATUSBAR_GRIP_SIZE =
     WIDTH_STATUSBAR_GRIP_BAND*NUM_STATUSBAR_GRIP_BANDS;
 
 static const size_t STATUSBAR_GRIP_SIZE =
     WIDTH_STATUSBAR_GRIP_BAND*NUM_STATUSBAR_GRIP_BANDS;
 
+static const wxCoord SLIDER_MARGIN = 6; // margin around slider
+static const wxCoord SLIDER_THUMB_LENGTH = 18;
+static const wxCoord SLIDER_TICK_LENGTH = 6;
+
 enum IndicatorType
 {
     IndicatorType_Check,
 enum IndicatorType
 {
     IndicatorType_Check,
@@ -146,7 +152,8 @@ public:
     virtual void DrawBackground(wxDC& dc,
                                 const wxColour& col,
                                 const wxRect& rect,
     virtual void DrawBackground(wxDC& dc,
                                 const wxColour& col,
                                 const wxRect& rect,
-                                int flags = 0);
+                                int flags = 0,
+                                wxWindow *window = NULL);
     virtual void DrawLabel(wxDC& dc,
                            const wxString& label,
                            const wxRect& rect,
     virtual void DrawLabel(wxDC& dc,
                            const wxString& label,
                            const wxRect& rect,
@@ -228,6 +235,12 @@ public:
                                  int flags = 0,
                                  wxAlignment align = wxALIGN_LEFT,
                                  int indexAccel = -1);
                                  int flags = 0,
                                  wxAlignment align = wxALIGN_LEFT,
                                  int indexAccel = -1);
+    virtual void DrawToolBarButton(wxDC& dc,
+                                   const wxString& label,
+                                   const wxBitmap& bitmap,
+                                   const wxRect& rect,
+                                   int flags = 0,
+                                   long style = 0);
     virtual void DrawTextLine(wxDC& dc,
                               const wxString& text,
                               const wxRect& rect,
     virtual void DrawTextLine(wxDC& dc,
                               const wxString& text,
                               const wxRect& rect,
@@ -245,21 +258,25 @@ public:
 
     virtual void DrawSliderShaft(wxDC& dc,
                                  const wxRect& rect,
 
     virtual void DrawSliderShaft(wxDC& dc,
                                  const wxRect& rect,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int flags = 0,
                                  wxOrientation orient,
                                  int flags = 0,
+                                 long style = 0,
                                  wxRect *rectShaft = NULL);
     virtual void DrawSliderThumb(wxDC& dc,
                                  const wxRect& rect,
                                  wxOrientation orient,
                                  wxRect *rectShaft = NULL);
     virtual void DrawSliderThumb(wxDC& dc,
                                  const wxRect& rect,
                                  wxOrientation orient,
-                                 int flags = 0);
+                                 int flags = 0,
+                                 long style = 0);
     virtual void DrawSliderTicks(wxDC& dc,
                                  const wxRect& rect,
     virtual void DrawSliderTicks(wxDC& dc,
                                  const wxRect& rect,
-                                 const wxSize& sizeThumb,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int start,
                                  int end,
                                  int step = 1,
                                  wxOrientation orient,
                                  int start,
                                  int end,
                                  int step = 1,
-                                 int flags = 0);
+                                 int flags = 0,
+                                 long style = 0);
 
     virtual void DrawMenuBarItem(wxDC& dc,
                                  const wxRect& rect,
 
     virtual void DrawMenuBarItem(wxDC& dc,
                                  const wxRect& rect,
@@ -315,8 +332,6 @@ public:
     virtual wxSize GetFrameIconSize() const;
     virtual int HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const;
 
     virtual wxSize GetFrameIconSize() const;
     virtual int HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const;
 
-    virtual wxIcon GetStdIcon(int which) const;
-
     virtual void GetComboBitmaps(wxBitmap *bmpNormal,
                                  wxBitmap *bmpFocus,
                                  wxBitmap *bmpPressed,
     virtual void GetComboBitmaps(wxBitmap *bmpNormal,
                                  wxBitmap *bmpFocus,
                                  wxBitmap *bmpPressed,
@@ -346,20 +361,28 @@ public:
     virtual wxCoord GetCheckItemMargin() const
         { return 0; }
 
     virtual wxCoord GetCheckItemMargin() const
         { return 0; }
 
+    virtual wxSize GetToolBarButtonSize(wxCoord *separator) const
+        { if ( separator ) *separator = 5; return wxSize(16, 15); }
+    virtual wxSize GetToolBarMargin() const
+        { return wxSize(4, 4); }
+
     virtual wxRect GetTextTotalArea(const wxTextCtrl *text,
     virtual wxRect GetTextTotalArea(const wxTextCtrl *text,
-                                    const wxRect& rect);
+                                    const wxRect& rect) const;
     virtual wxRect GetTextClientArea(const wxTextCtrl *text,
                                      const wxRect& rect,
     virtual wxRect GetTextClientArea(const wxTextCtrl *text,
                                      const wxRect& rect,
-                                     wxCoord *extraSpaceBeyond);
+                                     wxCoord *extraSpaceBeyond) const;
 
     virtual wxSize GetTabIndent() const { return wxSize(2, 2); }
     virtual wxSize GetTabPadding() const { return wxSize(6, 5); }
 
 
     virtual wxSize GetTabIndent() const { return wxSize(2, 2); }
     virtual wxSize GetTabPadding() const { return wxSize(6, 5); }
 
-    virtual wxCoord GetSliderDim() const { return 20; }
-    virtual wxCoord GetSliderTickLen() const { return 4; }
+    virtual wxCoord GetSliderDim() const { return SLIDER_THUMB_LENGTH + 2*BORDER_THICKNESS; }
+    virtual wxCoord GetSliderTickLen() const { return SLIDER_TICK_LENGTH; }
     virtual wxRect GetSliderShaftRect(const wxRect& rect,
     virtual wxRect GetSliderShaftRect(const wxRect& rect,
-                                      wxOrientation orient) const;
+                                      int lenThumb,
+                                      wxOrientation orient,
+                                      long style = 0) const;
     virtual wxSize GetSliderThumbSize(const wxRect& rect,
     virtual wxSize GetSliderThumbSize(const wxRect& rect,
+                                      int lenThumb,
                                       wxOrientation orient) const;
     virtual wxSize GetProgressBarStep() const { return wxSize(16, 32); }
 
                                       wxOrientation orient) const;
     virtual wxSize GetProgressBarStep() const { return wxSize(16, 32); }
 
@@ -394,7 +417,8 @@ protected:
     // DrawButtonBorder() helper
     void DoDrawBackground(wxDC& dc,
                           const wxColour& col,
     // DrawButtonBorder() helper
     void DoDrawBackground(wxDC& dc,
                           const wxColour& col,
-                          const wxRect& rect);
+                          const wxRect& rect,
+                          wxWindow *window = NULL );
 
     // DrawBorder() helpers: all of them shift and clip the DC after drawing
     // the border
 
     // DrawBorder() helpers: all of them shift and clip the DC after drawing
     // the border
@@ -525,7 +549,8 @@ public:
 protected:
     virtual bool IsAllowedButton(int button) { return button == 1; }
 
 protected:
     virtual bool IsAllowedButton(int button) { return button == 1; }
 
-    virtual void Highlight(wxScrollBar *scrollbar, bool doIt)
+    virtual void Highlight(wxScrollBar * WXUNUSED(scrollbar),
+                           bool WXUNUSED(doIt))
     {
         // we don't highlight anything
     }
     {
         // we don't highlight anything
     }
@@ -586,14 +611,24 @@ private:
     bool m_isOnGrip;
 };
 
     bool m_isOnGrip;
 };
 
+class wxWin32SystemMenuEvtHandler;
+
 class wxWin32FrameInputHandler : public wxStdFrameInputHandler
 {
 public:
 class wxWin32FrameInputHandler : public wxStdFrameInputHandler
 {
 public:
-    wxWin32FrameInputHandler(wxInputHandler *handler)
-        : wxStdFrameInputHandler(handler) { }
+    wxWin32FrameInputHandler(wxInputHandler *handler);
+    ~wxWin32FrameInputHandler();
 
     virtual bool HandleMouse(wxInputConsumer *control,
                              const wxMouseEvent& event);
 
     virtual bool HandleMouse(wxInputConsumer *control,
                              const wxMouseEvent& event);
+
+    virtual bool HandleActivation(wxInputConsumer *consumer, bool activated);
+                             
+    void PopupSystemMenu(wxTopLevelWindow *window, const wxPoint& pos) const;
+
+private:
+    // was the mouse over the grip last time we checked?
+    wxWin32SystemMenuEvtHandler *m_menuHandler;
 };
 
 // ----------------------------------------------------------------------------
 };
 
 // ----------------------------------------------------------------------------
@@ -607,11 +642,23 @@ public:
     virtual wxColour GetBackground(wxWindow *win) const;
 };
 
     virtual wxColour GetBackground(wxWindow *win) const;
 };
 
+// ----------------------------------------------------------------------------
+// wxWin32ArtProvider
+// ----------------------------------------------------------------------------
+
+class wxWin32ArtProvider : public wxArtProvider
+{
+protected:
+    virtual wxBitmap CreateBitmap(const wxArtID& id,
+                                  const wxArtClient& client,
+                                  const wxSize& size);
+};
+
 // ----------------------------------------------------------------------------
 // wxWin32Theme
 // ----------------------------------------------------------------------------
 
 // ----------------------------------------------------------------------------
 // wxWin32Theme
 // ----------------------------------------------------------------------------
 
-WX_DEFINE_ARRAY(wxInputHandler *, wxArrayHandlers);
+WX_DEFINE_ARRAY_NO_PTR(wxInputHandler *, wxArrayHandlers);
 
 class wxWin32Theme : public wxTheme
 {
 
 class wxWin32Theme : public wxTheme
 {
@@ -620,6 +667,7 @@ public:
     virtual ~wxWin32Theme();
 
     virtual wxRenderer *GetRenderer();
     virtual ~wxWin32Theme();
 
     virtual wxRenderer *GetRenderer();
+    virtual wxArtProvider *GetArtProvider();
     virtual wxInputHandler *GetInputHandler(const wxString& control);
     virtual wxColourScheme *GetColourScheme();
 
     virtual wxInputHandler *GetInputHandler(const wxString& control);
     virtual wxColourScheme *GetColourScheme();
 
@@ -628,6 +676,8 @@ private:
     wxInputHandler *GetDefaultInputHandler();
 
     wxWin32Renderer *m_renderer;
     wxInputHandler *GetDefaultInputHandler();
 
     wxWin32Renderer *m_renderer;
+    
+    wxWin32ArtProvider *m_artProvider;
 
     // the names of the already created handlers and the handlers themselves
     // (these arrays are synchronized)
 
     // the names of the already created handlers and the handlers themselves
     // (these arrays are synchronized)
@@ -1139,6 +1189,7 @@ wxWin32Theme::wxWin32Theme()
     m_scheme = NULL;
     m_renderer = NULL;
     m_handlerDefault = NULL;
     m_scheme = NULL;
     m_renderer = NULL;
     m_handlerDefault = NULL;
+    m_artProvider = NULL;
 }
 
 wxWin32Theme::~wxWin32Theme()
 }
 
 wxWin32Theme::~wxWin32Theme()
@@ -1154,6 +1205,7 @@ wxWin32Theme::~wxWin32Theme()
 
     delete m_renderer;
     delete m_scheme;
 
     delete m_renderer;
     delete m_scheme;
+    wxArtProvider::RemoveProvider(m_artProvider);
 }
 
 wxRenderer *wxWin32Theme::GetRenderer()
 }
 
 wxRenderer *wxWin32Theme::GetRenderer()
@@ -1166,6 +1218,16 @@ wxRenderer *wxWin32Theme::GetRenderer()
     return m_renderer;
 }
 
     return m_renderer;
 }
 
+wxArtProvider *wxWin32Theme::GetArtProvider()
+{
+    if ( !m_artProvider )
+    {
+        m_artProvider = new wxWin32ArtProvider;
+    }
+
+    return m_artProvider;
+}
+
 wxInputHandler *wxWin32Theme::GetDefaultInputHandler()
 {
     if ( !m_handlerDefault )
 wxInputHandler *wxWin32Theme::GetDefaultInputHandler()
 {
     if ( !m_handlerDefault )
@@ -1226,6 +1288,10 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control)
         else if ( control == wxINP_HANDLER_STATUSBAR )
             handler = new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
 #endif // wxUSE_STATUSBAR
         else if ( control == wxINP_HANDLER_STATUSBAR )
             handler = new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
 #endif // wxUSE_STATUSBAR
+#if wxUSE_TOOLBAR
+        else if ( control == wxINP_HANDLER_TOOLBAR )
+            handler = new wxStdToolbarInputHandler(GetDefaultInputHandler());
+#endif // wxUSE_TOOLBAR
         else if ( control == wxINP_HANDLER_TOPLEVEL )
             handler = new wxWin32FrameInputHandler(GetDefaultInputHandler());
         else
         else if ( control == wxINP_HANDLER_TOPLEVEL )
             handler = new wxWin32FrameInputHandler(GetDefaultInputHandler());
         else
@@ -1313,8 +1379,12 @@ wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col) const
 
         case CONTROL_TEXT:      return wxColour(GetSysColor(COLOR_BTNTEXT));
 
 
         case CONTROL_TEXT:      return wxColour(GetSysColor(COLOR_BTNTEXT));
 
-        case SCROLLBAR:         return wxColour(GetSysColor(COLOR_SCROLLBAR));
-        case SCROLLBAR_PRESSED: return wxColour(GetSysColor(COLOR_HIGHLIGHT));
+#if defined(COLOR_3DLIGHT)
+        case SCROLLBAR:         return wxColour(GetSysColor(COLOR_3DLIGHT));
+#else
+        case SCROLLBAR:         return wxColour(0xe0e0e0);
+#endif
+        case SCROLLBAR_PRESSED: return wxColour(GetSysColor(COLOR_BTNTEXT));
 
         case HIGHLIGHT:         return wxColour(GetSysColor(COLOR_HIGHLIGHT));
         case HIGHLIGHT_TEXT:    return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT));
 
         case HIGHLIGHT:         return wxColour(GetSysColor(COLOR_HIGHLIGHT));
         case HIGHLIGHT_TEXT:    return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT));
@@ -1337,7 +1407,7 @@ wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col) const
         case TITLEBAR_ACTIVE:   return wxColour(GetSysColor(COLOR_ACTIVECAPTION));
         case TITLEBAR_TEXT:     return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT));
         case TITLEBAR_ACTIVE_TEXT: return wxColour(GetSysColor(COLOR_CAPTIONTEXT));
         case TITLEBAR_ACTIVE:   return wxColour(GetSysColor(COLOR_ACTIVECAPTION));
         case TITLEBAR_TEXT:     return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT));
         case TITLEBAR_ACTIVE_TEXT: return wxColour(GetSysColor(COLOR_CAPTIONTEXT));
-        
+
         case DESKTOP:           return wxColour(0x808000);
 #else // !__WXMSW__
         // use the standard Windows colours elsewhere
         case DESKTOP:           return wxColour(0x808000);
 #else // !__WXMSW__
         // use the standard Windows colours elsewhere
@@ -1680,8 +1750,7 @@ void wxWin32Renderer::DrawHalfRect(wxDC& dc, wxRect *rect, const wxPen& pen)
                 rect->GetRight(), rect->GetBottom());
 
     // adjust the rect
                 rect->GetRight(), rect->GetBottom());
 
     // adjust the rect
-    rect->width--;
-    rect->height--;
+    rect->Inflate(-1);
 }
 
 void wxWin32Renderer::DrawShadedRect(wxDC& dc, wxRect *rect,
 }
 
 void wxWin32Renderer::DrawShadedRect(wxDC& dc, wxRect *rect,
@@ -1811,8 +1880,12 @@ wxRect wxWin32Renderer::GetBorderDimensions(wxBorder border) const
             break;
 
         default:
             break;
 
         default:
+        { 
+            // char *crash = NULL;
+            // *crash = 0;
             wxFAIL_MSG(_T("unknown border type"));
             // fall through
             wxFAIL_MSG(_T("unknown border type"));
             // fall through
+        }
 
         case wxBORDER_DEFAULT:
         case wxBORDER_NONE:
 
         case wxBORDER_DEFAULT:
         case wxBORDER_NONE:
@@ -2332,6 +2405,40 @@ void wxWin32Renderer::DrawCheckButton(wxDC& dc,
                            0); // no focus rect offset for checkboxes
 }
 
                            0); // no focus rect offset for checkboxes
 }
 
+void wxWin32Renderer::DrawToolBarButton(wxDC& dc,
+                                        const wxString& label,
+                                        const wxBitmap& bitmap,
+                                        const wxRect& rectOrig,
+                                        int flags,
+                                        long style)
+{
+    if (style == wxTOOL_STYLE_BUTTON)
+    {
+        wxRect rect = rectOrig;
+        rect.Deflate(BORDER_THICKNESS);
+
+        if ( flags & wxCONTROL_PRESSED )
+        {
+            DrawBorder(dc, wxBORDER_SUNKEN, rect, flags);
+        }
+        else if ( flags & wxCONTROL_CURRENT )
+        {
+            DrawBorder(dc, wxBORDER_RAISED, rect, flags);
+        }
+
+        dc.DrawLabel(label, bitmap, rect, wxALIGN_CENTRE);
+    }
+    else if (style == wxTOOL_STYLE_SEPARATOR)
+    {
+        // leave a small gap aroudn the line, also account for the toolbar
+        // border itself
+        DrawVerticalLine(dc, rectOrig.x + rectOrig.width/2,
+                         rectOrig.y + 2*BORDER_THICKNESS,
+                         rectOrig.GetBottom() - BORDER_THICKNESS);
+    }
+    // don't draw wxTOOL_STYLE_CONTROL
+}
+
 // ----------------------------------------------------------------------------
 // text control
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // text control
 // ----------------------------------------------------------------------------
@@ -2347,7 +2454,9 @@ void wxWin32Renderer::DrawTextLine(wxDC& dc,
     StandardDrawTextLine(dc, text, rect, selStart, selEnd, flags);
 }
 
     StandardDrawTextLine(dc, text, rect, selStart, selEnd, flags);
 }
 
-void wxWin32Renderer::DrawLineWrapMark(wxDC& dc, const wxRect& rect)
+void
+wxWin32Renderer::DrawLineWrapMark(wxDC& WXUNUSED(dc),
+                                  const wxRect& WXUNUSED(rect))
 {
     // we don't draw them
 }
 {
     // we don't draw them
 }
@@ -2478,53 +2587,82 @@ void wxWin32Renderer::DrawTab(wxDC& dc,
 // slider
 // ----------------------------------------------------------------------------
 
 // slider
 // ----------------------------------------------------------------------------
 
-wxSize wxWin32Renderer::GetSliderThumbSize(const wxRect& rect,
-                                           wxOrientation orient) const
+wxSize
+wxWin32Renderer::GetSliderThumbSize(const wxRect& WXUNUSED(rect),
+                                    int lenThumb,
+                                    wxOrientation orient) const
 {
     wxSize size;
 {
     wxSize size;
+    wxCoord width  = wxMax (lenThumb, SLIDER_THUMB_LENGTH) / 2;
+    wxCoord height = wxMax (lenThumb, SLIDER_THUMB_LENGTH);
 
 
-    wxRect rectShaft = GetSliderShaftRect(rect, orient);
-    if ( orient == wxHORIZONTAL )
+    if (orient == wxHORIZONTAL) 
     {
     {
-        size.y = rect.height - 6;
-        size.x = wxMin(size.y / 2, rectShaft.width);
+        size.x = width;
+        size.y = height;
     }
     }
-    else // vertical
-    {
-        size.x = rect.width - 6;
-        size.y = wxMin(size.x / 2, rectShaft.height);
+    else
+    { // == wxVERTICAL
+        size.x = height;
+        size.y = width;
     }
 
     return size;
 }
 
 wxRect wxWin32Renderer::GetSliderShaftRect(const wxRect& rectOrig,
     }
 
     return size;
 }
 
 wxRect wxWin32Renderer::GetSliderShaftRect(const wxRect& rectOrig,
-                                           wxOrientation orient) const
+                                           int lenThumb,
+                                           wxOrientation orient,
+                                           long style) const
 {
 {
-    static const wxCoord SLIDER_MARGIN = 6;
+    bool transpose = (orient == wxVERTICAL);
+    bool left  = ((style & wxSL_AUTOTICKS) != 0) &
+                 (((style & wxSL_TOP) != 0) & !transpose |
+                  ((style & wxSL_LEFT) != 0) & transpose |
+                  ((style & wxSL_BOTH) != 0));
+    bool right = ((style & wxSL_AUTOTICKS) != 0) &
+                 (((style & wxSL_BOTTOM) != 0) & !transpose |
+                  ((style & wxSL_RIGHT) != 0) & transpose |
+                  ((style & wxSL_BOTH) != 0));
 
     wxRect rect = rectOrig;
 
 
     wxRect rect = rectOrig;
 
-    if ( orient == wxHORIZONTAL )
-    {
-        // make the rect of minimal width and centre it
-        rect.height = 2*BORDER_THICKNESS;
-        rect.y = rectOrig.y + (rectOrig.height - rect.height) / 2;
-        if ( rect.y < 0 )
-            rect.y = 0;
+    wxSize sizeThumb = GetSliderThumbSize (rect, lenThumb, orient);
 
 
-        // leave margins on the sides
-        rect.Deflate(SLIDER_MARGIN, 0);
+    if (orient == wxHORIZONTAL) {
+        rect.x += SLIDER_MARGIN;
+        if (left & right) 
+        {
+            rect.y += wxMax ((rect.height - 2*BORDER_THICKNESS) / 2, sizeThumb.y/2);
+        }
+        else if (left) 
+        {
+            rect.y += wxMax ((rect.height - 2*BORDER_THICKNESS - sizeThumb.y/2), sizeThumb.y/2);
+        }
+        else
+        {
+            rect.y += sizeThumb.y/2;
+        }
+        rect.width -= 2*SLIDER_MARGIN;
+        rect.height = 2*BORDER_THICKNESS;
     }
     }
-    else // vertical
-    {
-        // same as above but in other direction
+    else
+    { // == wxVERTICAL
+        rect.y += SLIDER_MARGIN;
+        if (left & right) 
+        {
+            rect.x += wxMax ((rect.width - 2*BORDER_THICKNESS) / 2, sizeThumb.x/2);
+        }
+        else if (left) 
+        {
+            rect.x += wxMax ((rect.width - 2*BORDER_THICKNESS - sizeThumb.x/2), sizeThumb.x/2);
+        }
+        else
+        {
+            rect.x += sizeThumb.x/2;
+        }
         rect.width = 2*BORDER_THICKNESS;
         rect.width = 2*BORDER_THICKNESS;
-        rect.x = rectOrig.x + (rectOrig.width - rect.width) / 2;
-        if ( rect.x < 0 )
-            rect.x = 0;
-
-        rect.Deflate(0, SLIDER_MARGIN);
+        rect.height -= 2*SLIDER_MARGIN;
     }
 
     return rect;
     }
 
     return rect;
@@ -2532,19 +2670,37 @@ wxRect wxWin32Renderer::GetSliderShaftRect(const wxRect& rectOrig,
 
 void wxWin32Renderer::DrawSliderShaft(wxDC& dc,
                                       const wxRect& rectOrig,
 
 void wxWin32Renderer::DrawSliderShaft(wxDC& dc,
                                       const wxRect& rectOrig,
+                                      int lenThumb,
                                       wxOrientation orient,
                                       int flags,
                                       wxOrientation orient,
                                       int flags,
+                                      long style,
                                       wxRect *rectShaft)
 {
                                       wxRect *rectShaft)
 {
-    if ( flags & wxCONTROL_FOCUSED )
-    {
+    /*    show shaft geometry
+
+             shaft
+        +-------------+
+        |             |
+        |     XXX     |  <-- x1
+        |     XXX     |
+        |     XXX     |
+        |     XXX     |
+        |     XXX     |  <-- x2
+        |             |
+        +-------------+
+
+              ^ ^
+              | |
+             y1 y2
+    */
+
+    if (flags & wxCONTROL_FOCUSED) {
         DrawFocusRect(dc, rectOrig);
     }
 
         DrawFocusRect(dc, rectOrig);
     }
 
-    wxRect rect = GetSliderShaftRect(rectOrig, orient);
+    wxRect rect = GetSliderShaftRect(rectOrig, lenThumb, orient, style);
 
 
-    if ( rectShaft )
-        *rectShaft = rect;
+    if (rectShaft) *rectShaft = rect;
 
     DrawSunkenBorder(dc, &rect);
 }
 
     DrawSunkenBorder(dc, &rect);
 }
@@ -2552,26 +2708,31 @@ void wxWin32Renderer::DrawSliderShaft(wxDC& dc,
 void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
                                       const wxRect& rect,
                                       wxOrientation orient,
 void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
                                       const wxRect& rect,
                                       wxOrientation orient,
-                                      int flags)
+                                      int flags,
+                                      long style)
 {
 {
-    /*
-       we are drawing a shape of this form
-
-       HHHHHHB <--- y
-       H    DB
-       H    DB
-       H    DB   where H is hightlight colour
-       H    DB         D    dark grey
-       H    DB         B    black
-       H    DB
-       H    DB <--- y3
-        H  DB
-         HDB
-          B    <--- y2
-
-       ^  ^  ^
-       |  |  |
-       x x3  x2
+    /*    show thumb geometry
+
+             H       <--- y1
+           H H B
+         H     H B
+       H         H B <--- y3
+       H         D B
+       H         D B
+       H         D B
+       H         D B   where H is hightlight colour
+       H         D B         D    dark grey
+       H         D B         B    black
+       H         D B
+       H         D B
+       H         D B <--- y4
+         H     D B
+           H D B
+             B       <--- y2
+
+       ^     ^     ^
+       |     |     |
+       x1    x3    x2
 
        The interior of this shape is filled with the hatched brush if the thumb
        is pressed.
 
        The interior of this shape is filled with the hatched brush if the thumb
        is pressed.
@@ -2579,51 +2740,81 @@ void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
 
     DrawBackground(dc, wxNullColour, rect, flags);
 
 
     DrawBackground(dc, wxNullColour, rect, flags);
 
-    bool transpose = orient == wxVERTICAL;
+    bool transpose = (orient == wxVERTICAL);
+    bool left  = ((style & wxSL_AUTOTICKS) != 0) &
+                 (((style & wxSL_TOP) != 0) & !transpose |
+                  ((style & wxSL_LEFT) != 0) & transpose) &
+                 ((style & wxSL_BOTH) == 0);
+    bool right = ((style & wxSL_AUTOTICKS) != 0) &
+                 (((style & wxSL_BOTTOM) != 0) & !transpose |
+                  ((style & wxSL_RIGHT) != 0) & transpose) &
+                 ((style & wxSL_BOTH) == 0);
+
+    wxCoord sizeArrow = (transpose ? rect.height : rect.width) / 2;
+    wxCoord c = ((transpose ? rect.height : rect.width) - 2*sizeArrow);
+
+    wxCoord x1, x2, x3, y1, y2, y3, y4;
+    x1 = (transpose ? rect.y : rect.x);
+    x2 = (transpose ? rect.GetBottom() : rect.GetRight());
+    x3 = (x1-1+c) + sizeArrow;
+    y1 = (transpose ? rect.x : rect.y);
+    y2 = (transpose ? rect.GetRight() : rect.GetBottom());
+    y3 = (left  ? (y1-1+c) + sizeArrow : y1);
+    y4 = (right ? (y2+1-c) - sizeArrow : y2);
 
 
-    wxCoord x, y, x2, y2;
-    if ( transpose )
+    dc.SetPen(m_penBlack);
+    if (left) {
+        DrawLine(dc, x3+1-c, y1, x2, y3, transpose);
+    }
+    DrawLine(dc, x2, y3, x2, y4, transpose);
+    if (right) 
     {
     {
-        x = rect.y;
-        y = rect.x;
-        x2 = rect.GetBottom();
-        y2 = rect.GetRight();
+        DrawLine(dc, x3+1-c, y2, x2, y4, transpose);
     }
     else
     {
     }
     else
     {
-        x = rect.x;
-        y = rect.y;
-        x2 = rect.GetRight();
-        y2 = rect.GetBottom();
+        DrawLine(dc, x1, y2, x2, y2, transpose);
     }
 
     }
 
-    // the size of the pointed part of the thumb
-    wxCoord sizeArrow = (transpose ? rect.height : rect.width) / 2;
-
-    wxCoord x3 = x + sizeArrow,
-            y3 = y2 - sizeArrow;
-
-    dc.SetPen(m_penHighlight);
-    DrawLine(dc, x, y, x2, y, transpose);
-    DrawLine(dc, x, y + 1, x, y2 - sizeArrow, transpose);
-    DrawLine(dc, x, y3, x3, y2, transpose);
-
-    dc.SetPen(m_penBlack);
-    DrawLine(dc, x3, y2, x2, y3, transpose);
-    DrawLine(dc, x2, y3, x2, y - 1, transpose);
-
     dc.SetPen(m_penDarkGrey);
     dc.SetPen(m_penDarkGrey);
-    DrawLine(dc, x3, y2 - 1, x2 - 1, y3, transpose);
-    DrawLine(dc, x2 - 1, y3, x2 - 1, y, transpose);
+    DrawLine(dc, x2-1, y3+1, x2-1, y4-1, transpose);
+    if (right) {
+        DrawLine(dc, x3+1-c, y2-1, x2-1, y4, transpose);
+    }
+    else
+    {
+        DrawLine(dc, x1+1, y2-1, x2-1, y2-1, transpose);
+    }
 
 
-    if ( flags & wxCONTROL_PRESSED )
+    dc.SetPen(m_penHighlight);
+    if (left) 
+    {
+        DrawLine(dc, x1, y3, x3, y1, transpose);
+        DrawLine(dc, x3+1-c, y1+1, x2-1, y3, transpose);
+    }
+    else
     {
     {
+        DrawLine(dc, x1, y1, x2, y1, transpose);
+    }
+    DrawLine(dc, x1, y3, x1, y4, transpose);
+    if (right) 
+    {
+        DrawLine(dc, x1, y4, x3+c, y2+c, transpose);
+    }
+
+    if (flags & wxCONTROL_PRESSED) {
         // TODO: MSW fills the entire area inside, not just the rect
         wxRect rectInt = rect;
         // TODO: MSW fills the entire area inside, not just the rect
         wxRect rectInt = rect;
-        if ( transpose )
-            rectInt.SetRight(y3);
+        if ( transpose ) 
+        {
+            rectInt.SetLeft(y3);
+            rectInt.SetRight(y4);
+        }
         else
         else
-            rectInt.SetBottom(y3);
+        {
+            rectInt.SetTop(y3);
+            rectInt.SetBottom(y4);
+        }
         rectInt.Deflate(2);
 
 #if !defined(__WXMGL__)
         rectInt.Deflate(2);
 
 #if !defined(__WXMGL__)
@@ -2665,70 +2856,80 @@ void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
 
 void wxWin32Renderer::DrawSliderTicks(wxDC& dc,
                                       const wxRect& rect,
 
 void wxWin32Renderer::DrawSliderTicks(wxDC& dc,
                                       const wxRect& rect,
-                                      const wxSize& sizeThumb,
+                                      int lenThumb,
                                       wxOrientation orient,
                                       int start,
                                       int end,
                                       int step,
                                       wxOrientation orient,
                                       int start,
                                       int end,
                                       int step,
-                                      int flags)
+                                      int WXUNUSED(flags),
+                                      long style)
 {
 {
-    if ( end == start )
-    {
-        // empty slider?
-        return;
-    }
-
-    // the variable names correspond to horizontal case, but they can be used
-    // for both orientations
-    wxCoord x1, x2, y1, y2, len, widthThumb;
-    if ( orient == wxHORIZONTAL )
-    {
-        x1 = rect.GetLeft();
-        x2 = rect.GetRight();
-
-        // draw from bottom to top to leave one pixel space between the ticks
-        // and the slider as Windows do
-        y1 = rect.GetBottom();
-        y2 = rect.GetTop();
-
-        len = rect.width;
-
-        widthThumb = sizeThumb.x;
-    }
-    else // vertical
-    {
-        x1 = rect.GetTop();
-        x2 = rect.GetBottom();
-
-        y1 = rect.GetRight();
-        y2 = rect.GetLeft();
-
-        len = rect.height;
-
-        widthThumb = sizeThumb.y;
-    }
-
-    // the first tick should be positioned in such way that a thumb drawn in
-    // the first position points down directly to it
-    x1 += widthThumb / 2;
-    x2 -= widthThumb / 2;
+    /*    show ticks geometry
+
+        left        right
+        ticks shaft ticks
+        ----   XX   ----  <-- x1
+        ----   XX   ----
+        ----   XX   ----
+        ----   XX   ----  <-- x2
+
+        ^  ^        ^  ^
+        |  |        |  |
+        y3 y1       y2 y4
+    */
 
 
-    // this also means that we have slightly less space for the ticks in
-    // between the first and the last
-    len -= widthThumb;
+    // empty slider?
+    if (end == start) return;
+
+    bool transpose = (orient == wxVERTICAL);
+    bool left  = ((style & wxSL_AUTOTICKS) != 0) &
+                 (((style & wxSL_TOP) != 0) & !transpose |
+                  ((style & wxSL_LEFT) != 0) & transpose |
+                  ((style & wxSL_BOTH) != 0));
+    bool right = ((style & wxSL_AUTOTICKS) != 0) &
+                 (((style & wxSL_BOTTOM) != 0) & !transpose |
+                  ((style & wxSL_RIGHT) != 0) & transpose |
+                  ((style & wxSL_BOTH) != 0));
+
+    // default thumb size
+    wxSize sizeThumb = GetSliderThumbSize (rect, 0, orient);
+    wxCoord defaultLen = (transpose ? sizeThumb.x : sizeThumb.y);
+
+    // normal thumb size
+    sizeThumb = GetSliderThumbSize (rect, lenThumb, orient);
+    wxCoord widthThumb  = (transpose ? sizeThumb.y : sizeThumb.x);
+
+    wxRect rectShaft = GetSliderShaftRect (rect, lenThumb, orient, style);
+
+    wxCoord x1, x2, y1, y2, y3, y4 , len;
+    x1 = (transpose ? rectShaft.y : rectShaft.x) + widthThumb/2;
+    x2 = (transpose ? rectShaft.GetBottom() : rectShaft.GetRight()) - widthThumb/2;
+    y1 = (transpose ? rectShaft.x : rectShaft.y) - defaultLen/2;
+    y2 = (transpose ? rectShaft.GetRight() : rectShaft.GetBottom()) + defaultLen/2;
+    y3 = (transpose ? rect.x : rect.y);
+    y4 = (transpose ? rect.GetRight() : rect.GetBottom());
+    len = x2 - x1;
 
     dc.SetPen(m_penBlack);
 
     int range = end - start;
 
     dc.SetPen(m_penBlack);
 
     int range = end - start;
-    for ( int n = 0; n < range; n += step )
-    {
+    for ( int n = 0; n < range; n += step ) {
         wxCoord x = x1 + (len*n) / range;
 
         wxCoord x = x1 + (len*n) / range;
 
-        DrawLine(dc, x, y1, x, y2, orient == wxVERTICAL);
+        if (left & (y1 > y3)) {
+            DrawLine(dc, x, y1, x, y3, orient == wxVERTICAL);
+        }
+        if (right & (y4 > y2)) {
+            DrawLine(dc, x, y2, x, y4, orient == wxVERTICAL);
+        }
     }
     }
-
     // always draw the line at the end position
     // always draw the line at the end position
-    DrawLine(dc, x2, y1, x2, y2, orient == wxVERTICAL);
+    if (left & (y1 > y3)) {
+        DrawLine(dc, x2, y1, x2, y3, orient == wxVERTICAL);
+    }
+    if (right & (y4 > y2)) {
+        DrawLine(dc, x2, y2, x2, y4, orient == wxVERTICAL);
+    }
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -2925,7 +3126,7 @@ wxMenuGeometryInfo *wxWin32Renderer::GetMenuGeometry(wxWindow *win,
             widthAccelMax = 0,
             widthBmpMax = MENU_LEFT_MARGIN;
 
             widthAccelMax = 0,
             widthBmpMax = MENU_LEFT_MARGIN;
 
-    for ( wxMenuItemList::Node *node = menu.GetMenuItems().GetFirst();
+    for ( wxMenuItemList::compatibility_iterator node = menu.GetMenuItems().GetFirst();
           node;
           node = node->GetNext() )
     {
           node;
           node = node->GetNext() )
     {
@@ -3074,7 +3275,7 @@ void wxWin32Renderer::DrawStatusField(wxDC& dc,
 // ----------------------------------------------------------------------------
 
 void wxWin32Renderer::GetComboBitmaps(wxBitmap *bmpNormal,
 // ----------------------------------------------------------------------------
 
 void wxWin32Renderer::GetComboBitmaps(wxBitmap *bmpNormal,
-                                      wxBitmap *bmpFocus,
+                                      wxBitmap * WXUNUSED(bmpFocus),
                                       wxBitmap *bmpPressed,
                                       wxBitmap *bmpDisabled)
 {
                                       wxBitmap *bmpPressed,
                                       wxBitmap *bmpDisabled)
 {
@@ -3114,7 +3315,8 @@ void wxWin32Renderer::GetComboBitmaps(wxBitmap *bmpNormal,
 
 void wxWin32Renderer::DoDrawBackground(wxDC& dc,
                                        const wxColour& col,
 
 void wxWin32Renderer::DoDrawBackground(wxDC& dc,
                                        const wxColour& col,
-                                       const wxRect& rect)
+                                       const wxRect& rect,
+                                       wxWindow * WXUNUSED(window))
 {
     wxBrush brush(col, wxSOLID);
     dc.SetBrush(brush);
 {
     wxBrush brush(col, wxSOLID);
     dc.SetBrush(brush);
@@ -3125,11 +3327,12 @@ void wxWin32Renderer::DoDrawBackground(wxDC& dc,
 void wxWin32Renderer::DrawBackground(wxDC& dc,
                                      const wxColour& col,
                                      const wxRect& rect,
 void wxWin32Renderer::DrawBackground(wxDC& dc,
                                      const wxColour& col,
                                      const wxRect& rect,
-                                     int flags)
+                                     int WXUNUSED(flags),
+                                     wxWindow *window)
 {
     // just fill it with the given or default bg colour
     wxColour colBg = col.Ok() ? col : wxSCHEME_COLOUR(m_scheme, CONTROL);
 {
     // just fill it with the given or default bg colour
     wxColour colBg = col.Ok() ? col : wxSCHEME_COLOUR(m_scheme, CONTROL);
-    DoDrawBackground(dc, colBg, rect);
+    DoDrawBackground(dc, colBg, rect, window );
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -3201,9 +3404,9 @@ void wxWin32Renderer::DrawArrowButton(wxDC& dc,
 }
 
 void wxWin32Renderer::DrawScrollbarThumb(wxDC& dc,
 }
 
 void wxWin32Renderer::DrawScrollbarThumb(wxDC& dc,
-                                         wxOrientation orient,
+                                         wxOrientation WXUNUSED(orient),
                                          const wxRect& rect,
                                          const wxRect& rect,
-                                         int flags)
+                                         int WXUNUSED(flags))
 {
     // we don't use the flags, the thumb never changes appearance
     wxRect rectThumb = rect;
 {
     // we don't use the flags, the thumb never changes appearance
     wxRect rectThumb = rect;
@@ -3212,7 +3415,7 @@ void wxWin32Renderer::DrawScrollbarThumb(wxDC& dc,
 }
 
 void wxWin32Renderer::DrawScrollbarShaft(wxDC& dc,
 }
 
 void wxWin32Renderer::DrawScrollbarShaft(wxDC& dc,
-                                         wxOrientation orient,
+                                         wxOrientation WXUNUSED(orient),
                                          const wxRect& rectBar,
                                          int flags)
 {
                                          const wxRect& rectBar,
                                          int flags)
 {
@@ -3466,7 +3669,7 @@ void wxWin32Renderer::DrawFrameTitle(wxDC& dc,
 
     dc.SetFont(m_titlebarFont);
     dc.SetTextForeground(col);
 
     dc.SetFont(m_titlebarFont);
     dc.SetTextForeground(col);
-    
+
     wxCoord textW;
     dc.GetTextExtent(title, &textW, NULL);
     if ( textW > r.width )
     wxCoord textW;
     dc.GetTextExtent(title, &textW, NULL);
     if ( textW > r.width )
@@ -3493,11 +3696,11 @@ void wxWin32Renderer::DrawFrameTitle(wxDC& dc,
             s << title[i];
         }
         s << wxT("...");
             s << title[i];
         }
         s << wxT("...");
-        dc.DrawLabel(s, wxNullBitmap, r, 
+        dc.DrawLabel(s, wxNullBitmap, r,
                      wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
     }
     else
                      wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
     }
     else
-        dc.DrawLabel(title, wxNullBitmap, r, 
+        dc.DrawLabel(title, wxNullBitmap, r,
                      wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
 }
 
                      wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
 }
 
@@ -3796,26 +3999,19 @@ static char *warning_xpm[]={
 "....ddddddddddddddddddddddddddd.",
 ".....ddddddddddddddddddddddddd.."};
 
 "....ddddddddddddddddddddddddddd.",
 ".....ddddddddddddddddddddddddd.."};
 
-wxIcon wxWin32Renderer::GetStdIcon(int which) const
+wxBitmap wxWin32ArtProvider::CreateBitmap(const wxArtID& id,
+                                          const wxArtClient& WXUNUSED(client),
+                                          const wxSize& WXUNUSED(size))
 {
 {
-    switch(which)
-    {
-        case wxICON_INFORMATION:
-            return wxIcon(info_xpm);
-
-        case wxICON_QUESTION:
-            return wxIcon(question_xpm);
-
-        case wxICON_EXCLAMATION:
-            return wxIcon(warning_xpm);
-
-        default:
-            wxFAIL_MSG(wxT("requested non existent standard icon"));
-            // still fall through
-
-        case wxICON_HAND:
-            return wxIcon(error_xpm);
-    }
+    if ( id == wxART_INFORMATION )
+        return wxBitmap(info_xpm);
+    if ( id == wxART_ERROR )
+        return wxBitmap(error_xpm);
+    if ( id == wxART_WARNING )
+        return wxBitmap(warning_xpm);
+    if ( id == wxART_QUESTION )
+        return wxBitmap(question_xpm);
+    return wxNullBitmap;
 }
 
 
 }
 
 
@@ -3828,8 +4024,9 @@ static inline int GetTextBorderWidth()
     return 1;
 }
 
     return 1;
 }
 
-wxRect wxWin32Renderer::GetTextTotalArea(const wxTextCtrl *text,
-                                         const wxRect& rect)
+wxRect
+wxWin32Renderer::GetTextTotalArea(const wxTextCtrl * WXUNUSED(text),
+                                  const wxRect& rect) const
 {
     wxRect rectTotal = rect;
 
 {
     wxRect rectTotal = rect;
 
@@ -3842,9 +4039,10 @@ wxRect wxWin32Renderer::GetTextTotalArea(const wxTextCtrl *text,
     return rectTotal;
 }
 
     return rectTotal;
 }
 
-wxRect wxWin32Renderer::GetTextClientArea(const wxTextCtrl *text,
-                                          const wxRect& rect,
-                                          wxCoord *extraSpaceBeyond)
+wxRect
+wxWin32Renderer::GetTextClientArea(const wxTextCtrl * WXUNUSED(text),
+                                   const wxRect& rect,
+                                   wxCoord *extraSpaceBeyond) const
 {
     wxRect rectText = rect;
 
 {
     wxRect rectText = rect;
 
@@ -3897,6 +4095,18 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window)
                 size->y += 9;
         }
 
                 size->y += 9;
         }
 
+        // for compatibility with other ports, the buttons default size is never
+        // less than the standard one, but not when display not PDAs.
+        if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA)
+        {
+        if ( !(window->GetWindowStyle() & wxBU_EXACTFIT) )
+            {
+                       wxSize szDef = wxButton::GetDefaultSize();
+                if ( size->x < szDef.x )
+                    size->x = szDef.x;
+            }
+        }
+
         // no border width adjustments for buttons
         return;
     }
         // no border width adjustments for buttons
         return;
     }
@@ -3921,9 +4131,9 @@ wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer *renderer)
     m_renderer = renderer;
 }
 
     m_renderer = renderer;
 }
 
-bool wxWin32InputHandler::HandleKey(wxInputConsumer *control,
-                                    const wxKeyEvent& event,
-                                    bool pressed)
+bool wxWin32InputHandler::HandleKey(wxInputConsumer * WXUNUSED(control),
+                                    const wxKeyEvent& WXUNUSED(event),
+                                    bool WXUNUSED(pressed))
 {
     return FALSE;
 }
 {
     return FALSE;
 }
@@ -3935,7 +4145,9 @@ bool wxWin32InputHandler::HandleMouse(wxInputConsumer *control,
     if ( event.ButtonDown() )
     {
         wxWindow *win = control->GetInputWindow();
     if ( event.ButtonDown() )
     {
         wxWindow *win = control->GetInputWindow();
-        if ( wxWindow::FindFocus() != control->GetInputWindow() )
+
+        if (( wxWindow::FindFocus() != control->GetInputWindow() ) &&
+            ( win->AcceptsFocus() ) )
         {
             win->SetFocus();
 
         {
             win->SetFocus();
 
@@ -4061,6 +4273,8 @@ bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer *control,
         // if we're scrolling the scrollbar because the arrow or the shaft was
         // pressed, check that the mouse stays on the same scrollbar element
 
         // if we're scrolling the scrollbar because the arrow or the shaft was
         // pressed, check that the mouse stays on the same scrollbar element
 
+#if 0
+        // Always let thumb jump back if we leave the scrollbar
         if ( event.Moving() )
         {
             ht = m_renderer->HitTestScrollbar(scrollbar, event.GetPosition());
         if ( event.Moving() )
         {
             ht = m_renderer->HitTestScrollbar(scrollbar, event.GetPosition());
@@ -4069,6 +4283,21 @@ bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer *control,
         {
             ht = wxHT_NOWHERE;
         }
         {
             ht = wxHT_NOWHERE;
         }
+#else
+        // Jump back only if we get far away from it
+        wxPoint pos = event.GetPosition();
+        if (scrollbar->HasFlag( wxVERTICAL ))
+        {
+            if (pos.x > -40 && pos.x < scrollbar->GetSize().x+40)
+               pos.x = 5;
+        }
+        else
+        {
+            if (pos.y > -40 && pos.y < scrollbar->GetSize().y+40)
+               pos.y = 5;
+        }
+        ht = m_renderer->HitTestScrollbar(scrollbar, pos );
+#endif
 
         // if we're dragging the thumb and the mouse stays in the scrollbar, it
         // is still ok - we only want to catch the case when the mouse leaves
 
         // if we're dragging the thumb and the mouse stays in the scrollbar, it
         // is still ok - we only want to catch the case when the mouse leaves
@@ -4205,12 +4434,27 @@ bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow *statbar,
                                             const wxPoint& pt) const
 {
     if ( statbar->HasFlag(wxST_SIZEGRIP) &&
                                             const wxPoint& pt) const
 {
     if ( statbar->HasFlag(wxST_SIZEGRIP) &&
-            statbar->GetParent()->HasFlag(wxRESIZE_BORDER) )
+         statbar->GetParent()->HasFlag(wxRESIZE_BORDER) )
     {
     {
-        wxSize sizeSbar = statbar->GetSize();
+        wxTopLevelWindow *
+            parentTLW = wxDynamicCast(statbar->GetParent(), wxTopLevelWindow);
 
 
-        return (sizeSbar.x - pt.x) < (wxCoord)STATUSBAR_GRIP_SIZE &&
-               (sizeSbar.y - pt.y) < (wxCoord)STATUSBAR_GRIP_SIZE;
+        wxCHECK_MSG( parentTLW, FALSE,
+                     _T("the status bar should be a child of a TLW") );
+
+        // a maximized window can't be resized anyhow
+        if ( !parentTLW->IsMaximized() )
+        {
+            // VZ: I think that the standard Windows behaviour is to only
+            //     show the resizing cursor when the mouse is on top of the
+            //     grip itself but apparently different Windows versions behave
+            //     differently (?) and it seems a better UI to allow resizing
+            //     the status bar even when the mouse is above the grip
+            wxSize sizeSbar = statbar->GetSize();
+
+            int diff = sizeSbar.x - pt.x;
+            return diff >= 0 && diff < (wxCoord)STATUSBAR_GRIP_SIZE;
+        }
     }
 
     return FALSE;
     }
 
     return FALSE;
@@ -4272,26 +4516,188 @@ bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
 // wxWin32FrameInputHandler
 // ----------------------------------------------------------------------------
 
 // wxWin32FrameInputHandler
 // ----------------------------------------------------------------------------
 
+class wxWin32SystemMenuEvtHandler : public wxEvtHandler
+{
+public:
+    wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler *handler);
+    
+    void Attach(wxInputConsumer *consumer);
+    void Detach();
+    
+private:
+    DECLARE_EVENT_TABLE()
+    void OnSystemMenu(wxCommandEvent &event);
+    void OnCloseFrame(wxCommandEvent &event);
+    void OnClose(wxCloseEvent &event);
+   
+    wxWin32FrameInputHandler *m_inputHnd;
+    wxTopLevelWindow         *m_wnd;
+    wxAcceleratorTable        m_oldAccelTable;
+};
+
+wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
+                                wxWin32FrameInputHandler *handler)
+{
+    m_inputHnd = handler;
+    m_wnd = NULL;
+}
+
+void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer *consumer)
+{
+    wxASSERT_MSG( m_wnd == NULL, _T("can't attach the handler twice!") );
+
+    m_wnd = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
+    m_wnd->PushEventHandler(this);
+    
+    // VS: This code relies on using generic implementation of 
+    //     wxAcceleratorTable in wxUniv!
+    wxAcceleratorTable table = *m_wnd->GetAcceleratorTable();
+    m_oldAccelTable = table;
+    table.Add(wxAcceleratorEntry(wxACCEL_ALT, WXK_SPACE, wxID_SYSTEM_MENU));
+    table.Add(wxAcceleratorEntry(wxACCEL_ALT, WXK_F4, wxID_CLOSE_FRAME));
+    m_wnd->SetAcceleratorTable(table);
+}
+
+void wxWin32SystemMenuEvtHandler::Detach()
+{
+    if ( m_wnd )
+    {
+        m_wnd->SetAcceleratorTable(m_oldAccelTable);
+        m_wnd->RemoveEventHandler(this); 
+        m_wnd = NULL;
+    }
+}
+
+BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler, wxEvtHandler)
+    EVT_MENU(wxID_SYSTEM_MENU, wxWin32SystemMenuEvtHandler::OnSystemMenu)
+    EVT_MENU(wxID_CLOSE_FRAME, wxWin32SystemMenuEvtHandler::OnCloseFrame)
+    EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose)
+END_EVENT_TABLE()
+
+void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent &WXUNUSED(event))
+{
+    int border = ((m_wnd->GetWindowStyle() & wxRESIZE_BORDER) &&
+                  !m_wnd->IsMaximized()) ?
+                      RESIZEABLE_FRAME_BORDER_THICKNESS :
+                      FRAME_BORDER_THICKNESS;
+    wxPoint pt = m_wnd->GetClientAreaOrigin();
+    pt.x = -pt.x + border;
+    pt.y = -pt.y + border + FRAME_TITLEBAR_HEIGHT;
+
+    wxAcceleratorTable table = *m_wnd->GetAcceleratorTable();
+    m_wnd->SetAcceleratorTable(wxNullAcceleratorTable);
+    m_inputHnd->PopupSystemMenu(m_wnd, pt);
+    m_wnd->SetAcceleratorTable(table);
+}
+
+void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent &WXUNUSED(event))
+{
+    m_wnd->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
+                         wxTOPLEVEL_BUTTON_CLOSE);
+}
+
+void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent &event)
+{
+    m_wnd = NULL;
+    event.Skip();
+}
+
+
+wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler *handler)
+        : wxStdFrameInputHandler(handler)
+{
+    m_menuHandler = new wxWin32SystemMenuEvtHandler(this);
+}
+
+wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
+{
+    if ( m_menuHandler )
+    {
+        m_menuHandler->Detach();
+        delete m_menuHandler;
+    }
+}
+
 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer *consumer,
                                            const wxMouseEvent& event)
 {
 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer *consumer,
                                            const wxMouseEvent& event)
 {
-    if ( event.LeftDClick() )
+    if ( event.LeftDClick() || event.LeftDown() || event.RightDown() )
     {
     {
-        wxTopLevelWindow *tlw = 
+        wxTopLevelWindow *tlw =
             wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
 
         long hit = tlw->HitTest(event.GetPosition());
 
             wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
 
         long hit = tlw->HitTest(event.GetPosition());
 
-        if ( hit == wxHT_TOPLEVEL_TITLEBAR )
+        if ( event.LeftDClick() && hit == wxHT_TOPLEVEL_TITLEBAR )
         {
         {
-            tlw->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK, 
-                               tlw->IsMaximized() ? 
-                                   wxTOPLEVEL_BUTTON_RESTORE : 
-                                   wxTOPLEVEL_BUTTON_MAXIMIZE);
+            tlw->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
+                               tlw->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
+                                                  : wxTOPLEVEL_BUTTON_MAXIMIZE);
             return TRUE;
         }
             return TRUE;
         }
+        else if ( tlw->GetWindowStyle() & wxSYSTEM_MENU )
+        {
+            if ( (event.LeftDown() && hit == wxHT_TOPLEVEL_ICON) ||
+                 (event.RightDown() && 
+                      (hit == wxHT_TOPLEVEL_TITLEBAR || 
+                       hit == wxHT_TOPLEVEL_ICON)) )
+            {
+                PopupSystemMenu(tlw, event.GetPosition());
+                return TRUE;
+            }
+        }
     }
 
     return wxStdFrameInputHandler::HandleMouse(consumer, event);
 }
 
     }
 
     return wxStdFrameInputHandler::HandleMouse(consumer, event);
 }
 
+void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow *window, 
+                                               const wxPoint& pos) const
+{
+    wxMenu *menu = new wxMenu;
+
+    if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
+        menu->Append(wxID_RESTORE_FRAME , _("&Restore"));
+    menu->Append(wxID_MOVE_FRAME , _("&Move"));
+    if ( window->GetWindowStyle() & wxRESIZE_BORDER )
+        menu->Append(wxID_RESIZE_FRAME , _("&Size"));
+    if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME) )
+        menu->Append(wxID_ICONIZE_FRAME , _("Mi&nimize"));
+    if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
+        menu->Append(wxID_MAXIMIZE_FRAME , _("Ma&ximize"));
+    menu->AppendSeparator();
+    menu->Append(wxID_CLOSE_FRAME, _("Close\tAlt-F4"));
+    
+    if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
+    {
+        if ( window->IsMaximized() )
+        {
+            menu->Enable(wxID_MAXIMIZE_FRAME, FALSE);
+            menu->Enable(wxID_MOVE_FRAME, FALSE);
+            if ( window->GetWindowStyle() & wxRESIZE_BORDER )
+                menu->Enable(wxID_RESIZE_FRAME, FALSE);
+        }
+        else
+            menu->Enable(wxID_RESTORE_FRAME, FALSE);
+    }
+
+    window->PopupMenu(menu, pos);
+    delete menu;
+}
+
+bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer *consumer, 
+                                                bool activated)
+{
+    if ( consumer->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU )
+    {
+        // always detach if active frame changed:
+        m_menuHandler->Detach();
+
+        if ( activated )
+        {
+            m_menuHandler->Attach(consumer);
+        }
+    }
+
+    return wxStdFrameInputHandler::HandleActivation(consumer, activated);
+}