1 // Name:        univ/themes/win32.cpp 
   2 // Purpose:     wxUniversal theme implementing Win32-like LNF 
   3 // Author:      Vadim Zeitlin 
   7 // Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com) 
   8 // Licence:     wxWindows license 
   9 /////////////////////////////////////////////////////////////////////////////// 
  11 // =========================================================================== 
  13 // =========================================================================== 
  15 // --------------------------------------------------------------------------- 
  17 // --------------------------------------------------------------------------- 
  19 // For compilers that support precompilation, includes "wx.h". 
  20 #include "wx/wxprec.h" 
  30     #include "wx/window.h" 
  32     #include "wx/dcmemory.h" 
  34     #include "wx/button.h" 
  35     #include "wx/listbox.h" 
  36     #include "wx/checklst.h" 
  37     #include "wx/combobox.h" 
  38     #include "wx/scrolbar.h" 
  39     #include "wx/slider.h" 
  40     #include "wx/textctrl.h" 
  43         // for COLOR_* constants 
  44         #include "wx/msw/private.h" 
  48 #include "wx/notebook.h" 
  49 #include "wx/spinbutt.h" 
  50 #include "wx/settings.h" 
  53 #include "wx/univ/scrtimer.h" 
  54 #include "wx/toplevel.h" 
  55 #include "wx/univ/renderer.h" 
  56 #include "wx/univ/inphand.h" 
  57 #include "wx/univ/colschem.h" 
  58 #include "wx/univ/theme.h" 
  60 // ---------------------------------------------------------------------------- 
  62 // ---------------------------------------------------------------------------- 
  64 static const int BORDER_THICKNESS 
= 2; 
  66 // the offset between the label and focus rect around it 
  67 static const int FOCUS_RECT_OFFSET_X 
= 1; 
  68 static const int FOCUS_RECT_OFFSET_Y 
= 1; 
  70 static const int FRAME_BORDER_THICKNESS            
= 3; 
  71 static const int RESIZEABLE_FRAME_BORDER_THICKNESS 
= 4; 
  72 static const int FRAME_TITLEBAR_HEIGHT             
= 18; 
  73 static const int FRAME_BUTTON_WIDTH                
= 16; 
  74 static const int FRAME_BUTTON_HEIGHT               
= 14; 
  76 static const size_t NUM_STATUSBAR_GRIP_BANDS 
= 3; 
  77 static const size_t WIDTH_STATUSBAR_GRIP_BAND 
= 4; 
  78 static const size_t STATUSBAR_GRIP_SIZE 
= 
  79     WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
; 
  91     IndicatorState_Normal
, 
  92     IndicatorState_Pressed
, // this one is for check/radioboxes 
  93     IndicatorState_Selected 
= IndicatorState_Pressed
, // for menus 
  94     IndicatorState_Disabled
, 
  95     IndicatorState_SelectedDisabled
,    // only for the menus 
 101     IndicatorStatus_Checked
, 
 102     IndicatorStatus_Unchecked
, 
 106 // wxWin32Renderer: draw the GUI elements in Win32 style 
 107 // ---------------------------------------------------------------------------- 
 109 class wxWin32Renderer 
: public wxRenderer
 
 113     enum wxArrowDirection
 
 128         Arrow_InversedDisabled
, 
 132     enum wxFrameButtonType
 
 135         FrameButton_Minimize
, 
 136         FrameButton_Maximize
