1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/univ/themes/win32.cpp 
   3 // Purpose:     wxUniversal theme implementing Win32-like LNF 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com) 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // =========================================================================== 
  14 // =========================================================================== 
  16 // --------------------------------------------------------------------------- 
  18 // --------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  27 #include "wx/univ/theme.h" 
  35     #include "wx/window.h" 
  37     #include "wx/dcmemory.h" 
  38     #include "wx/dcclient.h" 
  40     #include "wx/button.h" 
  41     #include "wx/bmpbuttn.h" 
  42     #include "wx/listbox.h" 
  43     #include "wx/checklst.h" 
  44     #include "wx/combobox.h" 
  45     #include "wx/scrolbar.h" 
  46     #include "wx/slider.h" 
  47     #include "wx/textctrl.h" 
  48     #include "wx/toolbar.h" 
  49     #include "wx/statusbr.h" 
  52         // for COLOR_* constants 
  53         #include "wx/msw/private.h" 
  56     #include "wx/settings.h" 
  57     #include "wx/toplevel.h" 
  61 #include "wx/notebook.h" 
  62 #include "wx/spinbutt.h" 
  63 #include "wx/artprov.h" 
  64 #ifdef wxUSE_TOGGLEBTN 
  65 #include "wx/tglbtn.h" 
  66 #endif // wxUSE_TOGGLEBTN 
  68 #include "wx/univ/scrtimer.h" 
  69 #include "wx/univ/stdrend.h" 
  70 #include "wx/univ/inpcons.h" 
  71 #include "wx/univ/inphand.h" 
  72 #include "wx/univ/colschem.h" 
  74 // ---------------------------------------------------------------------------- 
  76 // ---------------------------------------------------------------------------- 
  78 static const int BORDER_THICKNESS 
= 2; 
  80 static const size_t NUM_STATUSBAR_GRIP_BANDS 
= 3; 
  81 static const size_t WIDTH_STATUSBAR_GRIP_BAND 
= 4; 
  82 static const size_t STATUSBAR_GRIP_SIZE 
= 
  83     WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
; 
  85 static const wxCoord SLIDER_MARGIN 
= 6; // margin around slider 
  86 static const wxCoord SLIDER_THUMB_LENGTH 
= 18; 
  87 static const wxCoord SLIDER_TICK_LENGTH 
= 6; 
  89 // wxWin32Renderer: draw the GUI elements in Win32 style 
  90 // ---------------------------------------------------------------------------- 
  92 class wxWin32Renderer 
