]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/themes/win32.cpp
don't complain if file doesn't exist in DeleteFile(); do return false if it exists...
[wxWidgets.git] / src / univ / themes / win32.cpp
index 8352e502e8c0974d57bb51a6280a4e0a56e52b34..6edcca086271cf5188ed96c7e98472cfec37db16 100644 (file)
@@ -5,7 +5,7 @@
 // Created:     06.08.00
 // RCS-ID:      $Id$
 // Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 // ===========================================================================
 #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/toplevel.h"
 #include "wx/univ/renderer.h"
 #include "wx/univ/inphand.h"
 #include "wx/univ/colschem.h"
@@ -79,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 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,
@@ -147,7 +152,8 @@ public:
     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,
@@ -233,7 +239,8 @@ public:
                                    const wxString& label,
                                    const wxBitmap& bitmap,
                                    const wxRect& rect,
-                                   int flags);
+                                   int flags = 0,
+                                   long style = 0);
     virtual void DrawTextLine(wxDC& dc,
                               const wxString& text,
                               const wxRect& rect,
@@ -251,21 +258,25 @@ public:
 
     virtual void DrawSliderShaft(wxDC& dc,
                                  const wxRect& rect,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int flags = 0,
+                                 long style = 0,
                                  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,
-                                 const wxSize& sizeThumb,
+                                 int lenThumb,
                                  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,
@@ -321,8 +332,6 @@ public:
     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,
@@ -355,7 +364,7 @@ public:
     virtual wxSize GetToolBarButtonSize(wxCoord *separator) const
         { if ( separator ) *separator = 5; return wxSize(16, 15); }
     virtual wxSize GetToolBarMargin() const
-        { return wxSize(6, 6); }
+        { return wxSize(4, 4); }
 
     virtual wxRect GetTextTotalArea(const wxTextCtrl *text,
                                     const wxRect& rect) const;
@@ -366,11 +375,14 @@ public:
     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,
-                                      wxOrientation orient) const;
+                                      int lenThumb,
+                                      wxOrientation orient,
+                                      long style = 0) const;
     virtual wxSize GetSliderThumbSize(const wxRect& rect,
+                                      int lenThumb,
                                       wxOrientation orient) const;
     virtual wxSize GetProgressBarStep() const { return wxSize(16, 32); }
 
@@ -405,7 +417,8 @@ protected:
     // 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
@@ -536,7 +549,8 @@ public:
 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
     }
@@ -597,14 +611,24 @@ private:
     bool m_isOnGrip;
 };
 
+class wxWin32SystemMenuEvtHandler;
+
 class wxWin32FrameInputHandler : public wxStdFrameInputHandler
 {
 public:
-    wxWin32FrameInputHandler(wxInputHandler *handler)
-        : wxStdFrameInputHandler(handler) { }
+    wxWin32FrameInputHandler(wxInputHandler *handler);
+    ~wxWin32FrameInputHandler();
 
     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;
 };
 
 // ----------------------------------------------------------------------------
@@ -618,11 +642,23 @@ public:
     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
 // ----------------------------------------------------------------------------
 
-WX_DEFINE_ARRAY(wxInputHandler *, wxArrayHandlers);
+WX_DEFINE_ARRAY_PTR(wxInputHandler *, wxArrayHandlers);
 
 class wxWin32Theme : public wxTheme
 {
@@ -631,6 +667,7 @@ public:
     virtual ~wxWin32Theme();
 
     virtual wxRenderer *GetRenderer();
+    virtual wxArtProvider *GetArtProvider();
     virtual wxInputHandler *GetInputHandler(const wxString& control);
     virtual wxColourScheme *GetColourScheme();
 
@@ -639,6 +676,8 @@ private:
     wxInputHandler *GetDefaultInputHandler();
 
     wxWin32Renderer *m_renderer;
+    
+    wxWin32ArtProvider *m_artProvider;
 
     // the names of the already created handlers and the handlers themselves
     // (these arrays are synchronized)
@@ -1150,6 +1189,7 @@ wxWin32Theme::wxWin32Theme()
     m_scheme = NULL;
     m_renderer = NULL;
     m_handlerDefault = NULL;
+    m_artProvider = NULL;
 }
 
 wxWin32Theme::~wxWin32Theme()
@@ -1165,6 +1205,7 @@ wxWin32Theme::~wxWin32Theme()
 
     delete m_renderer;
     delete m_scheme;
+    wxArtProvider::RemoveProvider(m_artProvider);
 }
 
 wxRenderer *wxWin32Theme::GetRenderer()
@@ -1177,6 +1218,16 @@ wxRenderer *wxWin32Theme::GetRenderer()
     return m_renderer;
 }
 