, 
 143     wxWin32Renderer(const wxColourScheme 
*scheme
); 
 145     // implement the base class pure virtuals 
 146     virtual void DrawBackground(wxDC
& dc
, 
 150     virtual void DrawLabel(wxDC
& dc
, 
 151                            const wxString
& label
, 
 154                            int alignment 
= wxALIGN_LEFT 
| wxALIGN_TOP
, 
 156                            wxRect 
*rectBounds 
= NULL
); 
 157     virtual void DrawButtonLabel(wxDC
& dc
, 
 158                                  const wxString
& label
, 
 159                                  const wxBitmap
& image
, 
 162                                  int alignment 
= wxALIGN_LEFT 
| wxALIGN_TOP
, 
 164                                  wxRect 
*rectBounds 
= NULL
); 
 165     virtual void DrawBorder(wxDC
& dc
, 
 169                             wxRect 
*rectIn 
= (wxRect 
*)NULL
); 
 170     virtual void DrawHorizontalLine(wxDC
& dc
, 
 171                                     wxCoord y
, wxCoord x1
, wxCoord x2
); 
 172     virtual void DrawVerticalLine(wxDC
& dc
, 
 173                                   wxCoord x
, wxCoord y1
, wxCoord y2
); 
 174     virtual void DrawFrame(wxDC
& dc
, 
 175                            const wxString
& label
, 
 178                            int alignment 
= wxALIGN_LEFT
, 
 179                            int indexAccel 
= -1); 
 180     virtual void DrawTextBorder(wxDC
& dc
, 
 184                                 wxRect 
*rectIn 
= (wxRect 
*)NULL
); 
 185     virtual void DrawButtonBorder(wxDC
& dc
, 
 188                                   wxRect 
*rectIn 
= (wxRect 
*)NULL
); 
 189     virtual void DrawArrow(wxDC
& dc
, 
 193     virtual void DrawScrollbarArrow(wxDC
& dc
, 
 197         { DrawArrow(dc
, dir
, rect
, flags
); } 
 198     virtual void DrawScrollbarThumb(wxDC
& dc
, 
 199                                     wxOrientation orient
, 
 202     virtual void DrawScrollbarShaft(wxDC
& dc
, 
 203                                     wxOrientation orient
, 
 206     virtual void DrawScrollCorner(wxDC
& dc
, 
 208     virtual void DrawItem(wxDC
& dc
, 
 209                           const wxString
& label
, 
 212     virtual void DrawCheckItem(wxDC
& dc
, 
 213                                const wxString
& label
, 
 214                                const wxBitmap
& bitmap
, 
 217     virtual void DrawCheckButton(wxDC
& dc
, 
 218                                  const wxString
& label
, 
 219                                  const wxBitmap
& bitmap
, 
 222                                  wxAlignment align 
= wxALIGN_LEFT
, 
 223                                  int indexAccel 
= -1); 
 224     virtual void DrawRadioButton(wxDC
& dc
, 
 225                                  const wxString
& label
, 
 226                                  const wxBitmap
& bitmap
, 
 229                                  wxAlignment align 
= wxALIGN_LEFT
, 
 230                                  int indexAccel 
= -1); 
 231     virtual void DrawTextLine(wxDC
& dc
, 
 232                               const wxString
& text
, 
 237     virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
); 
 238     virtual void DrawTab(wxDC
& dc
, 
 241                          const wxString
& label
, 
 242                          const wxBitmap
& bitmap 
= wxNullBitmap
, 
 244                          int indexAccel 
= -1); 
 246     virtual void DrawSliderShaft(wxDC
& dc
, 
 248                                  wxOrientation orient
, 
 250                                  wxRect 
*rectShaft 
= NULL
); 
 251     virtual void DrawSliderThumb(wxDC
& dc
, 
 253                                  wxOrientation orient
, 
 255     virtual void DrawSliderTicks(wxDC
& dc
, 
 257                                  const wxSize
& sizeThumb
, 
 258                                  wxOrientation orient
, 
 264     virtual void DrawMenuBarItem(wxDC
& dc
, 
 266                                  const wxString
& label
, 
 268                                  int indexAccel 
= -1); 
 269     virtual void DrawMenuItem(wxDC
& dc
, 
 271                               const wxMenuGeometryInfo
& geometryInfo
, 
 272                               const wxString
& label
, 
 273                               const wxString
& accel
, 
 274                               const wxBitmap
& bitmap 
= wxNullBitmap
, 
 276                               int indexAccel 
= -1); 
 277     virtual void DrawMenuSeparator(wxDC
& dc
, 
 279                                    const wxMenuGeometryInfo
& geomInfo
); 
 281     virtual void DrawStatusField(wxDC
& dc
, 
 283                                  const wxString
& label
, 
 287     virtual void DrawFrameTitleBar(wxDC
& dc
, 
 289                                    const wxString
& title
, 
 292                                    int specialButton 
= 0, 
 293                                    int specialButtonFlags 
= 0); 
 294     virtual void DrawFrameBorder(wxDC
& dc
, 
 297     virtual void DrawFrameBackground(wxDC
& dc
, 
 300     virtual void DrawFrameTitle(wxDC
& dc
, 
 302                                 const wxString
& title
, 
 304     virtual void DrawFrameIcon(wxDC
& dc
, 
 308     virtual void DrawFrameButton(wxDC
& dc
, 
 309                                  wxCoord x
, wxCoord y
, 
 312     virtual wxRect 
GetFrameClientArea(const wxRect
& rect
, int flags
) const; 
 313     virtual wxSize 
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const; 
 314     virtual wxSize 
GetFrameIconSize() const; 
 315     virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const; 
 317     virtual wxIcon 
GetStdIcon(int which
) const; 
 319     virtual void GetComboBitmaps(wxBitmap 
*bmpNormal
, 
 321                                  wxBitmap 
*bmpPressed
, 
 322                                  wxBitmap 
*bmpDisabled
); 
 324     virtual void AdjustSize(wxSize 
*size
, const wxWindow 
*window
); 
 325     virtual wxRect 
GetBorderDimensions(wxBorder border
) const; 
 326     virtual bool AreScrollbarsInsideBorder() const; 
 328     virtual wxSize 
GetScrollbarArrowSize() const 
 329         { return m_sizeScrollbarArrow
; } 
 330     virtual wxRect 
GetScrollbarRect(const wxScrollBar 
*scrollbar
, 
 331                                     wxScrollBar::Element elem
, 
 332                                     int thumbPos 
= -1) const; 
 333     virtual wxCoord 
GetScrollbarSize(const wxScrollBar 
*scrollbar
); 
 334     virtual wxHitTest 
HitTestScrollbar(const wxScrollBar 
*scrollbar
, 
 335                                        const wxPoint
& pt
) const; 
 336     virtual wxCoord 
ScrollbarToPixel(const wxScrollBar 
*scrollbar
, 
 338     virtual int PixelToScrollbar(const wxScrollBar 
*scrollbar
, wxCoord coord
); 
 339     virtual wxCoord 
GetListboxItemHeight(wxCoord fontHeight
) 
 340         { return fontHeight 
+ 2; } 
 341     virtual wxSize 
GetCheckBitmapSize() const 
 342         { return wxSize(13, 13); } 
 343     virtual wxSize 
GetRadioBitmapSize() const 
 344         { return wxSize(12, 12); } 
 345     virtual wxCoord 
GetCheckItemMargin() const 
 348     virtual wxRect 
GetTextTotalArea(const wxTextCtrl 
*text
, 
 350     virtual wxRect 
GetTextClientArea(const wxTextCtrl 
*text
, 
 352                                      wxCoord 
*extraSpaceBeyond
); 
 354     virtual wxSize 
GetTabIndent() const { return wxSize(2, 2); } 
 355     virtual wxSize 
GetTabPadding() const { return wxSize(6, 5); } 
 357     virtual wxCoord 
GetSliderDim() const { return 20; } 
 358     virtual wxCoord 
GetSliderTickLen() const { return 4; } 
 359     virtual wxRect 
GetSliderShaftRect(const wxRect
& rect
, 
 360                                       wxOrientation orient
) const; 
 361     virtual wxSize 
GetSliderThumbSize(const wxRect
& rect
, 
 362                                       wxOrientation orient
) const; 
 363     virtual wxSize 
GetProgressBarStep() const { return wxSize(16, 32); } 
 365     virtual wxSize 
GetMenuBarItemSize(const wxSize
& sizeText
) const; 
 366     virtual wxMenuGeometryInfo 
*GetMenuGeometry(wxWindow 
*win
, 
 367                                                 const wxMenu
& menu
) const; 
 369     virtual wxSize 
GetStatusBarBorders(wxCoord 
*borderBetweenFields
) const; 
 372     // helper of DrawLabel() and DrawCheckOrRadioButton() 
 373     void DoDrawLabel(wxDC
& dc
, 
 374                      const wxString
& label
, 
 377                      int alignment 
= wxALIGN_LEFT 
| wxALIGN_TOP
, 
 379                      wxRect 
*rectBounds 
= NULL
, 
 380                      const wxPoint
& focusOffset
 
 381                         = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
)); 
 383     // common part of DrawLabel() and DrawItem() 
 384     void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
); 
 386     // DrawLabel() and DrawButtonLabel() helper 
 387     void DrawLabelShadow(wxDC
& dc
, 
 388                          const wxString
& label
, 
 393     // DrawButtonBorder() helper 
 394     void DoDrawBackground(wxDC
& dc
, 
 398     // DrawBorder() helpers: all of them shift and clip the DC after drawing 
 401     // just draw a rectangle with the given pen 
 402     void DrawRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
); 
 404     // draw the lower left part of rectangle 
 405     void DrawHalfRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
); 
 407     // draw the rectange using the first brush for the left and top sides and 
 408     // the second one for the bottom and right ones 
 409     void DrawShadedRect(wxDC
& dc
, wxRect 
*rect
, 
 410                         const wxPen
& pen1
, const wxPen
& pen2
); 
 412     // draw the normal 3D border 
 413     void DrawRaisedBorder(wxDC
& dc
, wxRect 
*rect
); 
 415     // draw the sunken 3D border 
 416     void DrawSunkenBorder(wxDC
& dc
, wxRect 
*rect
); 
 418     // draw the border used for scrollbar arrows 
 419     void DrawArrowBorder(wxDC
& dc
, wxRect 
*rect
, bool isPressed 
= FALSE
); 
 421     // public DrawArrow()s helper 
 422     void DrawArrow(wxDC
& dc
, const wxRect
& rect
, 
 423                    wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
); 
 425     // DrawArrowButton is used by DrawScrollbar and DrawComboButton 
 426     void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
, 
 427                          wxArrowDirection arrowDir
, 
 428                          wxArrowStyle arrowStyle
); 
 430     // DrawCheckButton/DrawRadioButton helper 
 431     void DrawCheckOrRadioButton(wxDC
& dc
, 
 432                                 const wxString
& label
, 
 433                                 const wxBitmap
& bitmap
, 
 438                                 wxCoord focusOffsetY
); 
 440     // draw a normal or transposed line (useful for using the same code fo both 
 441     // horizontal and vertical widgets) 
 442     void DrawLine(wxDC
& dc
, 
 443                   wxCoord x1
, wxCoord y1
, 
 444                   wxCoord x2
, wxCoord y2
, 
 445                   bool transpose 
= FALSE
) 
 448             dc
.DrawLine(y1
, x1
, y2
, x2
); 
 450             dc
.DrawLine(x1
, y1
, x2
, y2
); 
 453     // get the standard check/radio button bitmap 
 454     wxBitmap 
GetIndicator(IndicatorType indType
, int flags
); 
 455     wxBitmap 
GetCheckBitmap(int flags
) 
 456         { return GetIndicator(IndicatorType_Check
, flags
); } 
 457     wxBitmap 
GetRadioBitmap(int flags
) 
 458         { return GetIndicator(IndicatorType_Radio
, flags
); } 
 461     const wxColourScheme 
*m_scheme
; 
 463     // the sizing parameters (TODO make them changeable) 
 464     wxSize m_sizeScrollbarArrow
; 
 466     // GDI objects we use for drawing 
 467     wxColour m_colDarkGrey
, 
 475     wxFont m_titlebarFont
; 
 478     wxBitmap m_bmpFrameButtons
[FrameButton_Max
]; 
 480     // first row is for the normal state, second - for the disabled 
 481     wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
]; 
 484 // ---------------------------------------------------------------------------- 
 485 // wxWin32InputHandler and derived classes: process the keyboard and mouse 
 486 // messages according to Windows standards 
 487 // ---------------------------------------------------------------------------- 
 489 class wxWin32InputHandler 
: public wxInputHandler
 
 492     wxWin32InputHandler(wxWin32Renderer 
*renderer
); 
 494     virtual bool HandleKey(wxInputConsumer 
*control
, 
 495                            const wxKeyEvent
& event
, 
 497     virtual bool HandleMouse(wxInputConsumer 
*control
, 
 498                              const wxMouseEvent
& event
); 
 501     wxWin32Renderer 
*m_renderer
; 
 504 class wxWin32ScrollBarInputHandler 
: public wxStdScrollBarInputHandler
 
 507     wxWin32ScrollBarInputHandler(wxWin32Renderer 
*renderer
, 
 508                                  wxInputHandler 
*handler
); 
 510     virtual bool HandleMouse(wxInputConsumer 
*control
, const wxMouseEvent
& event
); 
 511     virtual bool HandleMouseMove(wxInputConsumer 
*control
, const wxMouseEvent
& event
); 
 513     virtual bool OnScrollTimer(wxScrollBar 
*scrollbar
, 
 514                                const wxControlAction
& action
); 
 517     virtual bool IsAllowedButton(int button
) { return button 
== 1; } 
 519     virtual void Highlight(wxScrollBar 
*scrollbar
, bool doIt
) 
 521         // we don't highlight anything 
 524     // the first and last event which caused the thumb to move 
 525     wxMouseEvent m_eventStartDrag
, 
 528     // have we paused the scrolling because the mouse moved? 
 531     // we remember the interval of the timer to be able to restart it 
 535 class wxWin32CheckboxInputHandler 
: public wxStdCheckboxInputHandler
 
 538     wxWin32CheckboxInputHandler(wxInputHandler 
*handler
) 
 539         : wxStdCheckboxInputHandler(handler
) { } 
 541     virtual bool HandleKey(wxInputConsumer 
*control
, 
 542                            const wxKeyEvent
& event
, 
 546 class wxWin32TextCtrlInputHandler 
: public wxStdTextCtrlInputHandler
 
 549     wxWin32TextCtrlInputHandler(wxInputHandler 
*handler
) 
 550         : wxStdTextCtrlInputHandler(handler
) { } 
 552     virtual bool HandleKey(wxInputConsumer 
*control
, 
 553                            const wxKeyEvent
& event
, 
 557 class wxWin32StatusBarInputHandler 
: public wxStdInputHandler
 
 560     wxWin32StatusBarInputHandler(wxInputHandler 
*handler
); 
 562     virtual bool HandleMouse(wxInputConsumer 
*consumer
, 
 563                              const wxMouseEvent
& event
); 
 565     virtual bool HandleMouseMove(wxInputConsumer 
*consumer
, 
 566                                  const wxMouseEvent
& event
); 
 569     // is the given point over the statusbar grip? 
 570     bool IsOnGrip(wxWindow 
*statbar
, const wxPoint
& pt
) const; 
 573     // the cursor we had replaced with the resize one 
 574     wxCursor m_cursorOld
; 
 576     // was the mouse over the grip last time we checked? 
 580 // ---------------------------------------------------------------------------- 
 581 // wxWin32ColourScheme: uses (default) Win32 colours 
 582 // ---------------------------------------------------------------------------- 
 584 class wxWin32ColourScheme 
: public wxColourScheme
 
 587     virtual wxColour 
Get(StdColour col
) const; 
 588     virtual wxColour 
GetBackground(wxWindow 
*win
) const; 
 591 // ---------------------------------------------------------------------------- 
 593 // ---------------------------------------------------------------------------- 
 595 WX_DEFINE_ARRAY(wxInputHandler 
*, wxArrayHandlers
); 
 597 class wxWin32Theme 
: public wxTheme
 
 601     virtual ~wxWin32Theme(); 
 603     virtual wxRenderer 
*GetRenderer(); 
 604     virtual wxInputHandler 
*GetInputHandler(const wxString
& control
); 
 605     virtual wxColourScheme 
*GetColourScheme(); 
 608     // get the default input handler 
 609     wxInputHandler 
*GetDefaultInputHandler(); 
 611     wxWin32Renderer 
*m_renderer
; 
 613     // the names of the already created handlers and the handlers themselves 
 614     // (these arrays are synchronized) 
 615     wxSortedArrayString m_handlerNames
; 
 616     wxArrayHandlers m_handlers
; 
 618     wxWin32InputHandler 
*m_handlerDefault
; 
 620     wxWin32ColourScheme 
*m_scheme
; 
 622     WX_DECLARE_THEME(win32
) 
 625 // ---------------------------------------------------------------------------- 
 627 // ---------------------------------------------------------------------------- 
 629 // frame buttons bitmaps 
 631 static const char *frame_button_close_xpm
[] = { 
 646 static const char *frame_button_help_xpm
[] = { 
 661 static const char *frame_button_maximize_xpm
[] = { 
 676 static const char *frame_button_minimize_xpm
[] = { 
 691 static const char *frame_button_restore_xpm
[] = { 
 708 static const char *checked_menu_xpm
[] = { 
 709 /* columns rows colors chars-per-pixel */ 
 725 static const char *selected_checked_menu_xpm
[] = { 
 726 /* columns rows colors chars-per-pixel */ 
 742 static const char *disabled_checked_menu_xpm
[] = { 
 743 /* columns rows colors chars-per-pixel */ 
 760 static const char *selected_disabled_checked_menu_xpm
[] = { 
 761 /* columns rows colors chars-per-pixel */ 
 777 // checkbox and radiobox bitmaps below 
 779 static const char *checked_xpm
[] = { 
 780 /* columns rows colors chars-per-pixel */ 
 803 static const char *pressed_checked_xpm
[] = { 
 804 /* columns rows colors chars-per-pixel */ 
 826 static const char *pressed_disabled_checked_xpm
[] = { 
 827 /* columns rows colors chars-per-pixel */ 
 849 static const char *checked_item_xpm
[] = { 
 850 /* columns rows colors chars-per-pixel */ 
 871 static const char *unchecked_xpm
[] = { 
 872 /* columns rows colors chars-per-pixel */ 
 895 static const char *pressed_unchecked_xpm
[] = { 
 896 /* columns rows colors chars-per-pixel */ 
 918 static const char *unchecked_item_xpm
[] = { 
 919 /* columns rows colors chars-per-pixel */ 
 939 static const char *checked_radio_xpm
[] = { 
 940 /* columns rows colors chars-per-pixel */ 
 963 static const char *pressed_checked_radio_xpm
[] = { 
 964 /* columns rows colors chars-per-pixel */ 
 987 static const char *pressed_disabled_checked_radio_xpm
[] = { 
 988 /* columns rows colors chars-per-pixel */ 
1011 static const char *unchecked_radio_xpm
[] = { 
1012 /* columns rows colors chars-per-pixel */ 
1035 static const char *pressed_unchecked_radio_xpm
[] = { 
1036 /* columns rows colors chars-per-pixel */ 
1059 static const char ** 
1060     bmpIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] = 
1065         { checked_xpm
, unchecked_xpm 
}, 
1068         { pressed_checked_xpm
, pressed_unchecked_xpm 
}, 
1071         { pressed_disabled_checked_xpm
, pressed_unchecked_xpm 
}, 
1077         { checked_radio_xpm
, unchecked_radio_xpm 
}, 
1080         { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm 
}, 
1083         { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm 
}, 
1089         { checked_menu_xpm
, NULL 
}, 
1092         { selected_checked_menu_xpm
, NULL 
}, 
1095         { disabled_checked_menu_xpm
, NULL 
}, 
1097         // disabled selected state 
1098         { selected_disabled_checked_menu_xpm
, NULL 
}, 
1102 // ============================================================================ 
1104 // ============================================================================ 
1106 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme")); 
1108 // ---------------------------------------------------------------------------- 
1110 // ---------------------------------------------------------------------------- 
1112 wxWin32Theme::wxWin32Theme() 
1116     m_handlerDefault 
= NULL
; 
1119 wxWin32Theme::~wxWin32Theme() 
1121     size_t count 
= m_handlers
.GetCount(); 
1122     for ( size_t n 
= 0; n 
< count
; n
++ ) 
1124         if ( m_handlers
[n
] != m_handlerDefault 
) 
1125             delete m_handlers
[n
]; 
1128     delete m_handlerDefault
; 
1134 wxRenderer 
*wxWin32Theme::GetRenderer() 
1138         m_renderer 
= new wxWin32Renderer(GetColourScheme()); 
1144 wxInputHandler 
*wxWin32Theme::GetDefaultInputHandler() 
1146     if ( !m_handlerDefault 
) 
1148         m_handlerDefault 
= new wxWin32InputHandler(m_renderer
); 
1151     return m_handlerDefault
; 
1154 wxInputHandler 
*wxWin32Theme::GetInputHandler(const wxString
& control
) 
1156     wxInputHandler 
*handler
; 
1157     int n 
= m_handlerNames
.Index(control
); 
1158     if ( n 
== wxNOT_FOUND 
) 
1160         // create a new handler 
1161         if ( control 
== wxINP_HANDLER_SCROLLBAR 
) 
1162             handler 
= new wxWin32ScrollBarInputHandler(m_renderer
, 
1163                                                        GetDefaultInputHandler()); 
1165         else if ( control 
== wxINP_HANDLER_BUTTON 
) 
1166             handler 
= new wxStdButtonInputHandler(GetDefaultInputHandler()); 
1167 #endif // wxUSE_BUTTON 
1169         else if ( control 
== wxINP_HANDLER_CHECKBOX 
) 
1170             handler 
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler()); 
1171 #endif // wxUSE_CHECKBOX 
1173         else if ( control 
== wxINP_HANDLER_COMBOBOX 
) 
1174             handler 
= new wxStdComboBoxInputHandler(GetDefaultInputHandler()); 
1175 #endif // wxUSE_COMBOBOX 
1177         else if ( control 
== wxINP_HANDLER_LISTBOX 
) 
1178             handler 
= new wxStdListboxInputHandler(GetDefaultInputHandler()); 
1179 #endif // wxUSE_LISTBOX 
1180 #if wxUSE_CHECKLISTBOX 
1181         else if ( control 
== wxINP_HANDLER_CHECKLISTBOX 
) 
1182             handler 
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler()); 
1183 #endif // wxUSE_CHECKLISTBOX 
1185         else if ( control 
== wxINP_HANDLER_TEXTCTRL 
) 
1186             handler 
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler()); 
1187 #endif // wxUSE_TEXTCTRL 
1189         else if ( control 
== wxINP_HANDLER_SLIDER 
) 
1190             handler 
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler()); 
1191 #endif // wxUSE_SLIDER 
1193         else if ( control 
== wxINP_HANDLER_SPINBTN 
) 
1194             handler 
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler()); 
1195 #endif // wxUSE_SPINBTN 
1197         else if ( control 
== wxINP_HANDLER_NOTEBOOK 
) 
1198             handler 
= new wxStdNotebookInputHandler(GetDefaultInputHandler()); 
1199 #endif // wxUSE_NOTEBOOK 
1201         else if ( control 
== wxINP_HANDLER_STATUSBAR 
) 
1202             handler 
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler()); 
1203 #endif // wxUSE_STATUSBAR 
1204         else if ( control 
== wxINP_HANDLER_TOPLEVEL 
) 
1205             handler 
= new wxStdFrameInputHandler(GetDefaultInputHandler()); 
1207             handler 
= GetDefaultInputHandler(); 
1209         n 
= m_handlerNames
.Add(control
); 
1210         m_handlers
.Insert(handler
, n
); 
1212     else // we already have it 
1214         handler 
= m_handlers
[n
]; 
1220 wxColourScheme 
*wxWin32Theme::GetColourScheme() 
1224         m_scheme 
= new wxWin32ColourScheme
; 
1229 // ============================================================================ 
1230 // wxWin32ColourScheme 
1231 // ============================================================================ 
1233 wxColour 
wxWin32ColourScheme::GetBackground(wxWindow 
*win
) const 
1236     if ( win
->UseBgCol() ) 
1238         // use the user specified colour 
1239         col 
= win
->GetBackgroundColour(); 
1242     if ( win
->IsContainerWindow() ) 
1244         wxTextCtrl 
*text 
= wxDynamicCast(win
, wxTextCtrl
); 
1247             if ( !text
->IsEnabled() ) // not IsEditable() 
1249             //else: execute code below 
1254             // doesn't depend on the state 
1260         int flags 
= win
->GetStateFlags(); 
1262         // the colour set by the user should be used for the normal state 
1263         // and for the states for which we don't have any specific colours 
1264         if ( !col
.Ok() || (flags 
!= 0) ) 
1266             if ( wxDynamicCast(win
, wxScrollBar
) ) 
1267                 col 
= Get(flags 
& wxCONTROL_PRESSED 
? SCROLLBAR_PRESSED
 
1277 wxColour 
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const 
1281         // use the system colours under Windows 
1282 #if defined(__WXMSW__) 
1283         case WINDOW
:            return wxColour(GetSysColor(COLOR_WINDOW
)); 
1285         case CONTROL_PRESSED
: 
1286         case CONTROL_CURRENT
: 
1287         case CONTROL
:           return wxColour(GetSysColor(COLOR_BTNFACE
)); 
1289         case CONTROL_TEXT
:      return wxColour(GetSysColor(COLOR_BTNTEXT
)); 
1291         case SCROLLBAR
:         return wxColour(GetSysColor(COLOR_SCROLLBAR
)); 
1292         case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
)); 
1294         case HIGHLIGHT
:         return wxColour(GetSysColor(COLOR_HIGHLIGHT
)); 
1295         case HIGHLIGHT_TEXT
:    return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
)); 
1297 #if defined(COLOR_3DDKSHADOW) 
1298         case SHADOW_DARK
:       return wxColour(GetSysColor(COLOR_3DDKSHADOW
)); 
1300         case SHADOW_DARK
:       return *wxBLACK
; 
1303         case CONTROL_TEXT_DISABLED
: 
1304         case SHADOW_HIGHLIGHT
:  return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
)); 
1306         case SHADOW_IN
:         return wxColour(GetSysColor(COLOR_BTNFACE
)); 
1308         case CONTROL_TEXT_DISABLED_SHADOW
: 
1309         case SHADOW_OUT
:        return wxColour(GetSysColor(COLOR_BTNSHADOW
)); 
1311         case TITLEBAR
:          return wxColour(GetSysColor(COLOR_INACTIVECAPTION
)); 
1312         case TITLEBAR_ACTIVE
:   return wxColour(GetSysColor(COLOR_ACTIVECAPTION
)); 
1313         case TITLEBAR_TEXT
:     return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
)); 
1314         case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
)); 
1316         case DESKTOP
:           return wxColour(0x808000); 
1318         // use the standard Windows colours elsewhere 
1319         case WINDOW
:            return *wxWHITE
; 
1321         case CONTROL_PRESSED
: 
1322         case CONTROL_CURRENT
: 
1323         case CONTROL
:           return wxColour(0xc0c0c0); 
1325         case CONTROL_TEXT
:      return *wxBLACK
; 
1327         case SCROLLBAR
:         return wxColour(0xe0e0e0); 
1328         case SCROLLBAR_PRESSED
: return *wxBLACK
; 
1330         case HIGHLIGHT
:         return wxColour(0x800000); 
1331         case HIGHLIGHT_TEXT
:    return wxColour(0xffffff); 
1333         case SHADOW_DARK
:       return *wxBLACK
; 
1335         case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0); 
1336         case SHADOW_HIGHLIGHT
:  return wxColour(0xffffff); 
1338         case SHADOW_IN
:         return wxColour(0xc0c0c0); 
1340         case CONTROL_TEXT_DISABLED_SHADOW
: 
1341         case SHADOW_OUT
:        return wxColour(0x7f7f7f); 
1343         case TITLEBAR
:          return wxColour(0xaeaaae); 
1344         case TITLEBAR_ACTIVE
:   return wxColour(0x820300); 
1345         case TITLEBAR_TEXT
:     return wxColour(0xc0c0c0); 
1346         case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
; 
1348         case DESKTOP
:           return wxColour(0x808000); 
1353             wxFAIL_MSG(_T("invalid standard colour")); 
1358 // ============================================================================ 
1360 // ============================================================================ 
1362 // ---------------------------------------------------------------------------- 
1364 // ---------------------------------------------------------------------------- 
1366 wxWin32Renderer::wxWin32Renderer(const wxColourScheme 
*scheme
) 
1370     m_sizeScrollbarArrow 
= wxSize(16, 16); 
1372     // init colours and pens 
1373     m_penBlack 
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
); 
1375     m_colDarkGrey 
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
); 
1376     m_penDarkGrey 
= wxPen(m_colDarkGrey
, 0, wxSOLID
); 
1378     m_penLightGrey 
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
); 
1380     m_colHighlight 
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
); 
1381     m_penHighlight 
= wxPen(m_colHighlight
, 0, wxSOLID
); 
1383     m_titlebarFont 
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
); 
1384     m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
); 
1386     // init the arrow bitmaps 
1387     static const size_t ARROW_WIDTH 
= 7; 
1388     static const size_t ARROW_LENGTH 
= 4; 
1391     wxMemoryDC dcNormal
, 
1394     for ( size_t n 
= 0; n 
< Arrow_Max
; n
++ ) 
1396         bool isVertical 
= n 
> Arrow_Right
; 
1409         // disabled arrow is larger because of the shadow 
1410         m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
); 
1411         m_bmpArrows
[Arrow_Disabled
][n
].Create(w 
+ 1, h 
+ 1); 
1413         dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]); 
1414         dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]); 
1416         dcNormal
.SetBackground(*wxWHITE_BRUSH
); 
1417         dcDisabled
.SetBackground(*wxWHITE_BRUSH
); 
1421         dcNormal
.SetPen(m_penBlack
); 
1422         dcDisabled
.SetPen(m_penDarkGrey
); 
1424         // calculate the position of the point of the arrow 
1428             x1 
= (ARROW_WIDTH 
- 1)/2; 
1429             y1 
= n 
== Arrow_Up 
? 0 : ARROW_LENGTH 
- 1; 
1433             x1 
= n 
== Arrow_Left 
? 0 : ARROW_LENGTH 
- 1; 
1434             y1 
= (ARROW_WIDTH 
- 1)/2; 
1445         for ( size_t i 
= 0; i 
< ARROW_LENGTH
; i
++ ) 
1447             dcNormal
.DrawLine(x1
, y1
, x2
, y2
); 
1448             dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1455                 if ( n 
== Arrow_Up 
) 
1466             else // left or right arrow 
1471                 if ( n 
== Arrow_Left 
) 
1484         // draw the shadow for the disabled one 
1485         dcDisabled
.SetPen(m_penHighlight
); 
1490                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1494                 x1 
= ARROW_LENGTH 
- 1; 
1495                 y1 
= (ARROW_WIDTH 
- 1)/2 + 1; 
1498                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1499                 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
); 
1504                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1508                 x1 
= ARROW_WIDTH 
- 1; 
1510                 x2 
= (ARROW_WIDTH 
- 1)/2; 
1512                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1513                 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
); 
1518         // create the inversed bitmap but only for the right arrow as we only 
1519         // use it for the menus 
1520         if ( n 
== Arrow_Right 
) 
1522             m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
); 
1523             dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]); 
1525             dcInverse
.Blit(0, 0, w
, h
, 
1528             dcInverse
.SelectObject(wxNullBitmap
); 
1530             mask 
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
); 
1531             m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
); 
1533             m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
); 
1534             dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]); 
1536             dcInverse
.Blit(0, 0, w
, h
, 
1539             dcInverse
.SelectObject(wxNullBitmap
); 
1541             mask 
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
); 
1542             m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
); 
1545         dcNormal
.SelectObject(wxNullBitmap
); 
1546         dcDisabled
.SelectObject(wxNullBitmap
); 
1548         mask 
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
); 
1549         m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
); 
1550         mask 
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
); 
1551         m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
); 
1553         m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
]; 
1556     // init the frame buttons bitmaps 
1557     m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
); 
1558     m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
); 
1559     m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
); 
1560     m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
); 
1561     m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
); 
1564 // ---------------------------------------------------------------------------- 
1566 // ---------------------------------------------------------------------------- 
1569    The raised border in Win32 looks like this: 
1571    IIIIIIIIIIIIIIIIIIIIIIB 
1573    I                    GB  I = white       (HILIGHT) 
1574    I                    GB  H = light grey  (LIGHT) 
1575    I                    GB  G = dark grey   (SHADOI) 
1576    I                    GB  B = black       (DKSHADOI) 
1577    I                    GB  I = hIghlight (COLOR_3DHILIGHT) 
1579    IGGGGGGGGGGGGGGGGGGGGGB 
1580    BBBBBBBBBBBBBBBBBBBBBBB 
1582    The sunken border looks like this: 
1584    GGGGGGGGGGGGGGGGGGGGGGI 
1585    GBBBBBBBBBBBBBBBBBBBBHI 
1592    GHHHHHHHHHHHHHHHHHHHHHI 
1593    IIIIIIIIIIIIIIIIIIIIIII 
1595    The static border (used for the controls which don't get focus) is like 
1598    GGGGGGGGGGGGGGGGGGGGGGW 
1606    WWWWWWWWWWWWWWWWWWWWWWW 
1608    The most complicated is the double border: 
1610    HHHHHHHHHHHHHHHHHHHHHHB 
1611    HWWWWWWWWWWWWWWWWWWWWGB 
1612    HWHHHHHHHHHHHHHHHHHHHGB 
1617    HWHHHHHHHHHHHHHHHHHHHGB 
1618    HGGGGGGGGGGGGGGGGGGGGGB 
1619    BBBBBBBBBBBBBBBBBBBBBBB 
1621    And the simple border is, well, simple: 
1623    BBBBBBBBBBBBBBBBBBBBBBB 
1632    BBBBBBBBBBBBBBBBBBBBBBB 
1635 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
) 
1639     dc
.SetBrush(*wxTRANSPARENT_BRUSH
); 
1640     dc
.DrawRectangle(*rect
); 
1646 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
) 
1648     // draw the bottom and right sides 
1650     dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(), 
1651                 rect
->GetRight() + 1, rect
->GetBottom()); 
1652     dc
.DrawLine(rect
->GetRight(), rect
->GetTop(), 
1653                 rect
->GetRight(), rect
->GetBottom()); 
1660 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect 
*rect
, 
1661                                      const wxPen
& pen1
, const wxPen
& pen2
) 
1663     // draw the rectangle 
1665     dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(), 
1666                 rect
->GetLeft(), rect
->GetBottom()); 
1667     dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(), 
1668                 rect
->GetRight(), rect
->GetTop()); 
1670     dc
.DrawLine(rect
->GetRight(), rect
->GetTop(), 
1671                 rect
->GetRight(), rect
->GetBottom()); 
1672     dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(), 
1673                 rect
->GetRight() + 1, rect
->GetBottom()); 
1679 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect 
*rect
) 
1681     DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
); 
1682     DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
); 
1685 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect 
*rect
) 
1687     DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
); 
1688     DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
); 
1691 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect 
*rect
, bool isPressed
) 
1695         DrawRect(dc
, rect
, m_penDarkGrey
); 
1697         // the arrow is usually drawn inside border of width 2 and is offset by 
1698         // another pixel in both directions when it's pressed - as the border 
1699         // in this case is more narrow as well, we have to adjust rect like 
1707         DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
); 
1708         DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
); 
1712 void wxWin32Renderer::DrawBorder(wxDC
& dc
, 
1714                                  const wxRect
& rectTotal
, 
1715                                  int WXUNUSED(flags
), 
1720     wxRect rect 
= rectTotal
; 
1724         case wxBORDER_SUNKEN
: 
1725             for ( i 
= 0; i 
< BORDER_THICKNESS 
/ 2; i
++ ) 
1727                 DrawSunkenBorder(dc
, &rect
); 
1731         case wxBORDER_STATIC
: 
1732             DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
); 
1735         case wxBORDER_RAISED
: 
1736             for ( i 
= 0; i 
< BORDER_THICKNESS 
/ 2; i
++ ) 
1738                 DrawRaisedBorder(dc
, &rect
); 
1742         case wxBORDER_DOUBLE
: 
1743             DrawArrowBorder(dc
, &rect
); 
1744             DrawRect(dc
, &rect
, m_penLightGrey
); 
1747         case wxBORDER_SIMPLE
: 
1748             for ( i 
= 0; i 
< BORDER_THICKNESS 
/ 2; i
++ ) 
1750                 DrawRect(dc
, &rect
, m_penBlack
); 
1755             wxFAIL_MSG(_T("unknown border type")); 
1758         case wxBORDER_DEFAULT
: 
1767 wxRect 
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const 
1772         case wxBORDER_RAISED
: 
1773         case wxBORDER_SUNKEN
: 
1774             width 
= BORDER_THICKNESS
; 
1777         case wxBORDER_SIMPLE
: 
1778         case wxBORDER_STATIC
: 
1782         case wxBORDER_DOUBLE
: 
1787             wxFAIL_MSG(_T("unknown border type")); 
1790         case wxBORDER_DEFAULT
: 
1800     rect
.height 
= width
; 
1805 bool wxWin32Renderer::AreScrollbarsInsideBorder() const 
1810 // ---------------------------------------------------------------------------- 
1812 // ---------------------------------------------------------------------------- 
1814 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
, 
1820     // text controls are not special under windows 
1821     DrawBorder(dc
, border
, rect
, flags
, rectIn
); 
1824 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
, 
1825                                        const wxRect
& rectTotal
, 
1829     wxRect rect 
= rectTotal
; 
1831     if ( flags 
& wxCONTROL_PRESSED 
) 
1833         // button pressed: draw a double border around it 
1834         DrawRect(dc
, &rect
, m_penBlack
); 
1835         DrawRect(dc
, &rect
, m_penDarkGrey
); 
1839         // button not pressed 
1841         if ( flags 
& (wxCONTROL_FOCUSED 
| wxCONTROL_ISDEFAULT
) ) 
1843             // button either default or focused (or both): add an extra border around it 
1844             DrawRect(dc
, &rect
, m_penBlack
); 
1847         // now draw a normal button 
1848         DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
); 
1849         DrawHalfRect(dc
, &rect
, m_penDarkGrey
); 
1858 // ---------------------------------------------------------------------------- 
1860 // ---------------------------------------------------------------------------- 
1862 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
, 
1863                                          wxCoord y
, wxCoord x1
, wxCoord x2
) 
1865     dc
.SetPen(m_penDarkGrey
); 
1866     dc
.DrawLine(x1
, y
, x2 
+ 1, y
); 
1867     dc
.SetPen(m_penHighlight
); 
1869     dc
.DrawLine(x1
, y
, x2 
+ 1, y
); 
1872 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
, 
1873                                        wxCoord x
, wxCoord y1
, wxCoord y2
) 
1875     dc
.SetPen(m_penDarkGrey
); 
1876     dc
.DrawLine(x
, y1
, x
, y2 
+ 1); 
1877     dc
.SetPen(m_penHighlight
); 
1879     dc
.DrawLine(x
, y1
, x
, y2 
+ 1); 
1882 void wxWin32Renderer::DrawFrame(wxDC
& dc
, 
1883                                 const wxString
& label
, 
1889     wxCoord height 
= 0; // of the label 
1890     wxRect rectFrame 
= rect
; 
1891     if ( !label
.empty() ) 
1893         // the text should touch the top border of the rect, so the frame 
1894         // itself should be lower 
1895         dc
.GetTextExtent(label
, NULL
, &height
); 
1896         rectFrame
.y 
+= height 
/ 2; 
1897         rectFrame
.height 
-= height 
/ 2; 
1899         // we have to draw each part of the frame individually as we can't 
1900         // erase the background beyond the label as it might contain some 
1901         // pixmap already, so drawing everything and then overwriting part of 
1902         // the frame with label doesn't work 
1904         // TODO: the +5 and space insertion should be customizable 
1907         rectText
.x 
= rectFrame
.x 
+ 5; 
1908         rectText
.y 
= rect
.y
; 
1909         rectText
.width 
= rectFrame
.width 
- 7; // +2 border width 
1910         rectText
.height 
= height
; 
1913         label2 
<< _T(' ') << label 
<< _T(' '); 
1914         if ( indexAccel 
!= -1 ) 
1916             // adjust it as we prepended a space 
1921         DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
); 
1923         StandardDrawFrame(dc
, rectFrame
, rectLabel
); 
1927         // just draw the complete frame 
1928         DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
); 
1929         DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
); 
1933 // ---------------------------------------------------------------------------- 
1935 // ---------------------------------------------------------------------------- 
1937 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
) 
1939     // VZ: this doesn't work under Windows, the dotted pen has dots of 3 
1940     //     pixels each while we really need dots here... PS_ALTERNATE might 
1941     //     work, but it is for NT 5 only 
1943     DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
)); 
1945     // draw the pixels manually: note that to behave in the same manner as 
1946     // DrawRect(), we must exclude the bottom and right borders from the 
1948     wxCoord x1 
= rect
.GetLeft(), 
1950             x2 
= rect
.GetRight(), 
1951             y2 
= rect
.GetBottom(); 
1953     dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
)); 
1955     // this seems to be closer than what Windows does than wxINVERT although 
1956     // I'm still not sure if it's correct 
1957     dc
.SetLogicalFunction(wxAND_REVERSE
); 
1960     for ( z 
= x1 
+ 1; z 
< x2
; z 
+= 2 ) 
1961         dc
.DrawPoint(z
, rect
.GetTop()); 
1963     wxCoord shift 
= z 
== x2 
? 0 : 1; 
1964     for ( z 
= y1 
+ shift
; z 
< y2
; z 
+= 2 ) 
1965         dc
.DrawPoint(x2
, z
); 
1967     shift 
= z 
== y2 
? 0 : 1; 
1968     for ( z 
= x2 
- shift
; z 
> x1
; z 
-= 2 ) 
1969         dc
.DrawPoint(z
, y2
); 
1971     shift 
= z 
== x1 
? 0 : 1; 
1972     for ( z 
= y2 
- shift
; z 
> y1
; z 
-= 2 ) 
1973         dc
.DrawPoint(x1
, z
); 
1975     dc
.SetLogicalFunction(wxCOPY
); 
1979 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
, 
1980                                       const wxString
& label
, 
1985     // draw shadow of the text 
1986     dc
.SetTextForeground(m_colHighlight
); 
1987     wxRect rectShadow 
= rect
; 
1990     dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
); 
1992     // make the text grey 
1993     dc
.SetTextForeground(m_colDarkGrey
); 
1996 void wxWin32Renderer::DrawLabel(wxDC
& dc
, 
1997                                 const wxString
& label
, 
2004     DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
); 
2007 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
, 
2008                                   const wxString
& label
, 
2014                                   const wxPoint
& focusOffset
) 
2016     // the underscores are not drawn for focused controls in wxMSW 
2017     if ( flags 
& wxCONTROL_FOCUSED 
) 
2022     if ( flags 
& wxCONTROL_DISABLED 
) 
2024         // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED 
2025         // currently only can happen for a menu item and it seems that Windows 
2026         // doesn't draw the shadow in this case, so we don't do it neither 
2027         if ( flags 
& wxCONTROL_SELECTED 
) 
2029             // just make the label text greyed out 
2030             dc
.SetTextForeground(m_colDarkGrey
); 
2032         else // draw normal disabled label 
2034             DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
); 
2039     dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
); 
2041     if ( flags 
& wxCONTROL_DISABLED 
) 
2043         // restore the fg colour 
2044         dc
.SetTextForeground(*wxBLACK
); 
2047     if ( flags 
& wxCONTROL_FOCUSED 
) 
2049         if ( focusOffset
.x 
|| focusOffset
.y 
) 
2051             rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
); 
2054         DrawFocusRect(dc
, rectLabel
); 
2058         *rectBounds 
= rectLabel
; 
2061 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
, 
2062                                       const wxString
& label
, 
2063                                       const wxBitmap
& image
, 
2070     // the underscores are not drawn for focused controls in wxMSW 
2071     if ( flags 
& wxCONTROL_PRESSED 
) 
2076     wxRect rectLabel 
= rect
; 
2077     if ( !label
.empty() ) 
2079         // shift the label if a button is pressed 
2080         if ( flags 
& wxCONTROL_PRESSED 
) 
2086         if ( flags 
& wxCONTROL_DISABLED 
) 
2088             DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
); 
2091         // leave enough space for the focus rectangle 
2092         if ( flags 
& wxCONTROL_FOCUSED 
) 
2094             rectLabel
.Inflate(-2); 
2098     dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
); 
2100     if ( !label
.empty() && (flags 
& wxCONTROL_FOCUSED
) ) 
2102         if ( flags 
& wxCONTROL_PRESSED 
) 
2104             // the focus rectangle is never pressed, so undo the shift done 
2112         DrawFocusRect(dc
, rectLabel
); 
2116 // ---------------------------------------------------------------------------- 
2117 // (check)listbox items 
2118 // ---------------------------------------------------------------------------- 
2120 void wxWin32Renderer::DrawItem(wxDC
& dc
, 
2121                                const wxString
& label
, 
2125     wxDCTextColourChanger 
colChanger(dc
); 
2127     if ( flags 
& wxCONTROL_SELECTED 
) 
2129         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
2131         wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
2132         dc
.SetBrush(wxBrush(colBg
, wxSOLID
)); 
2133         dc
.SetPen(wxPen(colBg
, 0, wxSOLID
)); 
2134         dc
.DrawRectangle(rect
); 
2137     wxRect rectText 
= rect
; 
2139     rectText
.width 
-= 2; 
2140     dc
.DrawLabel(label
, wxNullBitmap
, rectText
); 
2142     if ( flags 
& wxCONTROL_FOCUSED 
) 
2144         DrawFocusRect(dc
, rect
); 
2148 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
, 
2149                                     const wxString
& label
, 
2150                                     const wxBitmap
& bitmap
, 
2159     else // use default bitmap 
2161         bmp 
= wxBitmap(flags 
& wxCONTROL_CHECKED 
? checked_item_xpm
 
2162                                                  : unchecked_item_xpm
); 
2165     dc
.DrawBitmap(bmp
, rect
.x
, rect
.y 
+ (rect
.height 
- bmp
.GetHeight()) / 2 - 1, 
2166                   TRUE 
/* use mask */); 
2168     wxRect rectLabel 
= rect
; 
2169     int bmpWidth 
= bmp
.GetWidth(); 
2170     rectLabel
.x 
+= bmpWidth
; 
2171     rectLabel
.width 
-= bmpWidth
; 
2173     DrawItem(dc
, label
, rectLabel
, flags
); 
2176 // ---------------------------------------------------------------------------- 
2177 // check/radio buttons 
2178 // ---------------------------------------------------------------------------- 
2180 wxBitmap 
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
) 
2182     IndicatorState indState
; 
2183     if ( flags 
& wxCONTROL_SELECTED 
) 
2184         indState 
= flags 
& wxCONTROL_DISABLED 
? IndicatorState_SelectedDisabled
 