: public wxStdRenderer
 
  96     wxWin32Renderer(const wxColourScheme 
*scheme
); 
  98     // reimplement the renderer methods which are different for this theme 
  99     virtual void DrawLabel(wxDC
& dc
, 
 100                            const wxString
& label
, 
 103                            int alignment 
= wxALIGN_LEFT 
| wxALIGN_TOP
, 
 105                            wxRect 
*rectBounds 
= NULL
); 
 106     virtual void DrawButtonLabel(wxDC
& dc
, 
 107                                  const wxString
& label
, 
 108                                  const wxBitmap
& image
, 
 111                                  int alignment 
= wxALIGN_LEFT 
| wxALIGN_TOP
, 
 113                                  wxRect 
*rectBounds 
= NULL
); 
 114     virtual void DrawButtonBorder(wxDC
& dc
, 
 117                                   wxRect 
*rectIn 
= NULL
); 
 119     virtual void DrawArrow(wxDC
& dc
, 
 123     virtual void DrawScrollbarThumb(wxDC
& dc
, 
 124                                     wxOrientation orient
, 
 127     virtual void DrawScrollbarShaft(wxDC
& dc
, 
 128                                     wxOrientation orient
, 
 133     virtual void DrawToolBarButton(wxDC
& dc
, 
 134                                    const wxString
& label
, 
 135                                    const wxBitmap
& bitmap
, 
 140 #endif // wxUSE_TOOLBAR 
 143     virtual void DrawTab(wxDC
& dc
, 
 146                          const wxString
& label
, 
 147                          const wxBitmap
& bitmap 
= wxNullBitmap
, 
 149                          int indexAccel 
= -1); 
 150 #endif // wxUSE_NOTEBOOK 
 153     virtual void DrawSliderShaft(wxDC
& dc
, 
 156                                  wxOrientation orient
, 
 159                                  wxRect 
*rectShaft 
= NULL
); 
 160     virtual void DrawSliderThumb(wxDC
& dc
, 
 162                                  wxOrientation orient
, 
 165     virtual void DrawSliderTicks(wxDC
& dc
, 
 168                                  wxOrientation orient
, 
 174 #endif // wxUSE_SLIDER 
 177     virtual void DrawMenuBarItem(wxDC
& dc
, 
 179                                  const wxString
& label
, 
 181                                  int indexAccel 
= -1); 
 182     virtual void DrawMenuItem(wxDC
& dc
, 
 184                               const wxMenuGeometryInfo
& geometryInfo
, 
 185                               const wxString
& label
, 
 186                               const wxString
& accel
, 
 187                               const wxBitmap
& bitmap 
= wxNullBitmap
, 
 189                               int indexAccel 
= -1); 
 190     virtual void DrawMenuSeparator(wxDC
& dc
, 
 192                                    const wxMenuGeometryInfo
& geomInfo
); 
 193 #endif // wxUSE_MENUS 
 196     virtual void DrawStatusField(wxDC
& dc
, 
 198                                  const wxString
& label
, 
 199                                  int flags 
= 0, int style 
= 0); 
 200 #endif // wxUSE_STATUSBAR 
 202     virtual void GetComboBitmaps(wxBitmap 
*bmpNormal
, 
 204                                  wxBitmap 
*bmpPressed
, 
 205                                  wxBitmap 
*bmpDisabled
); 
 207     virtual void AdjustSize(wxSize 
*size
, const wxWindow 
*window
); 
 208     virtual bool AreScrollbarsInsideBorder() const; 
 210     virtual wxSize 
GetScrollbarArrowSize() const 
 211         { return m_sizeScrollbarArrow
; } 
 213     virtual wxSize 
GetCheckBitmapSize() const 
 214         { return wxSize(13, 13); } 
 215     virtual wxSize 
GetRadioBitmapSize() const 
 216         { return wxSize(12, 12); } 
 217     virtual wxCoord 
GetCheckItemMargin() const 
 221     virtual wxSize 
GetToolBarButtonSize(wxCoord 
*separator
) const 
 222         { if ( separator 
) *separator 
= 5; return wxSize(16, 15); } 
 223     virtual wxSize 
GetToolBarMargin() const 
 224         { return wxSize(4, 4); } 
 225 #endif // wxUSE_TOOLBAR 
 228     virtual wxRect 
GetTextTotalArea(const wxTextCtrl 
*text
, 
 229                                     const wxRect
& rect
) const; 
 230     virtual wxRect 
GetTextClientArea(const wxTextCtrl 
*text
, 
 232                                      wxCoord 
*extraSpaceBeyond
) const; 
 233 #endif // wxUSE_TEXTCTRL 
 236     virtual wxSize 
GetTabIndent() const { return wxSize(2, 2); } 
 237     virtual wxSize 
GetTabPadding() const { return wxSize(6, 5); } 
 238 #endif // wxUSE_NOTEBOOK 
 242     virtual wxCoord 
GetSliderDim() const { return SLIDER_THUMB_LENGTH 
+ 2*BORDER_THICKNESS
; } 
 243     virtual wxCoord 
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; } 
 244     virtual wxRect 
GetSliderShaftRect(const wxRect
& rect
, 
 246                                       wxOrientation orient
, 
 247                                       long style 
= 0) const; 
 248     virtual wxSize 
GetSliderThumbSize(const wxRect
& rect
, 
 250                                       wxOrientation orient
) const; 
 251 #endif // wxUSE_SLIDER 
 253     virtual wxSize 
GetProgressBarStep() const { return wxSize(16, 32); } 
 256     virtual wxSize 
GetMenuBarItemSize(const wxSize
& sizeText
) const; 
 257     virtual wxMenuGeometryInfo 
*GetMenuGeometry(wxWindow 
*win
, 
 258                                                 const wxMenu
& menu
) const; 
 259 #endif // wxUSE_MENUS 
 262     // overridden wxStdRenderer methods 
 263     virtual void DrawFrameWithLabel(wxDC
& dc
, 
 264                                     const wxString
& label
, 
 265                                     const wxRect
& rectFrame
, 
 266                                     const wxRect
& rectText
, 
 271     virtual void DrawCheckItemBitmap(wxDC
& dc
, 
 272                                      const wxBitmap
& bitmap
, 
 277     // draw the border used for scrollbar arrows 
 278     void DrawArrowBorder(wxDC
& dc
, wxRect 
*rect
, bool isPressed 
= false); 
 280     // public DrawArrow()s helper 
 281     void DrawArrow(wxDC
& dc
, const wxRect
& rect
, 
 282                    ArrowDirection arrowDir
, ArrowStyle arrowStyle
); 
 284     // DrawArrowButton is used by DrawScrollbar and DrawComboButton 
 285     void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
, 
 286                          ArrowDirection arrowDir
, 
 287                          ArrowStyle arrowStyle
); 
 289     // draw a normal or transposed line (useful for using the same code fo both 
 290     // horizontal and vertical widgets) 
 291     void DrawLine(wxDC
& dc
, 
 292                   wxCoord x1
, wxCoord y1
, 
 293                   wxCoord x2
, wxCoord y2
, 
 294                   bool transpose 
= false) 
 297             dc
.DrawLine(y1
, x1
, y2
, x2
); 
 299             dc
.DrawLine(x1
, y1
, x2
, y2
); 
 302     // get the standard check/radio button bitmap 
 303     wxBitmap 
GetIndicator(IndicatorType indType
, int flags
); 
 304     virtual wxBitmap 
GetCheckBitmap(int flags
) 
 305         { return GetIndicator(IndicatorType_Check
, flags
); } 
 306     virtual wxBitmap 
GetRadioBitmap(int flags
) 
 307         { return GetIndicator(IndicatorType_Radio
, flags
); } 
 309     virtual wxBitmap 
GetFrameButtonBitmap(FrameButtonType type
); 
 312     // Fill the arguments with true or false if this slider has labels on 
 313     // left/right side (or top/bottom for horizontal sliders) respectively 
 315     void GetSliderLabelsSides(wxOrientation orient
, long style
, 
 316                               bool *left
, bool *right
) 
 318         // should we draw ticks at all? 
 319         if ( !(style 
& wxSL_AUTOTICKS
) ) 
 326         // should we draw them on both sides? 
 327         if ( style 
& wxSL_BOTH 
) 
 334         // we draw them on one side only, determine which one 
 335         if ( ((style 
& wxSL_TOP
) && (orient 
== wxHORIZONTAL
)) || 
 336                 ((style 
& wxSL_LEFT
) && (orient 
== wxVERTICAL
)) ) 
 341         else if ( ((style 
& wxSL_BOTTOM
) && (orient 
== wxHORIZONTAL
)) || 
 342                     ((style 
& wxSL_RIGHT
) && (orient 
== wxVERTICAL
)) ) 
 349             wxFAIL_MSG( "inconsistent wxSlider flags" ); 
 355 #endif // wxUSE_SLIDER 
 358     // the sizing parameters (TODO make them changeable) 
 359     wxSize m_sizeScrollbarArrow
; 
 361     // the checked and unchecked bitmaps for DrawCheckItemBitmap() 
 362     wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
]; 
 364     // the bitmaps returned by GetIndicator() 
 365     wxBitmap m_bmpIndicators
[IndicatorType_Max
] 
 366                             [IndicatorState_MaxMenu
] 
 367                             [IndicatorStatus_Max
]; 
 370     wxBitmap m_bmpFrameButtons
[FrameButton_Max
]; 
 372     // standard defaults for the above bitmaps 
 373     static const char **ms_xpmChecked
[IndicatorStatus_Max
]; 
 374     static const char **ms_xpmIndicators
[IndicatorType_Max
] 
 375                                         [IndicatorState_MaxMenu
] 
 376                                         [IndicatorStatus_Max
]; 
 377     static const char **ms_xpmFrameButtons
[FrameButton_Max
]; 
 379     // first row is for the normal state, second - for the disabled 
 380     wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
]; 
 383 // ---------------------------------------------------------------------------- 
 384 // wxWin32InputHandler and derived classes: process the keyboard and mouse 
 385 // messages according to Windows standards 
 386 // ---------------------------------------------------------------------------- 
 388 class wxWin32InputHandler 
: public wxInputHandler
 
 391     wxWin32InputHandler() { } 
 393     virtual bool HandleKey(wxInputConsumer 
*control
, 
 394                            const wxKeyEvent
& event
, 
 396     virtual bool HandleMouse(wxInputConsumer 
*control
, 
 397                              const wxMouseEvent
& event
); 
 401 class wxWin32ScrollBarInputHandler 
: public wxStdScrollBarInputHandler
 
 404     wxWin32ScrollBarInputHandler(wxRenderer 
*renderer
, 
 405                                  wxInputHandler 
*handler
); 
 407     virtual bool HandleMouse(wxInputConsumer 
*control
, 
 408                              const wxMouseEvent
& event
); 
 409     virtual bool HandleMouseMove(wxInputConsumer 
*control
, 
 410                                  const wxMouseEvent
& event
); 
 412     virtual bool OnScrollTimer(wxScrollBar 
*scrollbar
, 
 413                                const wxControlAction
& action
); 
 416     virtual void Highlight(wxScrollBar 
* WXUNUSED(scrollbar
), 
 419         // we don't highlight anything 
 422     // the first and last event which caused the thumb to move 
 423     wxMouseEvent m_eventStartDrag
, 
 426     // have we paused the scrolling because the mouse moved? 
 429     // we remember the interval of the timer to be able to restart it 
 432 #endif // wxUSE_SCROLLBAR 
 435 class wxWin32CheckboxInputHandler 
: public wxStdInputHandler
 
 438     wxWin32CheckboxInputHandler(wxInputHandler 
*handler
) 
 439         : wxStdInputHandler(handler
) { } 
 441     virtual bool HandleKey(wxInputConsumer 
*control
, 
 442                            const wxKeyEvent
& event
, 
 445 #endif // wxUSE_CHECKBOX 
 448 class wxWin32TextCtrlInputHandler 
: public wxStdInputHandler
 
 451     wxWin32TextCtrlInputHandler(wxInputHandler 
*handler
) 
 452         : wxStdInputHandler(handler
) { } 
 454     virtual bool HandleKey(wxInputConsumer 
*control
, 
 455                            const wxKeyEvent
& event
, 
 458 #endif // wxUSE_TEXTCTRL 
 460 class wxWin32StatusBarInputHandler 
: public wxStdInputHandler
 
 463     wxWin32StatusBarInputHandler(wxInputHandler 
*handler
); 
 465     virtual bool HandleMouse(wxInputConsumer 
*consumer
, 
 466                              const wxMouseEvent
& event
); 
 468     virtual bool HandleMouseMove(wxInputConsumer 
*consumer
, 
 469                                  const wxMouseEvent
& event
); 
 472     // is the given point over the statusbar grip? 
 473     bool IsOnGrip(wxWindow 
*statbar
, const wxPoint
& pt
) const; 
 476     // the cursor we had replaced with the resize one 
 477     wxCursor m_cursorOld
; 
 479     // was the mouse over the grip last time we checked? 
 483 class wxWin32SystemMenuEvtHandler
; 
 485 class wxWin32FrameInputHandler 
: public wxStdInputHandler
 
 488     wxWin32FrameInputHandler(wxInputHandler 
*handler
); 
 489     virtual ~wxWin32FrameInputHandler(); 
 491     virtual bool HandleMouse(wxInputConsumer 
*control
, 
 492                              const wxMouseEvent
& event
); 
 494     virtual bool HandleActivation(wxInputConsumer 
*consumer
, bool activated
); 
 497     void PopupSystemMenu(wxTopLevelWindow 
*window
) const; 
 498 #endif // wxUSE_MENUS 
 501     // was the mouse over the grip last time we checked? 
 502     wxWin32SystemMenuEvtHandler 
*m_menuHandler
; 
 505 // ---------------------------------------------------------------------------- 
 506 // wxWin32ColourScheme: uses (default) Win32 colours 
 507 // ---------------------------------------------------------------------------- 
 509 class wxWin32ColourScheme 
: public wxColourScheme
 
 512     virtual wxColour 
Get(StdColour col
) const; 
 513     virtual wxColour 
GetBackground(wxWindow 
*win
) const; 
 516 // ---------------------------------------------------------------------------- 
 517 // wxWin32ArtProvider 
 518 // ---------------------------------------------------------------------------- 
 520 class wxWin32ArtProvider 
: public wxArtProvider
 
 523     virtual wxBitmap 
CreateBitmap(const wxArtID
& id
, 
 524                                   const wxArtClient
& client
, 
 528 // ---------------------------------------------------------------------------- 
 530 // ---------------------------------------------------------------------------- 
 532 WX_DEFINE_ARRAY_PTR(wxInputHandler 
*, wxArrayHandlers
); 
 534 class wxWin32Theme 
: public wxTheme
 
 538     virtual ~wxWin32Theme(); 
 540     virtual wxRenderer 
*GetRenderer(); 
 541     virtual wxArtProvider 
*GetArtProvider(); 
 542     virtual wxInputHandler 
*GetInputHandler(const wxString
& control
, 
 543                                             wxInputConsumer 
*consumer
); 
 544     virtual wxColourScheme 
*GetColourScheme(); 
 547     wxWin32Renderer 
*m_renderer
; 
 549     wxWin32ArtProvider 
*m_artProvider
; 
 551     // the names of the already created handlers and the handlers themselves 
 552     // (these arrays are synchronized) 
 553     wxSortedArrayString m_handlerNames
; 
 554     wxArrayHandlers m_handlers
; 
 556     wxWin32ColourScheme 
*m_scheme
; 
 558     WX_DECLARE_THEME(win32
) 
 561 // ---------------------------------------------------------------------------- 
 563 // ---------------------------------------------------------------------------- 
 565 // frame buttons bitmaps 
 566 static const char *frame_button_close_xpm
[] = { 
 581 static const char *frame_button_help_xpm
[] = { 
 596 static const char *frame_button_maximize_xpm
[] = { 
 611 static const char *frame_button_minimize_xpm
[] = { 
 626 static const char *frame_button_restore_xpm
[] = { 
 641 const char **wxWin32Renderer::ms_xpmFrameButtons
[FrameButton_Max
] = 
 643     frame_button_close_xpm
, 
 644     frame_button_minimize_xpm
, 
 645     frame_button_maximize_xpm
, 
 646     frame_button_restore_xpm
, 
 647     frame_button_help_xpm
, 
 652 static const char *checked_menu_xpm
[] = { 
 653 /* columns rows colors chars-per-pixel */ 
 669 static const char *selected_checked_menu_xpm
[] = { 
 670 /* columns rows colors chars-per-pixel */ 
 686 static const char *disabled_checked_menu_xpm
[] = { 
 687 /* columns rows colors chars-per-pixel */ 
 704 static const char *selected_disabled_checked_menu_xpm
[] = { 
 705 /* columns rows colors chars-per-pixel */ 
 721 // checkbox and radiobox bitmaps below 
 723 static const char *checked_xpm
[] = { 
 724 /* columns rows colors chars-per-pixel */ 
 747 static const char *pressed_checked_xpm
[] = { 
 748 /* columns rows colors chars-per-pixel */ 
 770 static const char *pressed_disabled_checked_xpm
[] = { 
 771 /* columns rows colors chars-per-pixel */ 
 793 static const char *checked_item_xpm
[] = { 
 794 /* columns rows colors chars-per-pixel */ 
 815 static const char *unchecked_xpm
[] = { 
 816 /* columns rows colors chars-per-pixel */ 
 839 static const char *pressed_unchecked_xpm
[] = { 
 840 /* columns rows colors chars-per-pixel */ 
 862 static const char *unchecked_item_xpm
[] = { 
 863 /* columns rows colors chars-per-pixel */ 
 883 static const char *undetermined_xpm
[] = { 
 884 /* columns rows colors chars-per-pixel */ 
 907 static const char *pressed_undetermined_xpm
[] = { 
 908 /* columns rows colors chars-per-pixel */ 
 931 static const char *checked_radio_xpm
[] = { 
 932 /* columns rows colors chars-per-pixel */ 
 955 static const char *pressed_checked_radio_xpm
[] = { 
 956 /* columns rows colors chars-per-pixel */ 
 979 static const char *pressed_disabled_checked_radio_xpm
[] = { 
 980 /* columns rows colors chars-per-pixel */ 
1003 static const char *unchecked_radio_xpm
[] = { 
1004 /* columns rows colors chars-per-pixel */ 
1027 static const char *pressed_unchecked_radio_xpm
[] = { 
1028 /* columns rows colors chars-per-pixel */ 
1051 const char **wxWin32Renderer::ms_xpmIndicators
[IndicatorType_Max
] 
1052                                               [IndicatorState_MaxMenu
] 
1053                                               [IndicatorStatus_Max
] = 
1058         { checked_xpm
, unchecked_xpm
, undetermined_xpm 
}, 
1061         { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm 
}, 
1064         { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm 
}, 
1070         { checked_radio_xpm
, unchecked_radio_xpm
, NULL 
}, 
1073         { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL 
}, 
1076         { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL 
}, 
1082         { checked_menu_xpm
, NULL
, NULL 
}, 
1085         { selected_checked_menu_xpm
, NULL
, NULL 
}, 
1088         { disabled_checked_menu_xpm
, NULL
, NULL 
}, 
1090         // disabled selected state 
1091         { selected_disabled_checked_menu_xpm
, NULL
, NULL 
}, 
1095 const char **wxWin32Renderer::ms_xpmChecked
[IndicatorStatus_Max
] = 
1101 // ============================================================================ 
1103 // ============================================================================ 
1105 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme")); 
1107 // ---------------------------------------------------------------------------- 
1109 // ---------------------------------------------------------------------------- 
1111 wxWin32Theme::wxWin32Theme() 
1115     m_artProvider 
= NULL
; 
1118 wxWin32Theme::~wxWin32Theme() 
1122     delete m_artProvider
; 
1125 wxRenderer 
*wxWin32Theme::GetRenderer() 
1129         m_renderer 
= new wxWin32Renderer(GetColourScheme()); 
1135 wxArtProvider 
*wxWin32Theme::GetArtProvider() 
1137     if ( !m_artProvider 
) 
1139         m_artProvider 
= new wxWin32ArtProvider
; 
1142     return m_artProvider
; 
1146 wxWin32Theme::GetInputHandler(const wxString
& control
, 
1147                               wxInputConsumer 
*consumer
) 
1149     wxInputHandler 
*handler 
= NULL
; 
1150     int n 
= m_handlerNames
.Index(control
); 
1151     if ( n 
== wxNOT_FOUND 
) 
1153         static wxWin32InputHandler s_handlerDef
; 
1155         wxInputHandler 
* const 
1156           handlerStd 
= consumer
->DoGetStdInputHandler(&s_handlerDef
); 
1158         // create a new handler 
1159         if ( control 
== wxINP_HANDLER_TOPLEVEL 
) 
1161             static wxWin32FrameInputHandler 
s_handler(handlerStd
); 
1163             handler 
= &s_handler
; 
1166         else if ( control 
== wxINP_HANDLER_CHECKBOX 
) 
1168             static wxWin32CheckboxInputHandler 
s_handler(handlerStd
); 
1170             handler 
= &s_handler
; 
1172 #endif // wxUSE_CHECKBOX 
1174         else if ( control 
== wxINP_HANDLER_SCROLLBAR 
) 
1176             static wxWin32ScrollBarInputHandler
 
1177                 s_handler(GetRenderer(), handlerStd
); 
1179             handler 
= &s_handler
; 
1181 #endif // wxUSE_SCROLLBAR 
1183         else if ( control 
== wxINP_HANDLER_STATUSBAR 
) 
1185             static wxWin32StatusBarInputHandler 
s_handler(handlerStd
); 
1187             handler 
= &s_handler
; 
1189 #endif // wxUSE_STATUSBAR 
1191         else if ( control 
== wxINP_HANDLER_TEXTCTRL 
) 
1193             static wxWin32TextCtrlInputHandler 
s_handler(handlerStd
); 
1195             handler 
= &s_handler
; 
1197 #endif // wxUSE_TEXTCTRL 
1198         else // no special handler for this control 
1200             handler 
= handlerStd
; 
1203         n 
= m_handlerNames
.Add(control
); 
1204         m_handlers
.Insert(handler
, n
); 
1206     else // we already have it 
1208         handler 
= m_handlers
[n
]; 
1214 wxColourScheme 
*wxWin32Theme::GetColourScheme() 
1218         m_scheme 
= new wxWin32ColourScheme
; 
1223 // ============================================================================ 
1224 // wxWin32ColourScheme 
1225 // ============================================================================ 
1227 wxColour 
wxWin32ColourScheme::GetBackground(wxWindow 
*win
) const 
1230     if ( win
->UseBgCol() ) 
1232         // use the user specified colour 
1233         col 
= win
->GetBackgroundColour(); 
1236     if ( !win
->ShouldInheritColours() ) 
1239         wxTextCtrl 
*text 
= wxDynamicCast(win
, wxTextCtrl
); 
1240 #endif // wxUSE_TEXTCTRL 
1242         wxListBox
* listBox 
= wxDynamicCast(win
, wxListBox
); 
1243 #endif // wxUSE_LISTBOX 
1252             if ( !win
->IsEnabled() ) // not IsEditable() 
1258                     // doesn't depend on the state 
1263 #endif // wxUSE_TEXTCTRL 
1266             col 
= Get(CONTROL
); // Most controls should be this colour, not WINDOW 
1270         int flags 
= win
->GetStateFlags(); 
1272         // the colour set by the user should be used for the normal state 
1273         // and for the states for which we don't have any specific colours 
1274         if ( !col
.IsOk() || (flags 
& wxCONTROL_PRESSED
) != 0 ) 
1277             if ( wxDynamicCast(win
, wxScrollBar
) ) 
1278                 col 
= Get(flags 
& wxCONTROL_PRESSED 
? SCROLLBAR_PRESSED
 
1281 #endif // wxUSE_SCROLLBAR 
1289 wxColour 
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const 
1293         // use the system colours under Windows 
1294 #if defined(__WXMSW__) 
1295         case WINDOW
:            return wxColour(GetSysColor(COLOR_WINDOW
)); 
1297         case CONTROL_PRESSED
: 
1298         case CONTROL_CURRENT
: 
1299         case CONTROL
:           return wxColour(GetSysColor(COLOR_BTNFACE
)); 
1301         case CONTROL_TEXT
:      return wxColour(GetSysColor(COLOR_BTNTEXT
)); 
1303 #if defined(COLOR_3DLIGHT) 
1304         case SCROLLBAR
:         return wxColour(GetSysColor(COLOR_3DLIGHT
)); 
1306         case SCROLLBAR
:         return wxColour(0xe0e0e0); 
1308         case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
)); 
1310         case HIGHLIGHT
:         return wxColour(GetSysColor(COLOR_HIGHLIGHT
)); 
1311         case HIGHLIGHT_TEXT
:    return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
)); 
1313 #if defined(COLOR_3DDKSHADOW) 
1314         case SHADOW_DARK
:       return wxColour(GetSysColor(COLOR_3DDKSHADOW
)); 
1316         case SHADOW_DARK
:       return wxColour(GetSysColor(COLOR_3DHADOW
)); 
1319         case CONTROL_TEXT_DISABLED
: 
1320         case SHADOW_HIGHLIGHT
:  return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
)); 
1322         case SHADOW_IN
:         return wxColour(GetSysColor(COLOR_BTNFACE
)); 
1324         case CONTROL_TEXT_DISABLED_SHADOW
: 
1325         case SHADOW_OUT
:        return wxColour(GetSysColor(COLOR_BTNSHADOW
)); 
1327         case TITLEBAR
:          return wxColour(GetSysColor(COLOR_INACTIVECAPTION
)); 
1328         case TITLEBAR_ACTIVE
:   return wxColour(GetSysColor(COLOR_ACTIVECAPTION
)); 
1329         case TITLEBAR_TEXT
:     return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
)); 
1330         case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
)); 
1332         case DESKTOP
:           return wxColour(0x808000); 
1333         case FRAME
:             return wxColour(GetSysColor(COLOR_APPWORKSPACE
)); 
1335         // use the standard Windows colours elsewhere 
1336         case WINDOW
:            return *wxWHITE
; 
1338         case CONTROL_PRESSED
: 
1339         case CONTROL_CURRENT
: 
1340         case CONTROL
:           return wxColour(0xc0c0c0); 
1342         case CONTROL_TEXT
:      return *wxBLACK
; 
1344         case SCROLLBAR
:         return wxColour(0xe0e0e0); 
1345         case SCROLLBAR_PRESSED
: return *wxBLACK
; 
1347         case HIGHLIGHT
:         return wxColour(0x800000); 
1348         case HIGHLIGHT_TEXT
:    return wxColour(0xffffff); 
1350         case SHADOW_DARK
:       return *wxBLACK
; 
1352         case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0); 
1353         case SHADOW_HIGHLIGHT
:  return wxColour(0xffffff); 
1355         case SHADOW_IN
:         return wxColour(0xc0c0c0); 
1357         case CONTROL_TEXT_DISABLED_SHADOW
: 
1358         case SHADOW_OUT
:        return wxColour(0x7f7f7f); 
1360         case TITLEBAR
:          return wxColour(0xaeaaae); 
1361         case TITLEBAR_ACTIVE
:   return wxColour(0x820300); 
1362         case TITLEBAR_TEXT
:     return wxColour(0xc0c0c0); 
1363         case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
; 
1365         case DESKTOP
:           return wxColour(0x808000); 
1366         case FRAME
:             return wxColour(0x808080); 
1369         case GAUGE
:             return Get(HIGHLIGHT
); 
1373             wxFAIL_MSG(wxT("invalid standard colour")); 
1378 // ============================================================================ 
1380 // ============================================================================ 
1382 // ---------------------------------------------------------------------------- 
1384 // ---------------------------------------------------------------------------- 
1386 wxWin32Renderer::wxWin32Renderer(const wxColourScheme 
*scheme
) 
1387                : wxStdRenderer(scheme
) 
1390     m_sizeScrollbarArrow 
= wxSize(16, 16); 
1392     // init the arrow bitmaps 
1393     static const size_t ARROW_WIDTH 
= 7; 
1394     static const size_t ARROW_LENGTH 
= 4; 
1397     wxMemoryDC dcNormal
, 
1400     for ( size_t n 
= 0; n 
< Arrow_Max
; n
++ ) 
1402         bool isVertical 
= n 
> Arrow_Right
; 
1415         // disabled arrow is larger because of the shadow 
1416         m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
); 
1417         m_bmpArrows
[Arrow_Disabled
][n
].Create(w 
+ 1, h 
+ 1); 
1419         dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]); 
1420         dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]); 
1422         dcNormal
.SetBackground(*wxWHITE_BRUSH
); 
1423         dcDisabled
.SetBackground(*wxWHITE_BRUSH
); 
1427         dcNormal
.SetPen(m_penBlack
); 
1428         dcDisabled
.SetPen(m_penDarkGrey
); 
1430         // calculate the position of the point of the arrow 
1434             x1 
= (ARROW_WIDTH 
- 1)/2; 
1435             y1 
= n 
== Arrow_Up 
? 0 : ARROW_LENGTH 
- 1; 
1439             x1 
= n 
== Arrow_Left 
? 0 : ARROW_LENGTH 
- 1; 
1440             y1 
= (ARROW_WIDTH 
- 1)/2; 
1451         for ( size_t i 
= 0; i 
< ARROW_LENGTH
; i
++ ) 
1453             dcNormal
.DrawLine(x1
, y1
, x2
, y2
); 
1454             dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1461                 if ( n 
== Arrow_Up 
) 
1472             else // left or right arrow 
1477                 if ( n 
== Arrow_Left 
) 
1490         // draw the shadow for the disabled one 
1491         dcDisabled
.SetPen(m_penHighlight
); 
1496                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1500                 x1 
= ARROW_LENGTH 
- 1; 
1501                 y1 
= (ARROW_WIDTH 
- 1)/2 + 1; 
1504                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1505                 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
); 
1510                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1514                 x1 
= ARROW_WIDTH 
- 1; 
1516                 x2 
= (ARROW_WIDTH 
- 1)/2; 
1518                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1519                 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
); 
1524         // create the inverted bitmap but only for the right arrow as we only 
1525         // use it for the menus 
1526         if ( n 
== Arrow_Right 
) 
1528             m_bmpArrows
[Arrow_Inverted
][n
].Create(w
, h
); 
1529             dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inverted
][n
]); 
1531             dcInverse
.Blit(0, 0, w
, h
, 
1534             dcInverse
.SelectObject(wxNullBitmap
); 
1536             mask 
= new wxMask(m_bmpArrows
[Arrow_Inverted
][n
], *wxBLACK
); 
1537             m_bmpArrows
[Arrow_Inverted
][n
].SetMask(mask
); 
1539             m_bmpArrows
[Arrow_InvertedDisabled
][n
].Create(w
, h
); 
1540             dcInverse
.SelectObject(m_bmpArrows
[Arrow_InvertedDisabled
][n
]); 
1542             dcInverse
.Blit(0, 0, w
, h
, 
1545             dcInverse
.SelectObject(wxNullBitmap
); 
1547             mask 
= new wxMask(m_bmpArrows
[Arrow_InvertedDisabled
][n
], *wxBLACK
); 
1548             m_bmpArrows
[Arrow_InvertedDisabled
][n
].SetMask(mask
); 
1551         dcNormal
.SelectObject(wxNullBitmap
); 
1552         dcDisabled
.SelectObject(wxNullBitmap
); 
1554         mask 
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
); 
1555         m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
); 
1556         mask 
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
); 
1557         m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
); 
1559         m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
]; 
1563 bool wxWin32Renderer::AreScrollbarsInsideBorder() const 
1568 // ---------------------------------------------------------------------------- 
1570 // ---------------------------------------------------------------------------- 
1572 void wxWin32Renderer::DrawLabel(wxDC
& dc
, 
1573                                 const wxString
& label
, 
1580     // the underscores are not drawn for focused controls in wxMSW 
1581     if ( flags 
& wxCONTROL_FOCUSED 
) 
1586     if ( flags 
& wxCONTROL_DISABLED 
) 
1588         // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED 
1589         // currently only can happen for a menu item and it seems that Windows 
1590         // doesn't draw the shadow in this case, so we don't do it neither 
1591         if ( flags 
& wxCONTROL_SELECTED 
) 
1593             // just make the label text greyed out 
1594             dc
.SetTextForeground(m_penDarkGrey
.GetColour()); 
1596             flags 
&= ~wxCONTROL_DISABLED
; 
1600     wxStdRenderer::DrawLabel(dc
, label
, rect
, flags
, alignment
, 
1601                              indexAccel
, rectBounds
); 
1604 void wxWin32Renderer::DrawFrameWithLabel(wxDC
& dc
, 
1605                                          const wxString
& label
, 
1606                                          const wxRect
& rectFrame
, 
1607                                          const wxRect
& rectText
, 
1613     label2 
<< wxT(' ') << label 
<< wxT(' '); 
1614     if ( indexAccel 
!= -1 ) 
1616         // adjust it as we prepended a space 
1620     wxStdRenderer::DrawFrameWithLabel(dc
, label2
, rectFrame
, rectText
, 
1621                                       flags
, alignment
, indexAccel
); 
1624 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
, 
1625                                       const wxString
& label
, 
1626                                       const wxBitmap
& image
, 
1633     // the underscores are not drawn for focused controls in wxMSW 
1634     if ( flags 
& wxCONTROL_PRESSED 
) 
1639     wxStdRenderer::DrawButtonLabel(dc
, label
, image
, rect
, flags
, alignment
, 
1640                                    indexAccel
, rectBounds
); 
1643 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
, 
1644                                        const wxRect
& rectTotal
, 
1648     wxRect rect 
= rectTotal
; 
1650     wxPen 
penOut(*wxBLACK
); 
1651     if ( flags 
& wxCONTROL_PRESSED 
) 
1653         // button pressed: draw a double border around it 
1654         DrawRect(dc
, &rect
, penOut
); 
1655         DrawRect(dc
, &rect
, m_penDarkGrey
); 
1657     else // button not pressed 
1659         if ( flags 
& (wxCONTROL_FOCUSED 
| wxCONTROL_ISDEFAULT
) ) 
1661             // button either default or focused (or both): add an extra border 
1663             DrawRect(dc
, &rect
, penOut
); 
1666         // now draw a normal button border 
1667         DrawRaisedBorder(dc
, &rect
); 
1674 // ---------------------------------------------------------------------------- 
1675 // (check)listbox items 
1676 // ---------------------------------------------------------------------------- 
1678 void wxWin32Renderer::DrawCheckItemBitmap(wxDC
& dc
, 
1679                                           const wxBitmap
& bitmap
, 
1684     if ( bitmap
.IsOk() ) 
1688     else // use default bitmap 
1690         IndicatorStatus i 
= flags 
& wxCONTROL_CHECKED
 
1691                                 ? IndicatorStatus_Checked
 
1692                                 : IndicatorStatus_Unchecked
; 
1694         if ( !m_bmpCheckBitmaps
[i
].IsOk() ) 
1696             m_bmpCheckBitmaps
[i
] = wxBitmap(ms_xpmChecked
[i
]); 
1699         bmp 
= m_bmpCheckBitmaps
[i
]; 
1702     dc
.DrawBitmap(bmp
, rect
.x
, rect
.y 
+ (rect
.height 
- bmp
.GetHeight()) / 2 - 1, 
1703                   true /* use mask */); 
1706 // ---------------------------------------------------------------------------- 
1707 // check/radio buttons 
1708 // ---------------------------------------------------------------------------- 
1710 wxBitmap 
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
) 
1712     IndicatorState indState
; 
1713     IndicatorStatus indStatus
; 
1714     GetIndicatorsFromFlags(flags
, indState
, indStatus
); 
1716     wxBitmap
& bmp 
= m_bmpIndicators
[indType
][indState
][indStatus
]; 
1719         const char **xpm 
= ms_xpmIndicators
[indType
][indState
][indStatus
]; 
1722             // create and cache it 
1723             bmp 
= wxBitmap(xpm
); 
1730 // ---------------------------------------------------------------------------- 
1732 // ---------------------------------------------------------------------------- 
1735 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
, 
1736                                         const wxString
& label
, 
1737                                         const wxBitmap
& bitmap
, 
1738                                         const wxRect
& rectOrig
, 
1743     if (style 
== wxTOOL_STYLE_BUTTON
) 
1745         wxRect rect 
= rectOrig
; 
1746         rect
.Deflate(BORDER_THICKNESS
); 
1748         if ( flags 
& wxCONTROL_PRESSED 
) 
1750             DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
); 
1752         else if ( flags 
& wxCONTROL_CURRENT 
) 
1754             DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
); 
1757         if(tbarStyle 
& wxTB_TEXT
) 
1759             if(tbarStyle 
& wxTB_HORIZONTAL
) 
1761                 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
); 
1765                 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
); 
1770             int xpoint 
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2; 
1771             int ypoint 
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2; 
1772             dc
.DrawBitmap(bitmap
, xpoint
, ypoint
, bitmap
.GetMask() != NULL
); 
1775     else if (style 
== wxTOOL_STYLE_SEPARATOR
) 
1777         // leave a small gap aroudn the line, also account for the toolbar 
1779         if(rectOrig
.height 
> rectOrig
.width
) 
1782             DrawVerticalLine(dc
, rectOrig
.x 
+ rectOrig
.width
/2, 
1783                              rectOrig
.y 
+ 2*BORDER_THICKNESS
, 
1784                              rectOrig
.GetBottom() - BORDER_THICKNESS
); 
1789             DrawHorizontalLine(dc
, rectOrig
.y 
+ rectOrig
.height
/2, 
1790                          rectOrig
.x 
+ 2*BORDER_THICKNESS
, 
1791                          rectOrig
.GetRight() - BORDER_THICKNESS
); 
1794     // don't draw wxTOOL_STYLE_CONTROL 
1796 #endif // wxUSE_TOOLBAR 
1798 // ---------------------------------------------------------------------------- 
1800 // ---------------------------------------------------------------------------- 
1804 void wxWin32Renderer::DrawTab(wxDC
& dc
, 
1805                               const wxRect
& rectOrig
, 
1807                               const wxString
& label
, 
1808                               const wxBitmap
& bitmap
, 
1812     #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X ) 
1813     #define REVERSE_FOR_VERTICAL(X,Y) \ 
1814         SELECT_FOR_VERTICAL(X,Y)      \ 
1816         SELECT_FOR_VERTICAL(Y,X) 
1818     wxRect rect 
= rectOrig
; 
1820     bool isVertical 
= ( dir 
== wxLEFT 
) || ( dir 
== wxRIGHT 
); 
1822     // the current tab is drawn indented (to the top for default case) and 
1823     // bigger than the other ones 
1824     const wxSize indent 
= GetTabIndent(); 
1825     if ( flags 
& wxCONTROL_SELECTED 
) 
1827         rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x 
, 0), 
1828                       SELECT_FOR_VERTICAL( 0, indent
.y 
)); 
1832                 wxFAIL_MSG(wxT("invaild notebook tab orientation")); 
1839                 rect
.height 
+= indent
.y
; 
1846                 rect
.width 
+= indent
.x
; 
1851     // draw the text, image and the focus around them (if necessary) 
1852     wxRect 
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
), 
1853                       REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
) 
1855     rectLabel
.Deflate(1, 1); 
1858         // draw it horizontally into memory and rotate for screen 
1860         wxBitmap bitmapRotated
, 
1861                  bitmapMem( rectLabel
.x 
+ rectLabel
.width
, 
1862                             rectLabel
.y 
+ rectLabel
.height 
); 
1863         dcMem
.SelectObject(bitmapMem
); 
1864         dcMem
.SetBackground(dc
.GetBackground()); 
1865         dcMem
.SetFont(dc
.GetFont()); 
1866         dcMem
.SetTextForeground(dc
.GetTextForeground()); 
1870                         wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) ) 
1873 #endif // wxUSE_IMAGE 
1875         DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
, 
1876                         flags
, wxALIGN_CENTRE
, indexAccel
); 
1877         dcMem
.SelectObject(wxNullBitmap
); 
1878         bitmapMem 
= bitmapMem
.GetSubBitmap(rectLabel
); 
1880         bitmapMem 
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
)); 
1881 #endif // wxUSE_IMAGE 
1882         dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false); 
1886         DrawButtonLabel(dc
, label
, bitmap
, rectLabel
, 
1887                         flags
, wxALIGN_CENTRE
, indexAccel
); 
1890     // now draw the tab border itself (maybe use DrawRoundedRectangle()?) 
1891     static const wxCoord CUTOFF 
= 2; // radius of the rounded corner 
1892     wxCoord x 
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
), 
1893             y 
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
), 
1894             x2 
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()), 
1895             y2 
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight()); 
1897     // FIXME: all this code will break if the tab indent or the border width, 
1898     //        it is tied to the fact that both of them are equal to 2 
1904             // left orientation looks like top but IsVertical makes x and y reversed 
1906             // top is not vertical so use coordinates in written order 
1907             dc
.SetPen(m_penHighlight
); 
1908             dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
), 
1909                         REVERSE_FOR_VERTICAL(x
, y 
+ CUTOFF
)); 
1910             dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y 
+ CUTOFF
), 
1911                         REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y
)); 
1912             dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y
), 
1913                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF 
+ 1, y
)); 
1915             dc
.SetPen(m_penBlack
); 
1916             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
), 
1917                         REVERSE_FOR_VERTICAL(x2
, y 
+ CUTOFF
)); 
1918             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y 
+ CUTOFF
), 
1919                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF
, y
)); 
1921             dc
.SetPen(m_penDarkGrey
); 
1922             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2 
- 1, y2
), 
1923                         REVERSE_FOR_VERTICAL(x2 
- 1, y 
+ CUTOFF 
- 1)); 
1925             if ( flags 
& wxCONTROL_SELECTED 
) 
1927                 dc
.SetPen(m_penLightGrey
); 
1929                 // overwrite the part of the border below this tab 
1930                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y2 
+ 1), 
1931                             REVERSE_FOR_VERTICAL(x2 
- 1, y2 
+ 1)); 
1933                 // and the shadow of the tab to the left of us 
1934                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y 
+ CUTOFF 
+ 1), 
1935                             REVERSE_FOR_VERTICAL(x 
+ 1, y2 
+ 1)); 
1940             // right orientation looks like bottom but IsVertical makes x and y reversed 
1942             // bottom is not vertical so use coordinates in written order 
1943             dc
.SetPen(m_penHighlight
); 
1944             // we need to continue one pixel further to overwrite the corner of 
1945             // the border for the selected tab 
1946             dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y 
- (flags 
& wxCONTROL_SELECTED 
? 1 : 0)), 
1947                         REVERSE_FOR_VERTICAL(x
, y2 
- CUTOFF
)); 
1948             dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2 
- CUTOFF
), 
1949                         REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y2
)); 
1951             dc
.SetPen(m_penBlack
); 
1952             dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y2
), 
1953                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF 
+ 1, y2
)); 
1954             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
), 
1955                         REVERSE_FOR_VERTICAL(x2
, y2 
- CUTOFF
)); 
1956             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2 
- CUTOFF
), 
1957                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF
, y2
)); 
1959             dc
.SetPen(m_penDarkGrey
); 
1960             dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y2 
- 1), 
1961                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF 
+ 1, y2 
- 1)); 
1962             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2 
- 1, y
), 
1963                         REVERSE_FOR_VERTICAL(x2 
- 1, y2 
- CUTOFF 
+ 1)); 
1965             if ( flags 
& wxCONTROL_SELECTED 
) 
1967                 dc
.SetPen(m_penLightGrey
); 
1969                 // overwrite the part of the (double!) border above this tab 
1970                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y 
- 1), 
1971                             REVERSE_FOR_VERTICAL(x2 
- 1, y 
- 1)); 
1972                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y 
- 2), 
1973                             REVERSE_FOR_VERTICAL(x2 
- 1, y 
- 2)); 
1975                 // and the shadow of the tab to the left of us 
1976                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y2 
- CUTOFF
), 
1977                             REVERSE_FOR_VERTICAL(x 
+ 1, y 
- 1)); 
1982     #undef SELECT_FOR_VERTICAL 
1983     #undef REVERSE_FOR_VERTICAL 
1986 #endif // wxUSE_NOTEBOOK 
1990 // ---------------------------------------------------------------------------- 
1992 // ---------------------------------------------------------------------------- 
1995 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
), 
1997                                     wxOrientation orient
) const 
2000     wxCoord width  
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2; 
2001     wxCoord height 
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
); 
2003     if (orient 
== wxHORIZONTAL
) 
2017 wxRect 
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
, 
2019                                            wxOrientation orient
, 
2023     GetSliderLabelsSides(orient
, style
, &left
, &right
); 
2025     wxRect rect 
= rectOrig
; 
2027     wxSize sizeThumb 
= GetSliderThumbSize (rect
, lenThumb
, orient
); 
2029     if (orient 
== wxHORIZONTAL
) 
2031         rect
.x 
+= SLIDER_MARGIN
; 
2034             rect
.y 
+= wxMax ((rect
.height 
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2); 
2038             rect
.y 
+= wxMax ((rect
.height 
- 2*BORDER_THICKNESS 
- sizeThumb
.y
/2), sizeThumb
.y
/2); 
2042             rect
.y 
+= sizeThumb
.y
/2; 
2044         rect
.width 
-= 2*SLIDER_MARGIN
; 
2045         rect
.height 
= 2*BORDER_THICKNESS
; 
2047     else // == wxVERTICAL 
2049         rect
.y 
+= SLIDER_MARGIN
; 
2052             rect
.x 
+= wxMax ((rect
.width 
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2); 
2056             rect
.x 
+= wxMax ((rect
.width 
- 2*BORDER_THICKNESS 
- sizeThumb
.x
/2), sizeThumb
.x
/2); 
2060             rect
.x 
+= sizeThumb
.x
/2; 
2062         rect
.width 
= 2*BORDER_THICKNESS
; 
2063         rect
.height 
-= 2*SLIDER_MARGIN
; 
2069 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
, 
2070                                       const wxRect
& rectOrig
, 
2072                                       wxOrientation orient
, 
2077     /*    show shaft geometry 
2095     if (flags 
& wxCONTROL_FOCUSED
) 
2096         DrawFocusRect(NULL
, dc
, rectOrig
); 
2098     wxRect rect 
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
); 
2100     if (rectShaft
) *rectShaft 
= rect
; 
2102     DrawSunkenBorder(dc
, &rect
); 
2105 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
, 
2107                                       wxOrientation orient
, 
2111     /*    show thumb geometry 
2120        H         D B   where H is highlight colour 
2134        The interior of this shape is filled with the hatched brush if the thumb 
2138     DrawBackground(dc
, wxNullColour
, rect
, flags
); 
2141     GetSliderLabelsSides(orient
, style
, &left
, &right
); 
2143     bool isVertical 
= orient 
== wxVERTICAL
; 
2145     wxCoord sizeArrow 
= (isVertical 
? rect
.height 
: rect
.width
) / 2; 
2146     wxCoord c 
= ((isVertical 
? rect
.height 
: rect
.width
) - 2*sizeArrow
); 
2148     wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
; 
2149     x1 
= (isVertical 
? rect
.y 
: rect
.x
); 
2150     x2 
= (isVertical 
? rect
.GetBottom() : rect
.GetRight()); 
2151     x3 
= (x1
-1+c
) + sizeArrow
; 
2152     y1 
= (isVertical 
? rect
.x 
: rect
.y
); 
2153     y2 
= (isVertical 
? rect
.GetRight() : rect
.GetBottom()); 
2154     y3 
= (left  
? (y1
-1+c
) + sizeArrow 
: y1
); 
2155     y4 
= (right 
? (y2
+1-c
) - sizeArrow 
: y2
); 
2157     dc
.SetPen(m_penBlack
); 
2160         DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, isVertical
); 
2162     DrawLine(dc
, x2
, y3
, x2
, y4
, isVertical
); 
2165         DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, isVertical
); 
2169         DrawLine(dc
, x1
, y2
, x2
, y2
, isVertical
); 
2172     dc
.SetPen(m_penDarkGrey
); 
2173     DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, isVertical
); 
2176         DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, isVertical
); 
2180         DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, isVertical
); 
2183     dc
.SetPen(m_penHighlight
); 
2186         DrawLine(dc
, x1
, y3
, x3
, y1
, isVertical
); 
2187         DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, isVertical
); 
2191         DrawLine(dc
, x1
, y1
, x2
, y1
, isVertical
); 
2193     DrawLine(dc
, x1
, y3
, x1
, y4
, isVertical
); 
2196         DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, isVertical
); 
2199     if (flags 
& wxCONTROL_PRESSED
) 
2201         // TODO: MSW fills the entire area inside, not just the rect 
2202         wxRect rectInt 
= rect
; 
2205             rectInt
.SetLeft(y3
); 
2206             rectInt
.SetRight(y4
); 
2211             rectInt
.SetBottom(y4
); 
2215 #if !defined(__WXMGL__) 
2216         static const char *stipple_xpm
[] = { 
2217             /* columns rows colors chars-per-pixel */ 
2226         // VS: MGL can only do 8x8 stipple brushes 
2227         static const char *stipple_xpm
[] = { 
2228             /* columns rows colors chars-per-pixel */ 
2243         dc
.SetBrush(wxBrush(stipple_xpm
)); 
2245         dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
)); 
2246         dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
)); 
2247         dc
.SetPen(*wxTRANSPARENT_PEN
); 
2248         dc
.DrawRectangle(rectInt
); 
2252 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
, 
2255                                       wxOrientation orient
, 
2259                                       int WXUNUSED(flags
), 
2262     /*    show ticks geometry 
2281     GetSliderLabelsSides(orient
, style
, &left
, &right
); 
2283     bool isVertical 
= orient 
== wxVERTICAL
; 
2285     // default thumb size 
2286     wxSize sizeThumb 
= GetSliderThumbSize (rect
, 0, orient
); 
2287     wxCoord defaultLen 
= (isVertical 
? sizeThumb
.x 
: sizeThumb
.y
); 
2289     // normal thumb size 
2290     sizeThumb 
= GetSliderThumbSize (rect
, lenThumb
, orient
); 
2291     wxCoord widthThumb  
= (isVertical 
? sizeThumb
.y 
: sizeThumb
.x
); 
2293     wxRect rectShaft 
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
); 
2295     wxCoord x1
, x2
, y1
, y2
, y3
, y4 
, len
; 
2296     x1 
= (isVertical 
? rectShaft
.y 
: rectShaft
.x
) + widthThumb
/2; 
2297     x2 
= (isVertical 
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2; 
2298     y1 
= (isVertical 
? rectShaft
.x 
: rectShaft
.y
) - defaultLen
/2; 
2299     y2 
= (isVertical 
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2; 
2300     y3 
= (isVertical 
? rect
.x 
: rect
.y
); 
2301     y4 
= (isVertical 
? rect
.GetRight() : rect
.GetBottom()); 
2304     dc
.SetPen(m_penBlack
); 
2306     int range 
= end 
- start
; 
2307     for ( int n 
= 0; n 
< range
; n 
+= step 
) 
2309         wxCoord x 
= x1 
+ (len
*n
) / range
; 
2311         if (left 
& (y1 
> y3
)) 
2313             DrawLine(dc
, x
, y1
, x
, y3
, orient 
== wxVERTICAL
); 
2315         if (right 
& (y4 
> y2
)) 
2317             DrawLine(dc
, x
, y2
, x
, y4
, orient 
== wxVERTICAL
); 
2320     // always draw the line at the end position 
2321     if (left 
& (y1 
> y3
)) 
2323         DrawLine(dc
, x2
, y1
, x2
, y3
, orient 
== wxVERTICAL
); 
2325     if (right 
& (y4 
> y2
)) 
2327         DrawLine(dc
, x2
, y2
, x2
, y4
, orient 
== wxVERTICAL
); 
2331 #endif // wxUSE_SLIDER 
2335 // ---------------------------------------------------------------------------- 
2337 // ---------------------------------------------------------------------------- 
2339 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer 
2340 class WXDLLEXPORT wxWin32MenuGeometryInfo 
: public wxMenuGeometryInfo
 
2343     virtual wxSize 
GetSize() const { return m_size
; } 
2345     wxCoord 
GetLabelOffset() const { return m_ofsLabel
; } 
2346     wxCoord 
GetAccelOffset() const { return m_ofsAccel
; } 
2348     wxCoord 
GetItemHeight() const { return m_heightItem
; } 
2351     // the total size of the menu 
2354     // the offset of the start of the menu item label 
2357     // the offset of the start of the accel label 
2360     // the height of a normal (not separator) item 
2361     wxCoord m_heightItem
; 
2363     friend wxMenuGeometryInfo 
* 
2364         wxWin32Renderer::GetMenuGeometry(wxWindow 
*, const wxMenu
&) const; 
2367 // FIXME: all constants are hardcoded but shouldn't be 
2368 static const wxCoord MENU_LEFT_MARGIN 
= 9; 
2369 static const wxCoord MENU_RIGHT_MARGIN 
= 18; 
2370 static const wxCoord MENU_VERT_MARGIN 
= 3; 
2372 // the margin around bitmap/check marks (on each side) 
2373 static const wxCoord MENU_BMP_MARGIN 
= 2; 
2375 // the margin between the labels and accel strings 
2376 static const wxCoord MENU_ACCEL_MARGIN 
= 8; 
2378 // the separator height in pixels: in fact, strangely enough, the real height 
2379 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into 
2381 static const wxCoord MENU_SEPARATOR_HEIGHT 
= 3; 
2383 // the size of the standard checkmark bitmap 
2384 static const wxCoord MENU_CHECK_SIZE 
= 9; 
2386 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
, 
2387                                       const wxRect
& rectOrig
, 
2388                                       const wxString
& label
, 
2392     wxRect rect 
= rectOrig
; 
2395     wxDCTextColourChanger 
colChanger(dc
); 
2397     if ( flags 
& wxCONTROL_SELECTED 
) 
2399         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
2401         const wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
2404         dc
.DrawRectangle(rect
); 
2407     // don't draw the focus rect around menu bar items 
2408     DrawLabel(dc
, label
, rect
, flags 
& ~wxCONTROL_FOCUSED
, 
2409               wxALIGN_CENTRE
, indexAccel
); 
2412 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
, 
2414                                    const wxMenuGeometryInfo
& gi
, 
2415                                    const wxString
& label
, 
2416                                    const wxString
& accel
, 
2417                                    const wxBitmap
& bitmap
, 
2421     const wxWin32MenuGeometryInfo
& geometryInfo 
= 
2422         (const wxWin32MenuGeometryInfo
&)gi
; 
2427     rect
.width 
= geometryInfo
.GetSize().x
; 
2428     rect
.height 
= geometryInfo
.GetItemHeight(); 
2430     // draw the selected item specially 
2431     wxDCTextColourChanger 
colChanger(dc
); 
2432     if ( flags 
& wxCONTROL_SELECTED 
) 
2434         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
2436         const wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
2439         dc
.DrawRectangle(rect
); 
2442     // draw the bitmap: use the bitmap provided or the standard checkmark for 
2443     // the checkable items 
2444     wxBitmap bmp 
= bitmap
; 
2445     if ( !bmp
.IsOk() && (flags 
& wxCONTROL_CHECKED
) ) 
2447         bmp 
= GetIndicator(IndicatorType_Menu
, flags
); 
2452         rect
.SetRight(geometryInfo
.GetLabelOffset()); 
2453         wxControlRenderer::DrawBitmap(dc
, bmp
, rect
); 
2457     rect
.x 
= geometryInfo
.GetLabelOffset(); 
2458     rect
.SetRight(geometryInfo
.GetAccelOffset()); 
2460     DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
); 
2462     // draw the accel string 
2463     rect
.x 
= geometryInfo
.GetAccelOffset(); 
2464     rect
.SetRight(geometryInfo
.GetSize().x
); 
2466     // NB: no accel index here 
2467     DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
); 
2469     // draw the submenu indicator 
2470     if ( flags 
& wxCONTROL_ISSUBMENU 
) 
2472         rect
.x 
= geometryInfo
.GetSize().x 
- MENU_RIGHT_MARGIN
; 
2473         rect
.width 
= MENU_RIGHT_MARGIN
; 
2475         ArrowStyle arrowStyle
; 
2476         if ( flags 
& wxCONTROL_DISABLED 
) 
2477             arrowStyle 
= flags 
& wxCONTROL_SELECTED 
? Arrow_InvertedDisabled
 
2479         else if ( flags 
& wxCONTROL_SELECTED 
) 
2480             arrowStyle 
= Arrow_Inverted
; 
2482             arrowStyle 
= Arrow_Normal
; 
2484         DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
); 
2488 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
, 
2490                                         const wxMenuGeometryInfo
& geomInfo
) 
2492     DrawHorizontalLine(dc
, y 
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
); 
2495 wxSize 
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const 
2497     wxSize size 
= sizeText
; 
2499     // FIXME: menubar height is configurable under Windows 
2506 wxMenuGeometryInfo 
*wxWin32Renderer::GetMenuGeometry(wxWindow 
*win
, 
2507                                                      const wxMenu
& menu
) const 
2509     // prepare the dc: for now we draw all the items with the system font 
2511     dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
2513     // the height of a normal item 
2514     wxCoord heightText 
= dc
.GetCharHeight(); 
2519     // the max length of label and accel strings: the menu width is the sum of 
2520     // them, even if they're for different items (as the accels should be 
2523     // the max length of the bitmap is never 0 as Windows always leaves enough 
2524     // space for a check mark indicator 
2525     wxCoord widthLabelMax 
= 0, 
2527             widthBmpMax 
= MENU_LEFT_MARGIN
; 
2529     for ( wxMenuItemList::compatibility_iterator node 
= menu
.GetMenuItems().GetFirst(); 
2531           node 
= node
->GetNext() ) 
2533         // height of this item 
2536         wxMenuItem 
*item 
= node
->GetData(); 
2537         if ( item
->IsSeparator() ) 
2539             h 
= MENU_SEPARATOR_HEIGHT
; 
2541         else // not separator 
2546             dc
.GetTextExtent(item
->GetItemLabelText(), &widthLabel
, NULL
); 
2547             if ( widthLabel 
> widthLabelMax 
) 
2549                 widthLabelMax 
= widthLabel
; 
2553             dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
); 
2554             if ( widthAccel 
> widthAccelMax 
) 
2556                 widthAccelMax 
= widthAccel
; 
2559             const wxBitmap
& bmp 
= item
->GetBitmap(); 
2562                 wxCoord widthBmp 
= bmp
.GetWidth(); 
2563                 if ( widthBmp 
> widthBmpMax 
) 
2564                     widthBmpMax 
= widthBmp
; 
2566             //else if ( item->IsCheckable() ): no need to check for this as 
2567             // MENU_LEFT_MARGIN is big enough to show the check mark 
2570         h 
+= 2*MENU_VERT_MARGIN
; 
2572         // remember the item position and height 
2573         item
->SetGeometry(height
, h
); 
2578     // bundle the metrics into a struct and return it 
2579     wxWin32MenuGeometryInfo 
*gi 
= new wxWin32MenuGeometryInfo
; 
2581     gi
->m_ofsLabel 
= widthBmpMax 
+ 2*MENU_BMP_MARGIN
; 
2582     gi
->m_ofsAccel 
= gi
->m_ofsLabel 
+ widthLabelMax
; 
2583     if ( widthAccelMax 
> 0 ) 
2585         // if we actually have any accesl, add a margin 
2586         gi
->m_ofsAccel 
+= MENU_ACCEL_MARGIN
; 
2589     gi
->m_heightItem 
= heightText 
+ 2*MENU_VERT_MARGIN
; 
2591     gi
->m_size
.x 
= gi
->m_ofsAccel 
+ widthAccelMax 
+ MENU_RIGHT_MARGIN
; 
2592     gi
->m_size
.y 
= height
; 
2597 #endif // wxUSE_MENUS 
2601 // ---------------------------------------------------------------------------- 
2603 // ---------------------------------------------------------------------------- 
2605 void wxWin32Renderer::DrawStatusField(wxDC
& dc
, 
2607                                       const wxString
& label
, 
2613     if ( flags 
& wxCONTROL_SIZEGRIP 
) 
2615         // draw the size grip: it is a normal rect except that in the lower 
2616         // right corner we have several bands which may be used for dragging 
2617         // the status bar corner 
2619         // each band consists of 4 stripes: m_penHighlight, double 
2620         // m_penDarkGrey and transparent one 
2621         wxCoord x2 
= rect
.GetRight(), 
2622                 y2 
= rect
.GetBottom(); 
2624         // draw the upper left part of the rect normally 
2625         if (style 
!= wxSB_FLAT
) 
2627             if (style 
== wxSB_RAISED
) 
2628                 dc
.SetPen(m_penHighlight
); 
2630                 dc
.SetPen(m_penDarkGrey
); 
2631             dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
); 
2632             dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop()); 
2635         // draw the grey stripes of the grip 
2637         wxCoord ofs 
= WIDTH_STATUSBAR_GRIP_BAND 
- 1; 
2638         for ( n 
= 0; n 
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs 
+= WIDTH_STATUSBAR_GRIP_BAND 
) 
2640             dc
.DrawLine(x2 
- ofs 
+ 1, y2 
- 1, x2
, y2 
- ofs
); 
2641             dc
.DrawLine(x2 
- ofs
, y2 
- 1, x2
, y2 
- ofs 
- 1); 
2644         // draw the white stripes 
2645         dc
.SetPen(m_penHighlight
); 
2646         ofs 
= WIDTH_STATUSBAR_GRIP_BAND 
+ 1; 
2647         for ( n 
= 0; n 
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs 
+= WIDTH_STATUSBAR_GRIP_BAND 
) 
2649             dc
.DrawLine(x2 
- ofs 
+ 1, y2 
- 1, x2
, y2 
- ofs
); 
2652         // draw the remaining rect boundaries 
2653         if (style 
!= wxSB_FLAT
) 
2655             if (style 
== wxSB_RAISED
) 
2656                 dc
.SetPen(m_penDarkGrey
); 
2658                 dc
.SetPen(m_penHighlight
); 
2659             ofs 
-= WIDTH_STATUSBAR_GRIP_BAND
; 
2660             dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2 
- ofs 
+ 1); 
2661             dc
.DrawLine(rect
.GetLeft(), y2
, x2 
- ofs 
+ 1, y2
); 
2667         rectIn
.width 
-= STATUSBAR_GRIP_SIZE
; 
2669         // this will prevent the standard version from drawing any borders 
2673     wxStdRenderer::DrawStatusField(dc
, rect
, label
, flags
, style
); 
2676 #endif // wxUSE_STATUSBAR 
2678 // ---------------------------------------------------------------------------- 
2680 // ---------------------------------------------------------------------------- 
2682 void wxWin32Renderer::GetComboBitmaps(wxBitmap 
*bmpNormal
, 
2683                                       wxBitmap 
* WXUNUSED(bmpFocus
), 
2684                                       wxBitmap 
*bmpPressed
, 
2685                                       wxBitmap 
*bmpDisabled
) 
2687     static const wxCoord widthCombo 
= 16; 
2688     static const wxCoord heightCombo 
= 17; 
2694         bmpNormal
->Create(widthCombo
, heightCombo
); 
2695         dcMem
.SelectObject(*bmpNormal
); 
2696         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
2697                         Arrow_Down
, Arrow_Normal
); 
2702         bmpPressed
->Create(widthCombo
, heightCombo
); 
2703         dcMem
.SelectObject(*bmpPressed
); 
2704         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
2705                         Arrow_Down
, Arrow_Pressed
); 
2710         bmpDisabled
->Create(widthCombo
, heightCombo
); 
2711         dcMem
.SelectObject(*bmpDisabled
); 
2712         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
2713                         Arrow_Down
, Arrow_Disabled
); 
2717 // ---------------------------------------------------------------------------- 
2719 // ---------------------------------------------------------------------------- 
2721 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect 
*rect
, bool isPressed
) 
2725         DrawRect(dc
, rect
, m_penDarkGrey
); 
2727         // the arrow is usually drawn inside border of width 2 and is offset by 
2728         // another pixel in both directions when it's pressed - as the border 
2729         // in this case is more narrow as well, we have to adjust rect like 
2737         DrawAntiSunkenBorder(dc
, rect
); 
2741 void wxWin32Renderer::DrawArrow(wxDC
& dc
, 
2746     ArrowStyle arrowStyle
; 
2747     if ( flags 
& wxCONTROL_PRESSED 
) 
2749         // can't be pressed and disabled 
2750         arrowStyle 
= Arrow_Pressed
; 
2754         arrowStyle 
= flags 
& wxCONTROL_DISABLED 
? Arrow_Disabled 
: Arrow_Normal
; 
2757     DrawArrowButton(dc
, rect
, GetArrowDirection(dir
), arrowStyle
); 
2760 void wxWin32Renderer::DrawArrow(wxDC
& dc
, 
2762                                 ArrowDirection arrowDir
, 
2763                                 ArrowStyle arrowStyle
) 
2765     const wxBitmap
& bmp 
= m_bmpArrows
[arrowStyle
][arrowDir
]; 
2767     // under Windows the arrows always have the same size so just centre it in 
2768     // the provided rectangle 
2769     wxCoord x 
= rect
.x 
+ (rect
.width 
- bmp
.GetWidth()) / 2, 
2770             y 
= rect
.y 
+ (rect
.height 
- bmp
.GetHeight()) / 2; 
2772     // Windows does it like this... 
2773     if ( arrowDir 
== Arrow_Left 
) 
2777     dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */); 
2780 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
, 
2781                                       const wxRect
& rectAll
, 
2782                                       ArrowDirection arrowDir
, 
2783                                       ArrowStyle arrowStyle
) 
2785     wxRect rect 
= rectAll
; 
2786     DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
); 
2787     DrawArrowBorder(dc
, &rect
, arrowStyle 
== Arrow_Pressed
); 
2788     DrawArrow(dc
, rect
, arrowDir
, arrowStyle
); 
2791 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
, 
2792                                          wxOrientation 
WXUNUSED(orient
), 
2794                                          int WXUNUSED(flags
)) 
2796     // we don't use the flags, the thumb never changes appearance 
2797     wxRect rectThumb 
= rect
; 
2798     DrawArrowBorder(dc
, &rectThumb
); 
2799     DrawBackground(dc
, wxNullColour
, rectThumb
); 
2802 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
, 
2803                                          wxOrientation 
WXUNUSED(orient
), 
2804                                          const wxRect
& rectBar
, 
2807     wxColourScheme::StdColour col 
= flags 
& wxCONTROL_PRESSED
 