+wxArtProvider *wxWin32Theme::GetArtProvider()
+{
+    if ( !m_artProvider )
+    {
+        m_artProvider = new wxWin32ArtProvider;
+    }
+
+    return m_artProvider;
+}
+
 wxInputHandler *wxWin32Theme::GetDefaultInputHandler()
 {
     if ( !m_handlerDefault )
@@ -1328,8 +1379,12 @@ wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col) const
 
         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));
@@ -1695,8 +1750,7 @@ void wxWin32Renderer::DrawHalfRect(wxDC& dc, wxRect *rect, const wxPen& pen)
                 rect->GetRight(), rect->GetBottom());
 
     // adjust the rect
-    rect->width--;
-    rect->height--;
+    rect->Inflate(-1);
 }
 
 void wxWin32Renderer::DrawShadedRect(wxDC& dc, wxRect *rect,
@@ -1826,8 +1880,12 @@ wxRect wxWin32Renderer::GetBorderDimensions(wxBorder border) const
             break;
 
         default:
+        { 
+            // char *crash = NULL;
+            // *crash = 0;
             wxFAIL_MSG(_T("unknown border type"));
             // fall through
+        }
 
         case wxBORDER_DEFAULT:
         case wxBORDER_NONE:
@@ -2351,9 +2409,10 @@ void wxWin32Renderer::DrawToolBarButton(wxDC& dc,
                                         const wxString& label,
                                         const wxBitmap& bitmap,
                                         const wxRect& rectOrig,
-                                        int flags)
+                                        int flags,
+                                        long style)
 {
-    if ( !label.empty() || bitmap.Ok() )
+    if (style == wxTOOL_STYLE_BUTTON)
     {
         wxRect rect = rectOrig;
         rect.Deflate(BORDER_THICKNESS);
@@ -2369,10 +2428,15 @@ void wxWin32Renderer::DrawToolBarButton(wxDC& dc,
 
         dc.DrawLabel(label, bitmap, rect, wxALIGN_CENTRE);
     }
-    else // a separator
+    else if (style == wxTOOL_STYLE_SEPARATOR)
     {
-        // TODO
+        // 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
 }
 
 // ----------------------------------------------------------------------------
@@ -2390,7 +2454,9 @@ void wxWin32Renderer::DrawTextLine(wxDC& dc,
     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
 }
@@ -2521,53 +2587,82 @@ void wxWin32Renderer::DrawTab(wxDC& dc,
 // slider
 // ----------------------------------------------------------------------------
 
-wxSize wxWin32Renderer::GetSliderThumbSize(const wxRect& rect,
-                                           wxOrientation orient) const
+wxSize
+wxWin32Renderer::GetSliderThumbSize(const wxRect& WXUNUSED(rect),
+                                    int lenThumb,
+                                    wxOrientation orient) const
 {
     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,
-                                           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;
 
-    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.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;
@@ -2575,19 +2670,37 @@ wxRect wxWin32Renderer::GetSliderShaftRect(const wxRect& rectOrig,
 
 void wxWin32Renderer::DrawSliderShaft(wxDC& dc,
                                       const wxRect& rectOrig,
+                                      int lenThumb,
                                       wxOrientation orient,
                                       int flags,
+                                      long style,
                                       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);
     }
 
-    wxRect rect = GetSliderShaftRect(rectOrig, orient);
+    wxRect rect = GetSliderShaftRect(rectOrig, lenThumb, orient, style);
 
-    if ( rectShaft )
-        *rectShaft = rect;
+    if (rectShaft) *rectShaft = rect;
 
     DrawSunkenBorder(dc, &rect);
 }
@@ -2595,26 +2708,31 @@ void wxWin32Renderer::DrawSliderShaft(wxDC& dc,
 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.
@@ -2622,51 +2740,81 @@ void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
 
     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
     {
-        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);
-    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;
-        if ( transpose )
-            rectInt.SetRight(y3);
+        if ( transpose ) 
+        {
+            rectInt.SetLeft(y3);
+            rectInt.SetRight(y4);
+        }
         else
-            rectInt.SetBottom(y3);
+        {
+            rectInt.SetTop(y3);
+            rectInt.SetBottom(y4);
+        }
         rectInt.Deflate(2);
 
 #if !defined(__WXMGL__)
@@ -2708,70 +2856,80 @@ void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
 
 void wxWin32Renderer::DrawSliderTicks(wxDC& dc,
                                       const wxRect& rect,
-                                      const wxSize& sizeThumb,
+                                      int lenThumb,
                                       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;
-    for ( int n = 0; n < range; n += step )
-    {
+    for ( int n = 0; n < range; n += step ) {
         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
-    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);
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -2968,7 +3126,7 @@ wxMenuGeometryInfo *wxWin32Renderer::GetMenuGeometry(wxWindow *win,
             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() )
     {
@@ -3117,7 +3275,7 @@ void wxWin32Renderer::DrawStatusField(wxDC& dc,
 // ----------------------------------------------------------------------------
 
 void wxWin32Renderer::GetComboBitmaps(wxBitmap *bmpNormal,
-                                      wxBitmap *bmpFocus,
+                                      wxBitmap * WXUNUSED(bmpFocus),
                                       wxBitmap *bmpPressed,
                                       wxBitmap *bmpDisabled)
 {
@@ -3157,7 +3315,8 @@ void wxWin32Renderer::GetComboBitmaps(wxBitmap *bmpNormal,
 
 void wxWin32Renderer::DoDrawBackground(wxDC& dc,
                                        const wxColour& col,
-                                       const wxRect& rect)
+                                       const wxRect& rect,
+                                       wxWindow * WXUNUSED(window))
 {
     wxBrush brush(col, wxSOLID);
     dc.SetBrush(brush);
@@ -3168,11 +3327,12 @@ void wxWin32Renderer::DoDrawBackground(wxDC& dc,
 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);
-    DoDrawBackground(dc, colBg, rect);
+    DoDrawBackground(dc, colBg, rect, window );
 }
 
 // ----------------------------------------------------------------------------
@@ -3244,9 +3404,9 @@ void wxWin32Renderer::DrawArrowButton(wxDC& dc,
 }
 
 void wxWin32Renderer::DrawScrollbarThumb(wxDC& dc,
-                                         wxOrientation orient,
+                                         wxOrientation WXUNUSED(orient),
                                          const wxRect& rect,
-                                         int flags)
+                                         int WXUNUSED(flags))
 {
     // we don't use the flags, the thumb never changes appearance
     wxRect rectThumb = rect;
@@ -3255,7 +3415,7 @@ void wxWin32Renderer::DrawScrollbarThumb(wxDC& dc,
 }
 
 void wxWin32Renderer::DrawScrollbarShaft(wxDC& dc,
-                                         wxOrientation orient,
+                                         wxOrientation WXUNUSED(orient),
                                          const wxRect& rectBar,
                                          int flags)
 {
@@ -3839,26 +3999,19 @@ static char *warning_xpm[]={
 "....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;
 }
 
 
@@ -3871,8 +4024,9 @@ static inline int GetTextBorderWidth()
     return 1;
 }
 
-wxRect wxWin32Renderer::GetTextTotalArea(const wxTextCtrl *text,
-                                         const wxRect& rect) const
+wxRect
+wxWin32Renderer::GetTextTotalArea(const wxTextCtrl * WXUNUSED(text),
+                                  const wxRect& rect) const
 {
     wxRect rectTotal = rect;
 
@@ -3885,9 +4039,10 @@ wxRect wxWin32Renderer::GetTextTotalArea(const wxTextCtrl *text,
     return rectTotal;
 }
 
-wxRect wxWin32Renderer::GetTextClientArea(const wxTextCtrl *text,
-                                          const wxRect& rect,
-                                          wxCoord *extraSpaceBeyond) const
+wxRect
+wxWin32Renderer::GetTextClientArea(const wxTextCtrl * WXUNUSED(text),
+                                   const wxRect& rect,
+                                   wxCoord *extraSpaceBeyond) const
 {
     wxRect rectText = rect;
 
@@ -3940,6 +4095,18 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window)
                 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;
     }
@@ -3964,9 +4131,9 @@ wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer *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;
 }
@@ -3979,7 +4146,8 @@ bool wxWin32InputHandler::HandleMouse(wxInputConsumer *control,
     {
         wxWindow *win = control->GetInputWindow();
 
-        if ( wxWindow::FindFocus() != control->GetInputWindow() )
+        if (( wxWindow::FindFocus() != control->GetInputWindow() ) &&
+            ( win->AcceptsFocus() ) )
         {
             win->SetFocus();
 
@@ -4105,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 0
+        // Always let thumb jump back if we leave the scrollbar
         if ( event.Moving() )
         {
             ht = m_renderer->HitTestScrollbar(scrollbar, event.GetPosition());
@@ -4113,6 +4283,21 @@ bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer *control,
         {
             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
@@ -4331,25 +4516,188 @@ bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
 // 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)
 {
-    if ( event.LeftDClick() )
+    if ( event.LeftDClick() || event.LeftDown() || event.RightDown() )
     {
         wxTopLevelWindow *tlw =
             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);
             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);
 }
 
+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);
+}