2185                                               : IndicatorState_Selected
; 
2186     else if ( flags 
& wxCONTROL_DISABLED 
) 
2187         indState 
= IndicatorState_Disabled
; 
2188     else if ( flags 
& wxCONTROL_PRESSED 
) 
2189         indState 
= IndicatorState_Pressed
; 
2191         indState 
= IndicatorState_Normal
; 
2193     IndicatorStatus indStatus 
= flags 
& wxCONTROL_CHECKED
 
2194                                     ? IndicatorStatus_Checked
 
2195                                     : IndicatorStatus_Unchecked
; 
2197     const char **xpm 
= bmpIndicators
[indType
][indState
][indStatus
]; 
2204         return wxNullBitmap
; 
2207 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
, 
2208                                              const wxString
& label
, 
2209                                              const wxBitmap
& bitmap
, 
2214                                              wxCoord focusOffsetY
) 
2216     // calculate the position of the bitmap and of the label 
2217     wxCoord heightBmp 
= bitmap
.GetHeight(); 
2219             yBmp 
= rect
.y 
+ (rect
.height 
- heightBmp
) / 2; 
2222     dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
); 
2223     rectLabel
.y 
= rect
.y 
+ (rect
.height 
- rectLabel
.height
) / 2; 
2225     // align label vertically with the bitmap - looks nicer like this 
2226     rectLabel
.y 
-= (rectLabel
.height 
- heightBmp
) % 2; 
2228     // calc horz position 
2229     if ( align 
== wxALIGN_RIGHT 
) 
2231         xBmp 
= rect
.GetRight() - bitmap
.GetWidth(); 
2232         rectLabel
.x 
= rect
.x 
+ 3; 
2233         rectLabel
.SetRight(xBmp
); 
2235     else // normal (checkbox to the left of the text) case 
2238         rectLabel
.x 
= xBmp 
+ bitmap
.GetWidth() + 5; 
2239         rectLabel
.SetRight(rect
.GetRight()); 
2242     dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE 
/* use mask */); 
2245                 dc
, label
, rectLabel
, 
2247                 wxALIGN_LEFT 
| wxALIGN_TOP
, 
2249                 NULL
,         // we don't need bounding rect 
2250                 // use custom vert focus rect offset 
2251                 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
) 
2255 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
, 
2256                                       const wxString
& label
, 
2257                                       const wxBitmap
& bitmap
, 
2264         DrawCheckOrRadioButton(dc
, label
, 
2266                            rect
, flags
, align
, indexAccel
, 
2267                              FOCUS_RECT_OFFSET_Y
); // default focus rect offset 
2270         wxBitmap 
rbitmap(GetRadioBitmap(flags
)); 
2271         DrawCheckOrRadioButton(dc
, label
, 
2273                            rect
, flags
, align
, indexAccel
, 
2274                                FOCUS_RECT_OFFSET_Y
); // default focus rect offset 
2278 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
, 
2279                                       const wxString
& label
, 
2280                                       const wxBitmap
& bitmap
, 
2287         DrawCheckOrRadioButton(dc
, label
, 
2289                              rect
, flags
, align
, indexAccel
, 
2290                              0); // no focus rect offset for checkboxes 
2293             wxBitmap 
cbitmap(GetCheckBitmap(flags
)); 
2294         DrawCheckOrRadioButton(dc
, label
, 
2296                              rect
, flags
, align
, indexAccel
, 
2297                                0); // no focus rect offset for checkboxes 
2301 // ---------------------------------------------------------------------------- 
2303 // ---------------------------------------------------------------------------- 
2305 void wxWin32Renderer::DrawTextLine(wxDC
& dc
, 
2306                                    const wxString
& text
, 
2312     // nothing special to do here 
2313     StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
); 
2316 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
) 
2318     // we don't draw them 
2321 // ---------------------------------------------------------------------------- 
2323 // ---------------------------------------------------------------------------- 
2325 void wxWin32Renderer::DrawTab(wxDC
& dc
, 
2326                               const wxRect
& rectOrig
, 
2328                               const wxString
& label
, 
2329                               const wxBitmap
& bitmap
, 
2333     wxRect rect 
= rectOrig
; 
2335     // the current tab is drawn indented (to the top for default case) and 
2336     // bigger than the other ones 
2337     const wxSize indent 
= GetTabIndent(); 
2338     if ( flags 
& wxCONTROL_SELECTED 
) 
2343                 wxFAIL_MSG(_T("invaild notebook tab orientation")); 
2347                 rect
.Inflate(indent
.x
, 0); 
2349                 rect
.height 
+= indent
.y
; 
2353                 rect
.Inflate(indent
.x
, 0); 
2354                 rect
.height 
+= indent
.y
; 
2359                 wxFAIL_MSG(_T("TODO")); 
2364     // draw the text, image and the focus around them (if necessary) 
2365     wxRect rectLabel 
= rect
; 
2366     rectLabel
.Deflate(1, 1); 
2367     DrawButtonLabel(dc
, label
, bitmap
, rectLabel
, 
2368                     flags
, wxALIGN_CENTRE
, indexAccel
); 
2370     // now draw the tab border itself (maybe use DrawRoundedRectangle()?) 
2371     static const wxCoord CUTOFF 
= 2; // radius of the rounded corner 
2374             x2 
= rect
.GetRight(), 
2375             y2 
= rect
.GetBottom(); 
2377     // FIXME: all this code will break if the tab indent or the border width, 
2378     //        it is tied to the fact that both of them are equal to 2 
2383             dc
.SetPen(m_penHighlight
); 
2384             dc
.DrawLine(x
, y2
, x
, y 
+ CUTOFF
); 
2385             dc
.DrawLine(x
, y 
+ CUTOFF
, x 
+ CUTOFF
, y
); 
2386             dc
.DrawLine(x 
+ CUTOFF
, y
, x2 
- CUTOFF 
+ 1, y
); 
2388             dc
.SetPen(m_penBlack
); 
2389             dc
.DrawLine(x2
, y2
, x2
, y 
+ CUTOFF
); 
2390             dc
.DrawLine(x2
, y 
+ CUTOFF
, x2 
- CUTOFF
, y
); 
2392             dc
.SetPen(m_penDarkGrey
); 
2393             dc
.DrawLine(x2 
- 1, y2
, x2 
- 1, y 
+ CUTOFF 
- 1); 
2395             if ( flags 
& wxCONTROL_SELECTED 
) 
2397                 dc
.SetPen(m_penLightGrey
); 
2399                 // overwrite the part of the border below this tab 
2400                 dc
.DrawLine(x 
+ 1, y2 
+ 1, x2 
- 1, y2 
+ 1); 
2402                 // and the shadow of the tab to the left of us 
2403                 dc
.DrawLine(x 
+ 1, y 
+ CUTOFF 
+ 1, x 
+ 1, y2 
+ 1); 
2408             dc
.SetPen(m_penHighlight
); 
2409             // we need to continue one pixel further to overwrite the corner of 
2410             // the border for the selected tab 
2411             dc
.DrawLine(x
, y 
- (flags 
& wxCONTROL_SELECTED 
? 1 : 0), 
2413             dc
.DrawLine(x
, y2 
- CUTOFF
, x 
+ CUTOFF
, y2
); 
2415             dc
.SetPen(m_penBlack
); 
2416             dc
.DrawLine(x 
+ CUTOFF
, y2
, x2 
- CUTOFF 
+ 1, y2
); 
2417             dc
.DrawLine(x2
, y
, x2
, y2 
- CUTOFF
); 
2418             dc
.DrawLine(x2
, y2 
- CUTOFF
, x2 
- CUTOFF
, y2
); 
2420             dc
.SetPen(m_penDarkGrey
); 
2421             dc
.DrawLine(x 
+ CUTOFF
, y2 
- 1, x2 
- CUTOFF 
+ 1, y2 
- 1); 
2422             dc
.DrawLine(x2 
- 1, y
, x2 
- 1, y2 
- CUTOFF 
+ 1); 
2424             if ( flags 
& wxCONTROL_SELECTED 
) 
2426                 dc
.SetPen(m_penLightGrey
); 
2428                 // overwrite the part of the (double!) border above this tab 
2429                 dc
.DrawLine(x 
+ 1, y 
- 1, x2 
- 1, y 
- 1); 
2430                 dc
.DrawLine(x 
+ 1, y 
- 2, x2 
- 1, y 
- 2); 
2432                 // and the shadow of the tab to the left of us 
2433                 dc
.DrawLine(x 
+ 1, y2 
- CUTOFF
, x 
+ 1, y 
- 1); 
2439             wxFAIL_MSG(_T("TODO")); 
2443 // ---------------------------------------------------------------------------- 
2445 // ---------------------------------------------------------------------------- 
2447 wxSize 
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
, 
2448                                            wxOrientation orient
) const 
2452     wxRect rectShaft 
= GetSliderShaftRect(rect
, orient
); 
2453     if ( orient 
== wxHORIZONTAL 
) 
2455         size
.y 
= rect
.height 
- 6; 
2456         size
.x 
= wxMin(size
.y 
/ 2, rectShaft
.width
); 
2460         size
.x 
= rect
.width 
- 6; 
2461         size
.y 
= wxMin(size
.x 
/ 2, rectShaft
.height
); 
2467 wxRect 
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
, 
2468                                            wxOrientation orient
) const 
2470     static const wxCoord SLIDER_MARGIN 
= 6; 
2472     wxRect rect 
= rectOrig
; 
2474     if ( orient 
== wxHORIZONTAL 
) 
2476         // make the rect of minimal width and centre it 
2477         rect
.height 
= 2*BORDER_THICKNESS
; 
2478         rect
.y 
= rectOrig
.y 
+ (rectOrig
.height 
- rect
.height
) / 2; 
2482         // leave margins on the sides 
2483         rect
.Deflate(SLIDER_MARGIN
, 0); 
2487         // same as above but in other direction 
2488         rect
.width 
= 2*BORDER_THICKNESS
; 
2489         rect
.x 
= rectOrig
.x 
+ (rectOrig
.width 
- rect
.width
) / 2; 
2493         rect
.Deflate(0, SLIDER_MARGIN
); 
2499 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
, 
2500                                       const wxRect
& rectOrig
, 
2501                                       wxOrientation orient
, 
2505     if ( flags 
& wxCONTROL_FOCUSED 
) 
2507         DrawFocusRect(dc
, rectOrig
); 
2510     wxRect rect 
= GetSliderShaftRect(rectOrig
, orient
); 
2515     DrawSunkenBorder(dc
, &rect
); 
2518 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
, 
2520                                       wxOrientation orient
, 
2524        we are drawing a shape of this form 
2529        H    DB   where H is hightlight colour 
2542        The interior of this shape is filled with the hatched brush if the thumb 
2546     DrawBackground(dc
, wxNullColour
, rect
, flags
); 
2548     bool transpose 
= orient 
== wxVERTICAL
; 
2550     wxCoord x
, y
, x2
, y2
; 
2555         x2 
= rect
.GetBottom(); 
2556         y2 
= rect
.GetRight(); 
2562         x2 
= rect
.GetRight(); 
2563         y2 
= rect
.GetBottom(); 
2566     // the size of the pointed part of the thumb 
2567     wxCoord sizeArrow 
= (transpose 
? rect
.height 
: rect
.width
) / 2; 
2569     wxCoord x3 
= x 
+ sizeArrow
, 
2570             y3 
= y2 
- sizeArrow
; 
2572     dc
.SetPen(m_penHighlight
); 
2573     DrawLine(dc
, x
, y
, x2
, y
, transpose
); 
2574     DrawLine(dc
, x
, y 
+ 1, x
, y2 
- sizeArrow
, transpose
); 
2575     DrawLine(dc
, x
, y3
, x3
, y2
, transpose
); 
2577     dc
.SetPen(m_penBlack
); 
2578     DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
); 
2579     DrawLine(dc
, x2
, y3
, x2
, y 
- 1, transpose
); 
2581     dc
.SetPen(m_penDarkGrey
); 
2582     DrawLine(dc
, x3
, y2 
- 1, x2 
- 1, y3
, transpose
); 
2583     DrawLine(dc
, x2 
- 1, y3
, x2 
- 1, y
, transpose
); 
2585     if ( flags 
& wxCONTROL_PRESSED 
) 
2587         // TODO: MSW fills the entire area inside, not just the rect 
2588         wxRect rectInt 
= rect
; 
2590             rectInt
.SetRight(y3
); 
2592             rectInt
.SetBottom(y3
); 
2595 #if !defined(__WXMGL__) 
2596         static const char *stipple_xpm
[] = { 
2597             /* columns rows colors chars-per-pixel */ 
2606         // VS: MGL can only do 8x8 stipple brushes 
2607         static const char *stipple_xpm
[] = { 
2608             /* columns rows colors chars-per-pixel */ 
2623         dc
.SetBrush(wxBrush(stipple_xpm
)); 
2625         dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
)); 
2626         dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
)); 
2627         dc
.SetPen(*wxTRANSPARENT_PEN
); 
2628         dc
.DrawRectangle(rectInt
); 
2632 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
, 
2634                                       const wxSize
& sizeThumb
, 
2635                                       wxOrientation orient
, 
2647     // the variable names correspond to horizontal case, but they can be used 
2648     // for both orientations 
2649     wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
; 
2650     if ( orient 
== wxHORIZONTAL 
) 
2652         x1 
= rect
.GetLeft(); 
2653         x2 
= rect
.GetRight(); 
2655         // draw from bottom to top to leave one pixel space between the ticks 
2656         // and the slider as Windows do 
2657         y1 
= rect
.GetBottom(); 
2662         widthThumb 
= sizeThumb
.x
; 
2667         x2 
= rect
.GetBottom(); 
2669         y1 
= rect
.GetRight(); 
2670         y2 
= rect
.GetLeft(); 
2674         widthThumb 
= sizeThumb
.y
; 
2677     // the first tick should be positioned in such way that a thumb drawn in 
2678     // the first position points down directly to it 
2679     x1 
+= widthThumb 
/ 2; 
2680     x2 
-= widthThumb 
/ 2; 
2682     // this also means that we have slightly less space for the ticks in 
2683     // between the first and the last 
2686     dc
.SetPen(m_penBlack
); 
2688     int range 
= end 
- start
; 
2689     for ( int n 
= 0; n 
< range
; n 
+= step 
) 
2691         wxCoord x 
= x1 
+ (len
*n
) / range
; 
2693         DrawLine(dc
, x
, y1
, x
, y2
, orient 
== wxVERTICAL
); 
2696     // always draw the line at the end position 
2697     DrawLine(dc
, x2
, y1
, x2
, y2
, orient 
== wxVERTICAL
); 
2700 // ---------------------------------------------------------------------------- 
2702 // ---------------------------------------------------------------------------- 
2704 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer 
2705 class WXDLLEXPORT wxWin32MenuGeometryInfo 
: public wxMenuGeometryInfo
 