2808                                     ? wxColourScheme::SCROLLBAR_PRESSED
 
2809                                     : wxColourScheme::SCROLLBAR
; 
2810     DrawBackground(dc
, m_scheme
->Get(col
), rectBar
); 
2813 // ---------------------------------------------------------------------------- 
2815 // ---------------------------------------------------------------------------- 
2817 /* Copyright (c) Julian Smart */ 
2818 static const char *error_xpm
[]={ 
2819 /* columns rows colors chars-per-pixel */ 
2896 "        $oooooooooooo%&         ", 
2897 "      *=-ooooooooooooo;:        ", 
2898 "     *oooooooooooooooooo>       ", 
2899 "     =ooooooooooooooooooo,      ", 
2900 "    $-ooooooooooooooooooo<1     ", 
2901 "   .oooooo2334ooo533oooooo6     ", 
2902 "   +ooooooo789oo2883oooooo0q    ", 
2903 "   oooooooo2w83o78eoooooooor    ", 
2904 "  toooooooooy88u884oooooooori   ", 
2905 "  Xooooooooooe888poooooooooas   ", 
2906 "  ooooooooooo4889doooooooooof   ", 
2907 "  ooooooooooo588w2oooooooooofi  ", 
2908 "  oooooooooodw8887oooooooooofi  ", 
2909 "  goooooooooh8w588jooooooookli  ", 
2910 "  tooooooooz885op8wdooooooorix  ", 
2911 "   oooooood98cood98cooooooori   ", 
2912 "   @oooooop8w2ooo5885ooooovbi   ", 
2913 "   n%ooooooooooooooooooooomiM   ", 
2914 "    &;oooooooooooooooooooNBiV   ", 
2915 "     :ooooooooooooooooooCZiA    ", 
2916 "     nSooooooooooooooooCDiF     ", 
2917 "      nG<oooooooooooooNZiiH     ", 
2918 "        160ooooooooovmBiFH      ", 
2919 "         nqrraoookrrbiiA        ", 
2926 /* Copyright (c) Julian Smart */ 
2927 static const char *info_xpm
[]={ 
2928 /* columns rows colors chars-per-pixel */ 
2950 "     ..XXXXXXXXXXXXX..          ", 
2951 "    .XXXXXXXXXXXXXXXXX.         ", 
2952 "   .XXXXXXXXoO+XXXXXXXX.        ", 
2953 "  .XXXXXXXXX@#OXXXXXXXXX.       ", 
2954 " .XXXXXXXXXX$@oXXXXXXXXXX.      ", 
2955 " .XXXXXXXXXXXXXXXXXXXXXXX.%     ", 
2956 " .XXXXXXXXX&*=-XXXXXXXXXX.%%    ", 
2957 ".XXXXXXXXXX;:#>XXXXXXXXXXX.%    ", 
2958 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%    ", 
2959 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%%   ", 
2960 " .XXXXXXXXXX;#+XXXXXXXXXX.%%%   ", 
2961 " .XXXXXXXXXX;#+XXXXXXXXXX.%%%   ", 
2962 " .XXXXXXXXXX;#+XXXXXXXXXX.%%    ", 
2963 "  .XXXXXXXX*-##+XXXXXXXX.%%%    ", 
2964 "   .XXXXXXXXXXXXXXXXXXX.%%%%    ", 
2965 "    .XXXXXXXXXXXXXXXXX.%%%%     ", 
2966 "     ..XXXXXXXXXXXXX..%%%%      ", 
2967 "      %...XXXXXXXX..%%%%%       ", 
2968 "       %%%..XXXXXX.%%%%%        ", 
2982 /* Copyright (c) Julian Smart */ 
2983 static const char *question_xpm
[]={ 
2984 /* columns rows colors chars-per-pixel */ 
3005 "     ..XXXXXXXXXXXXX..          ", 
3006 "    .XXXXXXoO++@XXXXXX.         ", 
3007 "   .XXXXXXO#$$$$#%XXXXX.        ", 
3008 "  .XXXXXX@$$#&&#$#oXXXXX.       ", 
3009 " .XXXXXXX*$$%XX%$$=XXXXXX.      ", 
3010 " .XXXXXXX+-;XXXX$$-XXXXXX.:     ", 
3011 " .XXXXXXXXXXXXX+$$&XXXXXX.::    ", 
3012 ".XXXXXXXXXXXXo;$$*oXXXXXXX.:    ", 
3013 ".XXXXXXXXXXXo*$$*oXXXXXXXX.:    ", 
3014 ".XXXXXXXXXXX+$$*oXXXXXXXXX.::   ", 
3015 " .XXXXXXXXXX-$$oXXXXXXXXX.:::   ", 
3016 " .XXXXXXXXXXX--XXXXXXXXXX.:::   ", 
3017 " .XXXXXXXXXXXXXXXXXXXXXXX.::    ", 
3018 "  .XXXXXXXXX-$$XXXXXXXXX.:::    ", 
3019 "   .XXXXXXXX-$$XXXXXXXX.::::    ", 
3020 "    .XXXXXXXO++XXXXXXX.::::     ", 
3021 "     ..XXXXXXXXXXXXX..::::      ", 
3022 "      :...XXXXXXXX..:::::       ", 
3023 "       :::..XXXXXX.:::::        ", 
3037 /* Copyright (c) Julian Smart */ 
3038 static const char *warning_xpm
[]={ 
3039 /* columns rows colors chars-per-pixel */ 
3065 "         ..XXXXO@#XXX...        ", 
3066 "        ...XXXXO@#XXXX..        ", 
3067 "        ..XXXXXO@#XXXX...       ", 
3068 "       ...XXXXXo@OXXXXX..       ", 
3069 "      ...XXXXXXo@OXXXXXX..      ", 
3070 "      ..XXXXXXX$@OXXXXXX...     ", 
3071 "     ...XXXXXXXX@XXXXXXXX..     ", 
3072 "    ...XXXXXXXXXXXXXXXXXX...    ", 
3073 "    ..XXXXXXXXXXOXXXXXXXXX..    ", 
3074 "   ...XXXXXXXXXO@#XXXXXXXXX..   ", 
3075 "   ..XXXXXXXXXXX#XXXXXXXXXX...  ", 
3076 "  ...XXXXXXXXXXXXXXXXXXXXXXX..  ", 
3077 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ", 
3078 " .............................. ", 
3079 " .............................. ", 
3086 wxBitmap 
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
, 
3087                                           const wxArtClient
& WXUNUSED(client
), 
3088                                           const wxSize
& WXUNUSED(size
)) 
3090     if ( id 
== wxART_INFORMATION 
) 
3091         return wxBitmap(info_xpm
); 
3092     if ( id 
== wxART_ERROR 
) 
3093         return wxBitmap(error_xpm
); 
3094     if ( id 
== wxART_WARNING 
) 
3095         return wxBitmap(warning_xpm
); 
3096     if ( id 
== wxART_QUESTION 
) 
3097         return wxBitmap(question_xpm
); 
3098     return wxNullBitmap
; 
3104 // ---------------------------------------------------------------------------- 
3105 // text control geometry 
3106 // ---------------------------------------------------------------------------- 
3109 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl 
*text
, 
3110                                   const wxRect
& rect
) const 
3112     wxRect rectTotal 
= wxStdRenderer::GetTextTotalArea(text
, rect
); 
3114     // this is strange but it's what Windows does 
3121 wxWin32Renderer::GetTextClientArea(const wxTextCtrl 
*text
, 
3123                                    wxCoord 
*extraSpaceBeyond
) const 
3125     wxRect rectText 
= rect
; 
3127     // undo GetTextTotalArea() 
3128     if ( rectText
.height 
> 0 ) 
3131     return wxStdRenderer::GetTextClientArea(text
, rect
, extraSpaceBeyond
); 
3134 #endif // wxUSE_TEXTCTRL 
3136 // ---------------------------------------------------------------------------- 
3138 // ---------------------------------------------------------------------------- 
3140 void wxWin32Renderer::AdjustSize(wxSize 
*size
, const wxWindow 
*window
) 
3143     if ( wxDynamicCast(window
, wxScrollBar
) ) 
3146         Don't adjust the size for a scrollbar as its DoGetBestClientSize 
3147         already has the correct size set. Any size changes here would get 
3148         added to the best size, making the scrollbar larger. 
3149         Also skip border width adjustments, they don't make sense for us. 
3153 #endif // wxUSE_SCROLLBAR 
3156     if ( wxDynamicCast(window
, wxBitmapButton
) ) 
3160 #endif // wxUSE_BMPBUTTON 
3161 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN 
3164          || wxDynamicCast(window
, wxButton
) 
3165 #  endif // wxUSE_BUTTON 
3166 #  if wxUSE_TOGGLEBTN 
3167          || wxDynamicCast(window
, wxToggleButton
) 
3168 #  endif // wxUSE_TOGGLEBTN 
3171         if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) ) 
3173             // TODO: don't harcode all this 
3174             size
->x 
+= 3*window
->GetCharWidth(); 
3176             wxCoord heightBtn 
= (11*(window
->GetCharHeight() + 8))/10; 
3177             if ( size
->y 
< heightBtn 
- 8 ) 
3178                 size
->y 
= heightBtn
; 
3183         // for compatibility with other ports, the buttons default size is never 
3184         // less than the standard one, but not when display not PDAs. 
3185         if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
) 
3187             if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) ) 
3189                 wxSize szDef 
= wxButton::GetDefaultSize(); 
3190                 if ( size
->x 
< szDef
.x 
) 
3195         // no border width adjustments for buttons 
3198 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN 
3200     wxStdRenderer::AdjustSize(size
, window
); 
3203 wxBitmap 
wxWin32Renderer::GetFrameButtonBitmap(FrameButtonType type
) 
3205     wxBitmap
& bmp 
= m_bmpFrameButtons
[type
]; 
3208         bmp 
= wxBitmap(ms_xpmFrameButtons
[type
]); 
3214 // ============================================================================ 
3216 // ============================================================================ 
3218 // ---------------------------------------------------------------------------- 
3219 // wxWin32InputHandler 
3220 // ---------------------------------------------------------------------------- 
3222 bool wxWin32InputHandler::HandleKey(wxInputConsumer 
* WXUNUSED(control
), 
3223                                     const wxKeyEvent
& WXUNUSED(event
), 
3224                                     bool WXUNUSED(pressed
)) 
3229 bool wxWin32InputHandler::HandleMouse(wxInputConsumer 
*control
, 
3230                                       const wxMouseEvent
& event
) 
3232     // clicking on the control gives it focus 
3233     if ( event
.ButtonDown() ) 
3235         wxWindow 
* const win 
= control
->GetInputWindow(); 
3237         if ( win
->CanAcceptFocus() && wxWindow::FindFocus() != win 
) 
3250 // ---------------------------------------------------------------------------- 
3251 // wxWin32ScrollBarInputHandler 
3252 // ---------------------------------------------------------------------------- 
3254 wxWin32ScrollBarInputHandler:: 
3255 wxWin32ScrollBarInputHandler(wxRenderer 
*renderer
, wxInputHandler 
*handler
) 
3256         : wxStdScrollBarInputHandler(renderer
, handler
) 
3258     m_scrollPaused 
= false; 
3262 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar 
*scrollbar
, 
3263                                                  const wxControlAction
& action
) 
3265     // stop if went beyond the position of the original click (this can only 
3266     // happen when we scroll by pages) 
3268     if ( action 
== wxACTION_SCROLL_PAGE_DOWN 
) 
3270         stop 
= scrollbar
->HitTestBar(m_ptStartScrolling
) != wxHT_SCROLLBAR_BAR_2
; 
3272     else if ( action 
== wxACTION_SCROLL_PAGE_UP 
) 
3274         stop 
= scrollbar
->HitTestBar(m_ptStartScrolling
) != wxHT_SCROLLBAR_BAR_1
; 
3279         StopScrolling(scrollbar
); 
3281         scrollbar
->Refresh(); 
3286     return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
); 
3289 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer 
*control
, 
3290                                                const wxMouseEvent
& event
) 
3292     // remember the current state 
3293     bool wasDraggingThumb 
= m_htLast 
== wxHT_SCROLLBAR_THUMB
; 
3295     // do process the message 
3296     bool rc 
= wxStdScrollBarInputHandler::HandleMouse(control
, event
); 
3298     // analyse the changes 
3299     if ( !wasDraggingThumb 
&& (m_htLast 
== wxHT_SCROLLBAR_THUMB
) ) 
3301         // we just started dragging the thumb, remember its initial position to 
3302         // be able to restore it if the drag is cancelled later 
3303         m_eventStartDrag 
= event
; 
3309 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer 
*control
, 
3310                                                    const wxMouseEvent
& event
) 
3312     // we don't highlight scrollbar elements, so there is no need to process 
3313     // mouse move events normally - only do it while mouse is captured (i.e. 
3314     // when we're dragging the thumb or pressing on something) 
3315     if ( !m_winCapture 
) 
3318     if ( event
.Entering() ) 
3320         // we're not interested in this at all 
3324     wxScrollBar 
*scrollbar 
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
); 
3326     if ( m_scrollPaused 
) 
3328         // check if the mouse returned to its original location 
3330         if ( event
.Leaving() ) 
3336         ht 
= scrollbar
->HitTestBar(event
.GetPosition()); 
3337         if ( ht 
== m_htLast 
) 
3339             // yes it did, resume scrolling 
3340             m_scrollPaused 
= false; 
3341             if ( m_timerScroll 
) 
3343                 // we were scrolling by line/page, restart timer 
3344                 m_timerScroll
->Start(m_interval
); 
3346                 Press(scrollbar
, true); 
3348             else // we were dragging the thumb 
3350                 // restore its last location 
3351                 HandleThumbMove(scrollbar
, m_eventLastDrag
); 
3357     else // normal case, scrolling hasn't been paused 
3359         // if we're scrolling the scrollbar because the arrow or the shaft was 
3360         // pressed, check that the mouse stays on the same scrollbar element 
3363         // Always let thumb jump back if we leave the scrollbar 
3364         if ( event
.Moving() ) 
3366             ht 
= scrollbar
->HitTestBar(event
.GetPosition()); 
3368         else // event.Leaving() 
3373         // Jump back only if we get far away from it 
3374         wxPoint pos 
= event
.GetPosition(); 
3375         if (scrollbar
->HasFlag( wxVERTICAL 
)) 
3377             if (pos
.x 
> -40 && pos
.x 
< scrollbar
->GetSize().x
+40) 
3382             if (pos
.y 
> -40 && pos
.y 
< scrollbar
->GetSize().y
+40) 
3385         ht 
= scrollbar
->HitTestBar(pos
); 
3388         // if we're dragging the thumb and the mouse stays in the scrollbar, it 
3389         // is still ok - we only want to catch the case when the mouse leaves 
3390         // the scrollbar here 
3391         if ( m_htLast 
== wxHT_SCROLLBAR_THUMB 
&& ht 
!= wxHT_NOWHERE 
) 
3393             ht 
= wxHT_SCROLLBAR_THUMB
; 
3396         if ( ht 
!= m_htLast 
) 
3398             // what were we doing? 2 possibilities: either an arrow/shaft was 
3399             // pressed in which case we have a timer and so we just stop it or 
3400             // we were dragging the thumb 
3401             if ( m_timerScroll 
) 
3404                 m_interval 
= m_timerScroll
->GetInterval(); 
3405                 m_timerScroll
->Stop(); 
3406                 m_scrollPaused 
= true; 
3408                 // unpress the arrow 
3409                 Press(scrollbar
, false); 
3411             else // we were dragging the thumb 
3413                 // remember the current thumb position to be able to restore it 
3414                 // if the mouse returns to it later 
3415                 m_eventLastDrag 
= event
; 
3417                 // and restore the original position (before dragging) of the 
3419                 HandleThumbMove(scrollbar
, m_eventStartDrag
); 
3426     return wxStdInputHandler::HandleMouseMove(control
, event
); 
3429 #endif // wxUSE_SCROLLBAR 
3433 // ---------------------------------------------------------------------------- 
3434 // wxWin32CheckboxInputHandler 
3435 // ---------------------------------------------------------------------------- 
3437 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer 
*control
, 
3438                                             const wxKeyEvent
& event
, 
3443         wxControlAction action
; 
3444         int keycode 
= event
.GetKeyCode(); 
3448                 action 
= wxACTION_CHECKBOX_TOGGLE
; 
3452             case WXK_NUMPAD_SUBTRACT
: 
3453                 action 
= wxACTION_CHECKBOX_CHECK
; 
3457             case WXK_NUMPAD_ADD
: 
3458             case WXK_NUMPAD_EQUAL
: 
3459                 action 
= wxACTION_CHECKBOX_CLEAR
; 
3463         if ( !action
.IsEmpty() ) 
3465             control
->PerformAction(action
); 
3474 #endif // wxUSE_CHECKBOX 
3478 // ---------------------------------------------------------------------------- 
3479 // wxWin32TextCtrlInputHandler 
3480 // ---------------------------------------------------------------------------- 
3482 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer 
*control
, 
3483                                             const wxKeyEvent
& event
, 
3486     // handle only MSW-specific text bindings here, the others are handled in 
3490         int keycode 
= event
.GetKeyCode(); 
3492         wxControlAction action
; 
3493         if ( keycode 
== WXK_DELETE 
&& event
.ShiftDown() ) 
3495             action 
= wxACTION_TEXT_CUT
; 
3497         else if ( keycode 
== WXK_INSERT 
) 
3499             if ( event
.ControlDown() ) 
3500                 action 
= wxACTION_TEXT_COPY
; 
3501             else if ( event
.ShiftDown() ) 
3502                 action 
= wxACTION_TEXT_PASTE
; 
3505         if ( action 
!= wxACTION_NONE 
) 
3507             control
->PerformAction(action
); 
3513     return wxStdInputHandler::HandleKey(control
, event
, pressed
); 
3516 #endif // wxUSE_TEXTCTRL 
3520 // ---------------------------------------------------------------------------- 
3521 // wxWin32StatusBarInputHandler 
3522 // ---------------------------------------------------------------------------- 
3524 wxWin32StatusBarInputHandler:: 
3525 wxWin32StatusBarInputHandler(wxInputHandler 
*handler
) 
3526     : wxStdInputHandler(handler
) 
3531 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow 
*statbar
, 
3532                                             const wxPoint
& pt
) const 
3534     if ( statbar
->HasFlag(wxST_SIZEGRIP
) && 
3535          statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) ) 
3538             parentTLW 
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
); 
3540         wxCHECK_MSG( parentTLW
, false, 
3541                      wxT("the status bar should be a child of a TLW") ); 
3543         // a maximized window can't be resized anyhow 
3544         if ( !parentTLW
->IsMaximized() ) 
3546             // VZ: I think that the standard Windows behaviour is to only 
3547             //     show the resizing cursor when the mouse is on top of the 
3548             //     grip itself but apparently different Windows versions behave 
3549             //     differently (?) and it seems a better UI to allow resizing 
3550             //     the status bar even when the mouse is above the grip 
3551             wxSize sizeSbar 
= statbar
->GetSize(); 
3553             int diff 
= sizeSbar
.x 
- pt
.x
; 
3554             return diff 
>= 0 && diff 
< (wxCoord
)STATUSBAR_GRIP_SIZE
; 
3561 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer 
*consumer
, 
3562                                                const wxMouseEvent
& event
) 
3564     if ( event
.Button(1) ) 
3566         if ( event
.ButtonDown(1) ) 
3568             wxWindow 
*statbar 
= consumer
->GetInputWindow(); 
3570             if ( IsOnGrip(statbar
, event
.GetPosition()) ) 
3572                 wxTopLevelWindow 
*tlw 
= wxDynamicCast(statbar
->GetParent(), 
3576                     tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, 
3577                                        wxHT_TOPLEVEL_BORDER_SE
); 
3579                     statbar
->SetCursor(m_cursorOld
); 
3587     return wxStdInputHandler::HandleMouse(consumer
, event
); 
3590 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer 
*consumer
, 
3591                                                    const wxMouseEvent
& event
) 
3593     wxWindow 
*statbar 
= consumer
->GetInputWindow(); 
3595     bool isOnGrip 
= IsOnGrip(statbar
, event
.GetPosition()); 
3596     if ( isOnGrip 
!= m_isOnGrip 
) 
3598         m_isOnGrip 
= isOnGrip
; 
3601             m_cursorOld 
= statbar
->GetCursor(); 
3602             statbar
->SetCursor(wxCURSOR_SIZENWSE
); 
3606             statbar
->SetCursor(m_cursorOld
); 
3610     return wxStdInputHandler::HandleMouseMove(consumer
, event
); 
3613 #endif // wxUSE_STATUSBAR 
3615 // ---------------------------------------------------------------------------- 
3616 // wxWin32FrameInputHandler 
3617 // ---------------------------------------------------------------------------- 
3619 class wxWin32SystemMenuEvtHandler 
: public wxEvtHandler
 