2708     virtual wxSize 
GetSize() const { return m_size
; } 
2710     wxCoord 
GetLabelOffset() const { return m_ofsLabel
; } 
2711     wxCoord 
GetAccelOffset() const { return m_ofsAccel
; } 
2713     wxCoord 
GetItemHeight() const { return m_heightItem
; } 
2716     // the total size of the menu 
2719     // the offset of the start of the menu item label 
2722     // the offset of the start of the accel label 
2725     // the height of a normal (not separator) item 
2726     wxCoord m_heightItem
; 
2728     friend wxMenuGeometryInfo 
* 
2729         wxWin32Renderer::GetMenuGeometry(wxWindow 
*, const wxMenu
&) const; 
2732 // FIXME: all constants are hardcoded but shouldn't be 
2733 static const wxCoord MENU_LEFT_MARGIN 
= 9; 
2734 static const wxCoord MENU_RIGHT_MARGIN 
= 18; 
2735 static const wxCoord MENU_VERT_MARGIN 
= 3; 
2737 // the margin around bitmap/check marks (on each side) 
2738 static const wxCoord MENU_BMP_MARGIN 
= 2; 
2740 // the margin between the labels and accel strings 
2741 static const wxCoord MENU_ACCEL_MARGIN 
= 8; 
2743 // the separator height in pixels: in fact, strangely enough, the real height 
2744 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into 
2746 static const wxCoord MENU_SEPARATOR_HEIGHT 
= 3; 
2748 // the size of the standard checkmark bitmap 
2749 static const wxCoord MENU_CHECK_SIZE 
= 9; 
2751 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
, 
2752                                       const wxRect
& rectOrig
, 
2753                                       const wxString
& label
, 
2757     wxRect rect 
= rectOrig
; 
2760     wxDCTextColourChanger 
colChanger(dc
); 
2762     if ( flags 
& wxCONTROL_SELECTED 
) 
2764         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
2766         wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
2767         dc
.SetBrush(wxBrush(colBg
, wxSOLID
)); 
2768         dc
.SetPen(wxPen(colBg
, 0, wxSOLID
)); 
2769         dc
.DrawRectangle(rect
); 
2772     // don't draw the focus rect around menu bar items 
2773     DrawLabel(dc
, label
, rect
, flags 
& ~wxCONTROL_FOCUSED
, 
2774               wxALIGN_CENTRE
, indexAccel
); 
2777 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
, 
2779                                    const wxMenuGeometryInfo
& gi
, 
2780                                    const wxString
& label
, 
2781                                    const wxString
& accel
, 
2782                                    const wxBitmap
& bitmap
, 
2786     const wxWin32MenuGeometryInfo
& geometryInfo 
= 
2787         (const wxWin32MenuGeometryInfo
&)gi
; 
2792     rect
.width 
= geometryInfo
.GetSize().x
; 
2793     rect
.height 
= geometryInfo
.GetItemHeight(); 
2795     // draw the selected item specially 
2796     wxDCTextColourChanger 
colChanger(dc
); 
2797     if ( flags 
& wxCONTROL_SELECTED 
) 
2799         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
2801         wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
2802         dc
.SetBrush(wxBrush(colBg
, wxSOLID
)); 
2803         dc
.SetPen(wxPen(colBg
, 0, wxSOLID
)); 
2804         dc
.DrawRectangle(rect
); 
2807     // draw the bitmap: use the bitmap provided or the standard checkmark for 
2808     // the checkable items 
2809     wxBitmap bmp 
= bitmap
; 
2810     if ( !bmp
.Ok() && (flags 
& wxCONTROL_CHECKED
) ) 
2812         bmp 
= GetIndicator(IndicatorType_Menu
, flags
); 
2817         rect
.SetRight(geometryInfo
.GetLabelOffset()); 
2818         wxControlRenderer::DrawBitmap(dc
, bmp
, rect
); 
2822     rect
.x 
= geometryInfo
.GetLabelOffset(); 
2823     rect
.SetRight(geometryInfo
.GetAccelOffset()); 
2825     DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
); 
2827     // draw the accel string 
2828     rect
.x 
= geometryInfo
.GetAccelOffset(); 
2829     rect
.SetRight(geometryInfo
.GetSize().x
); 
2831     // NB: no accel index here 
2832     DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
); 
2834     // draw the submenu indicator 
2835     if ( flags 
& wxCONTROL_ISSUBMENU 
) 
2837         rect
.x 
= geometryInfo
.GetSize().x 
- MENU_RIGHT_MARGIN
; 
2838         rect
.width 
= MENU_RIGHT_MARGIN
; 
2840         wxArrowStyle arrowStyle
; 
2841         if ( flags 
& wxCONTROL_DISABLED 
) 
2842             arrowStyle 
= flags 
& wxCONTROL_SELECTED 
? Arrow_InversedDisabled
 
2844         else if ( flags 
& wxCONTROL_SELECTED 
) 
2845             arrowStyle 
= Arrow_Inversed
; 
2847             arrowStyle 
= Arrow_Normal
; 
2849         DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
); 
2853 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
, 
2855                                         const wxMenuGeometryInfo
& geomInfo
) 
2857     DrawHorizontalLine(dc
, y 
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
); 
2860 wxSize 
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const 
2862     wxSize size 
= sizeText
; 
2864     // FIXME: menubar height is configurable under Windows 
2871 wxMenuGeometryInfo 
*wxWin32Renderer::GetMenuGeometry(wxWindow 
*win
, 
2872                                                      const wxMenu
& menu
) const 
2874     // prepare the dc: for now we draw all the items with the system font 
2876     dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
2878     // the height of a normal item 
2879     wxCoord heightText 
= dc
.GetCharHeight(); 
2884     // the max length of label and accel strings: the menu width is the sum of 
2885     // them, even if they're for different items (as the accels should be 
2888     // the max length of the bitmap is never 0 as Windows always leaves enough 
2889     // space for a check mark indicator 
2890     wxCoord widthLabelMax 
= 0, 
2892             widthBmpMax 
= MENU_LEFT_MARGIN
; 
2894     for ( wxMenuItemList::Node 
*node 
= menu
.GetMenuItems().GetFirst(); 
2896           node 
= node
->GetNext() ) 
2898         // height of this item 
2901         wxMenuItem 
*item 
= node
->GetData(); 
2902         if ( item
->IsSeparator() ) 
2904             h 
= MENU_SEPARATOR_HEIGHT
; 
2906         else // not separator 
2911             dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
); 
2912             if ( widthLabel 
> widthLabelMax 
) 
2914                 widthLabelMax 
= widthLabel
; 
2918             dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
); 
2919             if ( widthAccel 
> widthAccelMax 
) 
2921                 widthAccelMax 
= widthAccel
; 
2924             const wxBitmap
& bmp 
= item
->GetBitmap(); 
2927                 wxCoord widthBmp 
= bmp
.GetWidth(); 
2928                 if ( widthBmp 
> widthBmpMax 
) 
2929                     widthBmpMax 
= widthBmp
; 
2931             //else if ( item->IsCheckable() ): no need to check for this as 
2932             // MENU_LEFT_MARGIN is big enough to show the check mark 
2935         h 
+= 2*MENU_VERT_MARGIN
; 
2937         // remember the item position and height 
2938         item
->SetGeometry(height
, h
); 
2943     // bundle the metrics into a struct and return it 
2944     wxWin32MenuGeometryInfo 
*gi 
= new wxWin32MenuGeometryInfo
; 
2946     gi
->m_ofsLabel 
= widthBmpMax 
+ 2*MENU_BMP_MARGIN
; 
2947     gi
->m_ofsAccel 
= gi
->m_ofsLabel 
+ widthLabelMax
; 
2948     if ( widthAccelMax 
> 0 ) 
2950         // if we actually have any accesl, add a margin 
2951         gi
->m_ofsAccel 
+= MENU_ACCEL_MARGIN
; 
2954     gi
->m_heightItem 
= heightText 
+ 2*MENU_VERT_MARGIN
; 
2956     gi
->m_size
.x 
= gi
->m_ofsAccel 
+ widthAccelMax 
+ MENU_RIGHT_MARGIN
; 
2957     gi
->m_size
.y 
= height
; 
2962 // ---------------------------------------------------------------------------- 
2964 // ---------------------------------------------------------------------------- 
2966 static const wxCoord STATBAR_BORDER_X 
= 2; 
2967 static const wxCoord STATBAR_BORDER_Y 
= 2; 
2969 wxSize 
wxWin32Renderer::GetStatusBarBorders(wxCoord 
*borderBetweenFields
) const 
2971     if ( borderBetweenFields 
) 
2972         *borderBetweenFields 
= 2; 
2974     return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
); 
2977 void wxWin32Renderer::DrawStatusField(wxDC
& dc
, 
2979                                       const wxString
& label
, 
2984     if ( flags 
& wxCONTROL_ISDEFAULT 
) 
2986         // draw the size grip: it is a normal rect except that in the lower 
2987         // right corner we have several bands which may be used for dragging 
2988         // the status bar corner 
2990         // each band consists of 4 stripes: m_penHighlight, double 
2991         // m_penDarkGrey and transparent one 
2992         wxCoord x2 
= rect
.GetRight(), 
2993                 y2 
= rect
.GetBottom(); 
2995         // draw the upper left part of the rect normally 
2996         dc
.SetPen(m_penDarkGrey
); 
2997         dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
); 
2998         dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop()); 
3000         // draw the grey stripes of the grip 
3002         wxCoord ofs 
= WIDTH_STATUSBAR_GRIP_BAND 
- 1; 
3003         for ( n 
= 0; n 
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs 
+= WIDTH_STATUSBAR_GRIP_BAND 
) 
3005             dc
.DrawLine(x2 
- ofs 
+ 1, y2 
- 1, x2
, y2 
- ofs
); 
3006             dc
.DrawLine(x2 
- ofs
, y2 
- 1, x2
, y2 
- ofs 
- 1); 
3009         // draw the white stripes 
3010         dc
.SetPen(m_penHighlight
); 
3011         ofs 
= WIDTH_STATUSBAR_GRIP_BAND 
+ 1; 
3012         for ( n 
= 0; n 
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs 
+= WIDTH_STATUSBAR_GRIP_BAND 
) 
3014             dc
.DrawLine(x2 
- ofs 
+ 1, y2 
- 1, x2
, y2 
- ofs
); 
3017         // draw the remaining rect boundaries 
3018         ofs 
-= WIDTH_STATUSBAR_GRIP_BAND
; 
3019         dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2 
- ofs 
+ 1); 
3020         dc
.DrawLine(rect
.GetLeft(), y2
, x2 
- ofs 
+ 1, y2
); 
3025         rectIn
.width 
-= STATUSBAR_GRIP_SIZE
; 
3029         DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
); 
3032     rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
); 
3034     wxDCClipper 
clipper(dc
, rectIn
); 
3035     DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT 
| wxALIGN_CENTRE_VERTICAL
); 
3038 // ---------------------------------------------------------------------------- 
3040 // ---------------------------------------------------------------------------- 
3042 void wxWin32Renderer::GetComboBitmaps(wxBitmap 
*bmpNormal
, 
3044                                       wxBitmap 
*bmpPressed
, 
3045                                       wxBitmap 
*bmpDisabled
) 
3047     static const wxCoord widthCombo 
= 16; 
3048     static const wxCoord heightCombo 
= 17; 
3054         bmpNormal
->Create(widthCombo
, heightCombo
); 
3055         dcMem
.SelectObject(*bmpNormal
); 
3056         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
3057                         Arrow_Down
, Arrow_Normal
); 
3062         bmpPressed
->Create(widthCombo
, heightCombo
); 
3063         dcMem
.SelectObject(*bmpPressed
); 
3064         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
3065                         Arrow_Down
, Arrow_Pressed
); 
3070         bmpDisabled
->Create(widthCombo
, heightCombo
); 
3071         dcMem
.SelectObject(*bmpDisabled
); 
3072         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
3073                         Arrow_Down
, Arrow_Disabled
); 
3077 // ---------------------------------------------------------------------------- 
3079 // ---------------------------------------------------------------------------- 
3081 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
, 
3082                                        const wxColour
& col
, 
3085     wxBrush 
brush(col
, wxSOLID
); 
3087     dc
.SetPen(*wxTRANSPARENT_PEN
); 
3088     dc
.DrawRectangle(rect
); 
3091 void wxWin32Renderer::DrawBackground(wxDC
& dc
, 
3092                                      const wxColour
& col
, 
3096     // just fill it with the given or default bg colour 
3097     wxColour colBg 
= col
.Ok() ? col 
: wxSCHEME_COLOUR(m_scheme
, CONTROL
); 
3098     DoDrawBackground(dc
, colBg
, rect
); 
3101 // ---------------------------------------------------------------------------- 
3103 // ---------------------------------------------------------------------------- 
3105 void wxWin32Renderer::DrawArrow(wxDC
& dc
, 
3110     // get the bitmap for this arrow 
3111     wxArrowDirection arrowDir
; 
3114         case wxLEFT
:    arrowDir 
= Arrow_Left
; break; 
3115         case wxRIGHT
:   arrowDir 
= Arrow_Right
; break; 
3116         case wxUP
:      arrowDir 
= Arrow_Up
; break; 
3117         case wxDOWN
:    arrowDir 
= Arrow_Down
; break; 
3120             wxFAIL_MSG(_T("unknown arrow direction")); 
3124     wxArrowStyle arrowStyle
; 
3125     if ( flags 
& wxCONTROL_PRESSED 
) 
3127         // can't be pressed and disabled 
3128         arrowStyle 
= Arrow_Pressed
; 
3132         arrowStyle 
= flags 
& wxCONTROL_DISABLED 
? Arrow_Disabled 
: Arrow_Normal
; 
3135     DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
); 
3138 void wxWin32Renderer::DrawArrow(wxDC
& dc
, 
3140                                 wxArrowDirection arrowDir
, 
3141                                 wxArrowStyle arrowStyle
) 
3143     const wxBitmap
& bmp 
= m_bmpArrows
[arrowStyle
][arrowDir
]; 
3145     // under Windows the arrows always have the same size so just centre it in 
3146     // the provided rectangle 
3147     wxCoord x 
= rect
.x 
+ (rect
.width 
- bmp
.GetWidth()) / 2, 
3148             y 
= rect
.y 
+ (rect
.height 
- bmp
.GetHeight()) / 2; 
3150     // Windows does it like this... 
3151     if ( arrowDir 
== Arrow_Left 
) 
3155     dc
.DrawBitmap(bmp
, x
, y
, TRUE 
/* use mask */); 
3158 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
, 
3159                                       const wxRect
& rectAll
, 
3160                                       wxArrowDirection arrowDir
, 
3161                                       wxArrowStyle arrowStyle
) 
3163     wxRect rect 
= rectAll
; 
3164     DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
); 
3165     DrawArrowBorder(dc
, &rect
, arrowStyle 
== Arrow_Pressed
); 
3166     DrawArrow(dc
, rect
, arrowDir
, arrowStyle
); 
3169 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
, 
3170                                          wxOrientation orient
, 
3174     // we don't use the flags, the thumb never changes appearance 
3175     wxRect rectThumb 
= rect
; 
3176     DrawArrowBorder(dc
, &rectThumb
); 
3177     DrawBackground(dc
, wxNullColour
, rectThumb
); 
3180 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
, 
3181                                          wxOrientation orient
, 
3182                                          const wxRect
& rectBar
, 
3185     wxColourScheme::StdColour col 
= flags 
& wxCONTROL_PRESSED
 