3622     wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler 
*handler
); 
3624     void Attach(wxInputConsumer 
*consumer
); 
3628     DECLARE_EVENT_TABLE() 
3629     void OnSystemMenu(wxCommandEvent 
&event
); 
3630     void OnCloseFrame(wxCommandEvent 
&event
); 
3631     void OnClose(wxCloseEvent 
&event
); 
3633     wxWin32FrameInputHandler 
*m_inputHnd
; 
3634     wxTopLevelWindow         
*m_wnd
; 
3636     wxAcceleratorTable        m_oldAccelTable
; 
3640 wxWin32SystemMenuEvtHandler:: 
3641 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler 
*handler
) 
3643     m_inputHnd 
= handler
; 
3647 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer 
*consumer
) 
3649     wxASSERT_MSG( m_wnd 
== NULL
, wxT("can't attach the handler twice!") ); 
3651     m_wnd 
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
); 
3652     m_wnd
->PushEventHandler(this); 
3655     // VS: This code relies on using generic implementation of 
3656     //     wxAcceleratorTable in wxUniv! 
3657     wxAcceleratorTable table 
= *m_wnd
->GetAcceleratorTable(); 
3658     m_oldAccelTable 
= table
; 
3659     table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
)); 
3660     table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
)); 
3661     m_wnd
->SetAcceleratorTable(table
); 
3665 void wxWin32SystemMenuEvtHandler::Detach() 
3670         m_wnd
->SetAcceleratorTable(m_oldAccelTable
); 
3672         m_wnd
->RemoveEventHandler(this); 
3677 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
) 
3678     EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
) 
3679     EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
) 
3680     EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
) 
3683 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent 
&WXUNUSED(event
)) 
3686     wxAcceleratorTable table 
= *m_wnd
->GetAcceleratorTable(); 
3687     m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
); 
3691     m_inputHnd
->PopupSystemMenu(m_wnd
); 
3692 #endif // wxUSE_MENUS 
3695     m_wnd
->SetAcceleratorTable(table
); 
3699 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent 
&WXUNUSED(event
)) 
3701     m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, 
3702                          wxTOPLEVEL_BUTTON_CLOSE
); 
3705 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent 
&event
) 
3712 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler 
*handler
) 
3713                         : wxStdInputHandler(handler
) 
3715     m_menuHandler 
= new wxWin32SystemMenuEvtHandler(this); 
3718 wxWin32FrameInputHandler::~wxWin32FrameInputHandler() 
3720     if ( m_menuHandler 
) 
3722         m_menuHandler
->Detach(); 
3723         delete m_menuHandler
; 
3727 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer 
*consumer
, 
3728                                            const wxMouseEvent
& event
) 
3730     if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() ) 
3732         wxTopLevelWindow 
*tlw 
= 
3733             wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
); 
3735         long hit 
= tlw
->HitTest(event
.GetPosition()); 
3737         if ( event
.LeftDClick() && hit 
== wxHT_TOPLEVEL_TITLEBAR 
) 
3739             tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, 
3740                                tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
 