3186                                     ? wxColourScheme::SCROLLBAR_PRESSED
 
3187                                     : wxColourScheme::SCROLLBAR
; 
3188     DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
); 
3191 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
) 
3193     DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
); 
3196 wxRect 
wxWin32Renderer::GetScrollbarRect(const wxScrollBar 
*scrollbar
, 
3197                                          wxScrollBar::Element elem
, 
3200     return StandardGetScrollbarRect(scrollbar
, elem
, 
3201                                     thumbPos
, m_sizeScrollbarArrow
); 
3204 wxCoord 
wxWin32Renderer::GetScrollbarSize(const wxScrollBar 
*scrollbar
) 
3206     return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
); 
3209 wxHitTest 
wxWin32Renderer::HitTestScrollbar(const wxScrollBar 
*scrollbar
, 
3210                                             const wxPoint
& pt
) const 
3212     return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
); 
3215 wxCoord 
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar 
*scrollbar
, 
3218     return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
); 
3221 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar 
*scrollbar
, 
3224     return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
); 
3227 // ---------------------------------------------------------------------------- 
3228 // top level windows 
3229 // ---------------------------------------------------------------------------- 
3231 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const 
3233     wxRect client 
= GetFrameClientArea(rect
, flags
); 
3235     if ( client
.Inside(pt
) ) 
3236         return wxHT_TOPLEVEL_CLIENT_AREA
; 
3238     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3240         wxRect client 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3242         if ( flags 
& wxTOPLEVEL_ICON 
) 
3244             if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) ) 
3245                 return wxHT_TOPLEVEL_ICON
; 
3248         wxRect 
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
, 
3249                        client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2, 
3250                        FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
); 
3252         if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
3254             if ( btnRect
.Inside(pt
) ) 
3255                 return wxHT_TOPLEVEL_BUTTON_CLOSE
; 
3256             btnRect
.x 
-= FRAME_BUTTON_WIDTH 
+ 2; 
3258         if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
3260             if ( btnRect
.Inside(pt
) ) 
3261                 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
; 
3262             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
3264         if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
3266             if ( btnRect
.Inside(pt
) ) 
3267                 return wxHT_TOPLEVEL_BUTTON_RESTORE
; 
3268             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
3270         if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
3272             if ( btnRect
.Inside(pt
) ) 
3273                 return wxHT_TOPLEVEL_BUTTON_ICONIZE
; 
3274             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
3276         if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
3278             if ( btnRect
.Inside(pt
) ) 
3279                 return wxHT_TOPLEVEL_BUTTON_HELP
; 
3280             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
3283         if ( pt
.y 
>= client
.y 
&& pt
.y 
< client
.y 
+ FRAME_TITLEBAR_HEIGHT 
) 
3284             return wxHT_TOPLEVEL_TITLEBAR
; 
3287     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3289         // we are certainly at one of borders, lets decide which one: 
3292         // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined! 
3293         if ( pt
.x 
< client
.x 
) 
3294             border 
|= wxHT_TOPLEVEL_BORDER_W
; 
3295         else if ( pt
.x 
>= client
.width 
+ client
.x 
) 
3296             border 
|= wxHT_TOPLEVEL_BORDER_E
; 
3297         if ( pt
.y 
< client
.y 
) 
3298             border 
|= wxHT_TOPLEVEL_BORDER_N
; 
3299         else if ( pt
.y 
>= client
.height 
+ client
.y 
) 
3300             border 
|= wxHT_TOPLEVEL_BORDER_S
; 
3304     return wxHT_NOWHERE
; 
3307 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
, 
3309                                         const wxString
& title
, 
3313                                         int specialButtonFlags
) 
3315     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3317         DrawFrameBorder(dc
, rect
, flags
); 
3319     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3321         DrawFrameBackground(dc
, rect
, flags
); 
3322         if ( flags 
& wxTOPLEVEL_ICON 
) 
3323             DrawFrameIcon(dc
, rect
, icon
, flags
); 
3324         DrawFrameTitle(dc
, rect
, title
, flags
); 
3326         wxRect client 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3328         x 
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
; 
3329         y 
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2; 
3331         if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
3333             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
, 
3334                             (specialButton 
== wxTOPLEVEL_BUTTON_CLOSE
) ? 
3335                             specialButtonFlags 
: 0); 
3336             x 
-= FRAME_BUTTON_WIDTH 
+ 2; 
3338         if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
3340             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
, 
3341                             (specialButton 
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ? 
3342                             specialButtonFlags 
: 0); 
3343             x 
-= FRAME_BUTTON_WIDTH
; 
3345         if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
3347             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
, 
3348                             (specialButton 
== wxTOPLEVEL_BUTTON_RESTORE
) ? 
3349                             specialButtonFlags 
: 0); 
3350             x 
-= FRAME_BUTTON_WIDTH
; 
3352         if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
3354             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
, 
3355                             (specialButton 
== wxTOPLEVEL_BUTTON_ICONIZE
) ? 
3356                             specialButtonFlags 
: 0); 
3357             x 
-= FRAME_BUTTON_WIDTH
; 
3359         if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
3361             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
, 
3362                             (specialButton 
== wxTOPLEVEL_BUTTON_HELP
) ? 
3363                             specialButtonFlags 
: 0); 
3364             x 
-= FRAME_BUTTON_WIDTH
; 
3369 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
, 
3373     if ( !(flags 
& wxTOPLEVEL_BORDER
) ) return; 
3377     DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
); 
3378     DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
); 
3379     DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
); 
3380     if ( flags 
& wxTOPLEVEL_RESIZEABLE 
) 
3381         DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
); 
3384 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
, 
3388     if ( !(flags 
& wxTOPLEVEL_TITLEBAR
) ) return; 
3390     wxColour col 
= (flags 
& wxTOPLEVEL_ACTIVE
) ? 
3391                    wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) : 
3392                    wxSCHEME_COLOUR(m_scheme
, TITLEBAR
); 
3394     wxRect r 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3395     r
.height 
= FRAME_TITLEBAR_HEIGHT
; 
3397     DrawBackground(dc
, col
, r
); 
3400 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
, 
3402                                      const wxString
& title
, 
3405     wxColour col 
= (flags 
& wxTOPLEVEL_ACTIVE
) ? 
3406                    wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) : 
3407                    wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
); 
3409     wxRect r 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3410     r
.height 
= FRAME_TITLEBAR_HEIGHT
; 
3411     if ( flags 
& wxTOPLEVEL_ICON 
) 
3412         r
.x 
+= FRAME_TITLEBAR_HEIGHT
; 
3416     dc
.SetFont(m_titlebarFont
); 
3417     dc
.SetTextForeground(col
); 
3418     dc
.DrawLabel(title
, wxNullBitmap
, r
, wxALIGN_LEFT 
| wxALIGN_CENTRE_VERTICAL
); 
3421 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
, 
3428         wxRect r 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3429         dc
.DrawIcon(icon
, r
.x
, r
.y
); 
3433 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
, 
3434                                       wxCoord x
, wxCoord y
, 
3438     wxRect 
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
); 
3443         case wxTOPLEVEL_BUTTON_CLOSE
:    idx 
= FrameButton_Close
; break; 
3444         case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx 
= FrameButton_Maximize
; break; 
3445         case wxTOPLEVEL_BUTTON_ICONIZE
: idx 
= FrameButton_Minimize
; break; 
3446         case wxTOPLEVEL_BUTTON_RESTORE
:  idx 
= FrameButton_Restore
; break; 
3447         case wxTOPLEVEL_BUTTON_HELP
:     idx 
= FrameButton_Help
; break; 
3449             wxFAIL_MSG(wxT("incorrect button specification")); 
3452     if ( flags 
& wxCONTROL_PRESSED 
) 
3454         DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
); 
3455         DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
); 
3456         DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
); 
3457         dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
); 
3461         DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
); 
3462         DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
); 
3463         DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
); 
3464         dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
); 
3469 wxRect 
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
, 
3474     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3476         int border 
= (flags 
& wxTOPLEVEL_RESIZEABLE
) ? 
3477                         RESIZEABLE_FRAME_BORDER_THICKNESS 
: 
3478                         FRAME_BORDER_THICKNESS
; 
3481     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3483         r
.y 
+= FRAME_TITLEBAR_HEIGHT
; 
3484         r
.height 
-= FRAME_TITLEBAR_HEIGHT
; 
3490 wxSize 
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
, 
3493     wxSize 
s(clientSize
); 
3495     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3497         int border 
= (flags 
& wxTOPLEVEL_RESIZEABLE
) ? 
3498                         RESIZEABLE_FRAME_BORDER_THICKNESS 
: 
3499                         FRAME_BORDER_THICKNESS
; 
3503     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3504         s
.y 
+= FRAME_TITLEBAR_HEIGHT
; 
3509 wxSize 
wxWin32Renderer::GetFrameIconSize() const 
3511     return wxSize(16, 16); 
3515 // ---------------------------------------------------------------------------- 
3517 // ---------------------------------------------------------------------------- 
3519 static char *error_xpm
[]={ 
3526 "...........########.............", 
3527 "........###aaaaaaaa###..........", 
3528 ".......#aaaaaaaaaaaaaa#.........", 
3529 ".....##aaaaaaaaaaaaaaaa##.......", 
3530 "....#aaaaaaaaaaaaaaaaaaaa#......", 
3531 "...#aaaaaaaaaaaaaaaaaaaaaa#.....", 
3532 "...#aaaaaaaaaaaaaaaaaaaaaa#b....", 
3533 "..#aaaaaacaaaaaaaaaacaaaaaa#b...", 
3534 ".#aaaaaacccaaaaaaaacccaaaaaa#...", 
3535 ".#aaaaacccccaaaaaacccccaaaaa#b..", 
3536 ".#aaaaaacccccaaaacccccaaaaaa#bb.", 
3537 "#aaaaaaaacccccaacccccaaaaaaaa#b.", 
3538 "#aaaaaaaaaccccccccccaaaaaaaaa#b.", 
3539 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb", 
3540 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb", 
3541 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb", 
3542 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb", 
3543 "#aaaaaaaaaccccccccccaaaaaaaaa#bb", 
3544 "#aaaaaaaacccccaacccccaaaaaaaa#bb", 
3545 ".#aaaaaacccccaaaacccccaaaaaa#bbb", 
3546 ".#aaaaacccccaaaaaacccccaaaaa#bbb", 
3547 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.", 
3548 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.", 
3549 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.", 
3550 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..", 
3551 "....#aaaaaaaaaaaaaaaaaaaa#bbb...", 
3552 ".....##aaaaaaaaaaaaaaaa##bbbb...", 
3553 "......b#aaaaaaaaaaaaaa#bbbbb....", 
3554 ".......b###aaaaaaaa###bbbbb.....", 
3555 ".........bb########bbbbbb.......", 
3556 "..........bbbbbbbbbbbbbb........", 
3557 ".............bbbbbbbb..........."}; 
3559 static char *info_xpm
[]={ 
3567 "...........########.............", 
3568 "........###abbbbbba###..........", 
3569 "......##abbbbbbbbbbbba##........", 
3570 ".....#abbbbbbbbbbbbbbbba#.......", 
3571 "....#bbbbbbbaccccabbbbbbbd......", 
3572 "...#bbbbbbbbccccccbbbbbbbbd.....", 
3573 "..#bbbbbbbbbccccccbbbbbbbbbd....", 
3574 ".#abbbbbbbbbaccccabbbbbbbbbad...", 
3575 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..", 
3576 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.", 
3577 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.", 
3578 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", 
3579 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", 
3580 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", 
3581 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", 
3582 "#abbbbbbbbbbbcccccbbbbbbbbbbad##", 
3583 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###", 
3584 ".#abbbbbbbbbbcccccbbbbbbbbbad###", 
3585 "..#bbbbbbbbcccccccccbbbbbbbd###.", 
3586 "...dbbbbbbbbbbbbbbbbbbbbbbd####.", 
3587 "....dbbbbbbbbbbbbbbbbbbbbd####..", 
3588 ".....dabbbbbbbbbbbbbbbbad####...", 
3589 "......ddabbbbbbbbbbbbadd####....", 
3590 ".......#dddabbbbbbaddd#####.....", 
3591 "........###dddabbbd#######......", 
3592 "..........####dbbbd#####........", 
3593 ".............#dbbbd##...........", 
3594 "...............dbbd##...........", 
3595 "................dbd##...........", 
3596 ".................dd##...........", 
3597 "..................###...........", 
3598 "...................##..........."}; 
3600 static char *question_xpm
[]={ 
3608 "...........########.............", 
3609 "........###abbbbbba###..........", 
3610 "......##abbbbbbbbbbbba##........", 
3611 ".....#abbbbbbbbbbbbbbbba#.......", 
3612 "....#bbbbbbbbbbbbbbbbbbbbc......", 
3613 "...#bbbbbbbaddddddabbbbbbbc.....", 
3614 "..#bbbbbbbadabbddddabbbbbbbc....", 
3615 ".#abbbbbbbddbbbbddddbbbbbbbac...", 
3616 ".#bbbbbbbbddddbbddddbbbbbbbbc#..", 
3617 "#abbbbbbbbddddbaddddbbbbbbbbac#.", 
3618 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.", 
3619 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##", 
3620 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##", 
3621 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##", 
3622 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##", 
3623 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##", 
3624 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###", 
3625 ".#abbbbbbbbbbddddbbbbbbbbbbac###", 
3626 "..#bbbbbbbbbbddddbbbbbbbbbbc###.", 
3627 "...cbbbbbbbbbaddabbbbbbbbbc####.", 
3628 "....cbbbbbbbbbbbbbbbbbbbbc####..", 
3629 ".....cabbbbbbbbbbbbbbbbac####...", 
3630 "......ccabbbbbbbbbbbbacc####....", 
3631 ".......#cccabbbbbbaccc#####.....", 
3632 "........###cccabbbc#######......", 
3633 "..........####cbbbc#####........", 
3634 ".............#cbbbc##...........", 
3635 "...............cbbc##...........", 
3636 "................cbc##...........", 
3637 ".................cc##...........", 
3638 "..................###...........", 
3639 "...................##..........."}; 
3641 static char *warning_xpm
[]={ 
3649 ".............###................", 
3650 "............#aabc...............", 
3651 "...........#aaaabcd.............", 
3652 "...........#aaaaacdd............", 
3653 "..........#aaaaaabcdd...........", 
3654 "..........#aaaaaaacdd...........", 
3655 ".........#aaaaaaaabcdd..........", 
3656 ".........#aaaaaaaaacdd..........", 
3657 "........#aaaaaaaaaabcdd.........", 
3658 "........#aaabcccbaaacdd.........", 
3659 ".......#aaaacccccaaabcdd........", 
3660 ".......#aaaacccccaaaacdd........", 
3661 "......#aaaaacccccaaaabcdd.......", 
3662 "......#aaaaacccccaaaaacdd.......", 
3663 ".....#aaaaaacccccaaaaabcdd......", 
3664 ".....#aaaaaa#ccc#aaaaaacdd......", 
3665 "....#aaaaaaabcccbaaaaaabcdd.....", 
3666 "....#aaaaaaaacccaaaaaaaacdd.....", 
3667 "...#aaaaaaaaa#c#aaaaaaaabcdd....", 
3668 "...#aaaaaaaaabcbaaaaaaaaacdd....", 
3669 "..#aaaaaaaaaaacaaaaaaaaaabcdd...", 
3670 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...", 
3671 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..", 
3672 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..", 
3673 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.", 
3674 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.", 
3675 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd", 
3676 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd", 
3677 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd", 
3678 "..#ccccccccccccccccccccccccddddd", 
3679 "....ddddddddddddddddddddddddddd.", 
3680 ".....ddddddddddddddddddddddddd.."}; 
3682 wxIcon 
wxWin32Renderer::GetStdIcon(int which
) const 
3686         case wxICON_INFORMATION
: 
3687             return wxIcon(info_xpm
); 
3689         case wxICON_QUESTION
: 
3690             return wxIcon(question_xpm
); 
3692         case wxICON_EXCLAMATION
: 
3693             return wxIcon(warning_xpm
); 
3696             wxFAIL_MSG(wxT("requested non existent standard icon")); 
3697             // still fall through 
3700             return wxIcon(error_xpm
); 
3705 // ---------------------------------------------------------------------------- 
3706 // text control geometry 
3707 // ---------------------------------------------------------------------------- 
3709 static inline int GetTextBorderWidth() 
3714 wxRect 
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl 
*text
, 
3717     wxRect rectTotal 
= rect
; 
3719     wxCoord widthBorder 
= GetTextBorderWidth(); 
3720     rectTotal
.Inflate(widthBorder
); 
3722     // this is what Windows does 
3728 wxRect 
wxWin32Renderer::GetTextClientArea(const wxTextCtrl 
*text
, 
3730                                           wxCoord 
*extraSpaceBeyond
) 
3732     wxRect rectText 
= rect
; 
3734     // undo GetTextTotalArea() 
3735     if ( rectText
.height 
> 0 ) 
3738     wxCoord widthBorder 
= GetTextBorderWidth(); 
3739     rectText
.Inflate(-widthBorder
); 
3741     if ( extraSpaceBeyond 
) 
3742         *extraSpaceBeyond 
= 0; 
3747 // ---------------------------------------------------------------------------- 
3749 // ---------------------------------------------------------------------------- 
3751 void wxWin32Renderer::AdjustSize(wxSize 
*size
, const wxWindow 
*window
) 
3754     if ( wxDynamicCast(window
, wxScrollBar
) ) 
3756         // we only set the width of vert scrollbars and height of the 
3758         if ( window
->GetWindowStyle() & wxSB_HORIZONTAL 
) 
3759             size
->y 
= m_sizeScrollbarArrow
.y
; 
3761             size
->x 
= m_sizeScrollbarArrow
.x
; 
3763         // skip border width adjustments, they don't make sense for us 
3766 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR 
3769     if ( wxDynamicCast(window
, wxButton
) ) 
3771         if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) ) 
3773             // TODO: don't harcode all this 
3774             size
->x 
+= 3*window
->GetCharWidth(); 
3776             wxCoord heightBtn 
= (11*(window
->GetCharHeight() + 8))/10; 
3777             if ( size
->y 
< heightBtn 
- 8 ) 
3778                 size
->y 
= heightBtn
; 
3783         // no border width adjustments for buttons 
3786 #endif // wxUSE_BUTTON 
3788     // take into account the border width 
3789     wxRect rectBorder 
= GetBorderDimensions(window
->GetBorder()); 
3790     size
->x 
+= rectBorder
.x 
+ rectBorder
.width
; 
3791     size
->y 
+= rectBorder
.y 
+ rectBorder
.height
; 
3794 // ============================================================================ 
3796 // ============================================================================ 
3798 // ---------------------------------------------------------------------------- 
3799 // wxWin32InputHandler 
3800 // ---------------------------------------------------------------------------- 
3802 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer 
*renderer
) 
3804     m_renderer 
= renderer
; 
3807 bool wxWin32InputHandler::HandleKey(wxInputConsumer 
*control
, 
3808                                     const wxKeyEvent
& event
, 
3814 bool wxWin32InputHandler::HandleMouse(wxInputConsumer 
*control
, 
3815                                       const wxMouseEvent
& event
) 
3817     // clicking on the control gives it focus 
3818     if ( event
.ButtonDown() ) 
3820         wxWindow 
*win 
= control
->GetInputWindow(); 
3821         if ( wxWindow::FindFocus() != control
->GetInputWindow() ) 
3832 // ---------------------------------------------------------------------------- 
3833 // wxWin32ScrollBarInputHandler 
3834 // ---------------------------------------------------------------------------- 
3836 wxWin32ScrollBarInputHandler:: 
3837 wxWin32ScrollBarInputHandler(wxWin32Renderer 
*renderer
, 
3838                              wxInputHandler 
*handler
) 
3839         : wxStdScrollBarInputHandler(renderer
, handler
) 
3841     m_scrollPaused 
= FALSE
; 
3845 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar 
*scrollbar
, 
3846                                                  const wxControlAction
& action
) 
3848     // stop if went beyond the position of the original click (this can only 
3849     // happen when we scroll by pages) 
3851     if ( action 
== wxACTION_SCROLL_PAGE_DOWN 
) 
3853         stop 
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
) 
3854                 != wxHT_SCROLLBAR_BAR_2
; 
3856     else if ( action 
== wxACTION_SCROLL_PAGE_UP 
) 
3858         stop 
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
) 
3859                 != wxHT_SCROLLBAR_BAR_1
; 
3864         StopScrolling(scrollbar
); 
3866         scrollbar
->Refresh(); 
3871     return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
); 
3874 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer 
*control
, 
3875                                                const wxMouseEvent
& event
) 
3877     // remember the current state 
3878     bool wasDraggingThumb 
= m_htLast 
== wxHT_SCROLLBAR_THUMB
; 
3880     // do process the message 
3881     bool rc 
= wxStdScrollBarInputHandler::HandleMouse(control
, event
); 
3883     // analyse the changes 
3884     if ( !wasDraggingThumb 
&& (m_htLast 
== wxHT_SCROLLBAR_THUMB
) ) 
3886         // we just started dragging the thumb, remember its initial position to 
3887         // be able to restore it if the drag is cancelled later 
3888         m_eventStartDrag 
= event
; 
3894 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer 
*control
, 
3895                                                    const wxMouseEvent
& event
) 
3897     // we don't highlight scrollbar elements, so there is no need to process 
3898     // mouse move events normally - only do it while mouse is captured (i.e. 
3899     // when we're dragging the thumb or pressing on something) 
3900     if ( !m_winCapture 
) 
3903     if ( event
.Entering() ) 
3905         // we're not interested in this at all 
3909     wxScrollBar 
*scrollbar 
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
); 
3911     if ( m_scrollPaused 
) 
3913         // check if the mouse returned to its original location 
3915         if ( event
.Leaving() ) 
3921         ht 
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition()); 
3922         if ( ht 
== m_htLast 
) 
3924             // yes it did, resume scrolling 
3925             m_scrollPaused 
= FALSE
; 
3926             if ( m_timerScroll 
) 
3928                 // we were scrolling by line/page, restart timer 
3929                 m_timerScroll
->Start(m_interval
); 
3931                 Press(scrollbar
, TRUE
); 
3933             else // we were dragging the thumb 
3935                 // restore its last location 
3936                 HandleThumbMove(scrollbar
, m_eventLastDrag
); 
3942     else // normal case, scrolling hasn't been paused 
3944         // if we're scrolling the scrollbar because the arrow or the shaft was 
3945         // pressed, check that the mouse stays on the same scrollbar element 
3947         if ( event
.Moving() ) 
3949             ht 
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition()); 
3951         else // event.Leaving() 
3956         // if we're dragging the thumb and the mouse stays in the scrollbar, it 
3957         // is still ok - we only want to catch the case when the mouse leaves 
3958         // the scrollbar here 
3959         if ( m_htLast 
== wxHT_SCROLLBAR_THUMB 
&& ht 
!= wxHT_NOWHERE 
) 
3961             ht 
= wxHT_SCROLLBAR_THUMB
; 
3964         if ( ht 
!= m_htLast 
) 
3966             // what were we doing? 2 possibilities: either an arrow/shaft was 
3967             // pressed in which case we have a timer and so we just stop it or 
3968             // we were dragging the thumb 
3969             if ( m_timerScroll 
) 
3972                 m_interval 
= m_timerScroll
->GetInterval(); 
3973                 m_timerScroll
->Stop(); 
3974                 m_scrollPaused 
= TRUE
; 
3976                 // unpress the arrow 
3977                 Press(scrollbar
, FALSE
); 
3979             else // we were dragging the thumb 
3981                 // remember the current thumb position to be able to restore it 
3982                 // if the mouse returns to it later 
3983                 m_eventLastDrag 
= event
; 
3985                 // and restore the original position (before dragging) of the 
3987                 HandleThumbMove(scrollbar
, m_eventStartDrag
); 
3994     return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
); 
3997 // ---------------------------------------------------------------------------- 
3998 // wxWin32CheckboxInputHandler 
3999 // ---------------------------------------------------------------------------- 
4001 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer 
*control
, 
4002                                             const wxKeyEvent
& event
, 
4007         wxControlAction action
; 
4008         int keycode 
= event
.GetKeyCode(); 
4012                 action 
= wxACTION_CHECKBOX_TOGGLE
; 
4016             case WXK_NUMPAD_SUBTRACT
: 
4017                 action 
= wxACTION_CHECKBOX_CHECK
; 
4021             case WXK_NUMPAD_ADD
: 
4022             case WXK_NUMPAD_EQUAL
: 
4023                 action 
= wxACTION_CHECKBOX_CLEAR
; 
4029             control
->PerformAction(action
); 
4038 // ---------------------------------------------------------------------------- 
4039 // wxWin32TextCtrlInputHandler 
4040 // ---------------------------------------------------------------------------- 
4042 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer 
*control
, 
4043                                             const wxKeyEvent
& event
, 
4046     // handle only MSW-specific text bindings here, the others are handled in 
4050         int keycode 
= event
.GetKeyCode(); 
4052         wxControlAction action
; 
4053         if ( keycode 
== WXK_DELETE 
&& event
.ShiftDown() ) 
4055             action 
= wxACTION_TEXT_CUT
; 
4057         else if ( keycode 
== WXK_INSERT 
) 
4059             if ( event
.ControlDown() ) 
4060                 action 
= wxACTION_TEXT_COPY
; 
4061             else if ( event
.ShiftDown() ) 
4062                 action 
= wxACTION_TEXT_PASTE
; 
4065         if ( action 
!= wxACTION_NONE 
) 
4067             control
->PerformAction(action
); 
4073     return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
); 
4076 // ---------------------------------------------------------------------------- 
4077 // wxWin32StatusBarInputHandler 
4078 // ---------------------------------------------------------------------------- 
4080 wxWin32StatusBarInputHandler:: 
4081 wxWin32StatusBarInputHandler(wxInputHandler 
*handler
) 
4082     : wxStdInputHandler(handler
) 
4087 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow 
*statbar
, 
4088                                             const wxPoint
& pt
) const 
4090     if ( statbar
->HasFlag(wxST_SIZEGRIP
) && 
4091             statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) ) 
4093         wxSize sizeSbar 
= statbar
->GetSize(); 
4095         return (sizeSbar
.x 
- pt
.x
) < (wxCoord
)STATUSBAR_GRIP_SIZE 
&& 
4096                (sizeSbar
.y 
- pt
.y
) < (wxCoord
)STATUSBAR_GRIP_SIZE
; 
4102 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer 
*consumer
, 
4103                                                const wxMouseEvent
& event
) 
4105     if ( event
.Button(1) ) 
4107         if ( event
.ButtonDown(1) ) 
4109             wxWindow 
*statbar 
= consumer
->GetInputWindow(); 
4111             if ( IsOnGrip(statbar
, event
.GetPosition()) ) 
4113                 wxTopLevelWindow 
*tlw 
= wxDynamicCast(statbar
->GetParent(), 
4117                     tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, 
4118                                        wxHT_TOPLEVEL_BORDER_SE
); 
4120                     statbar
->SetCursor(m_cursorOld
); 
4128     return wxStdInputHandler::HandleMouse(consumer
, event
); 
4131 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer 
*consumer
, 
4132                                                    const wxMouseEvent
& event
) 
4134     wxWindow 
*statbar 
= consumer
->GetInputWindow(); 
4136     bool isOnGrip 
= IsOnGrip(statbar
, event
.GetPosition()); 
4137     if ( isOnGrip 
!= m_isOnGrip 
) 
4139         m_isOnGrip 
= isOnGrip
; 
4142             m_cursorOld 
= statbar
->GetCursor(); 
4143             statbar
->SetCursor(wxCURSOR_SIZENWSE
); 
4147             statbar
->SetCursor(m_cursorOld
); 
4151     return wxStdInputHandler::HandleMouseMove(consumer
, event
);