3741                                                   : wxTOPLEVEL_BUTTON_MAXIMIZE
); 
3744         else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU 
) 
3746             if ( (event
.LeftDown() && hit 
== wxHT_TOPLEVEL_ICON
) || 
3747                  (event
.RightDown() && 
3748                       (hit 
== wxHT_TOPLEVEL_TITLEBAR 
|| 
3749                        hit 
== wxHT_TOPLEVEL_ICON
)) ) 
3752                 PopupSystemMenu(tlw
); 
3753 #endif // wxUSE_MENUS 
3759     return wxStdInputHandler::HandleMouse(consumer
, event
); 
3764 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow 
*window
) const 
3768     if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX 
) 
3769         menu
.Append(wxID_RESTORE_FRAME 
, _("&Restore")); 
3770     menu
.Append(wxID_MOVE_FRAME 
, _("&Move")); 
3771     if ( window
->GetWindowStyle() & wxRESIZE_BORDER 
) 
3772         menu
.Append(wxID_RESIZE_FRAME 
, _("&Size")); 
3773     if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) ) 
3774         menu
.Append(wxID_ICONIZE_FRAME 
, _("Mi&nimize")); 
3775     if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX 
) 
3776         menu
.Append(wxID_MAXIMIZE_FRAME 
, _("Ma&ximize")); 
3777     menu
.AppendSeparator(); 
3778     menu
.Append(wxID_CLOSE_FRAME
, _("&Close") + wxT("\t") + _("Alt+") + wxT("F4")); 
3780     if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX 
) 
3782         if ( window
->IsMaximized() ) 
3784             menu
.Enable(wxID_MAXIMIZE_FRAME
, false); 
3785             menu
.Enable(wxID_MOVE_FRAME
, false); 
3786             if ( window
->GetWindowStyle() & wxRESIZE_BORDER 
) 
3787                 menu
.Enable(wxID_RESIZE_FRAME
, false); 
3790             menu
.Enable(wxID_RESTORE_FRAME
, false); 
3793     window
->PopupMenu(&menu
, wxPoint(0, 0)); 
3796 #endif // wxUSE_MENUS 
3798 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer 
*consumer
, 
3801     if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU 
) 
3803         // always detach if active frame changed: 
3804         m_menuHandler
->Detach(); 
3808             m_menuHandler
->Attach(consumer
); 
3812     return wxStdInputHandler::HandleActivation(consumer
, activated
); 
3815 #endif // wxUSE_THEME_WIN32