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     // the sizing parameters (TODO make them changeable) 
 313     wxSize m_sizeScrollbarArrow
; 
 315     // the checked and unchecked bitmaps for DrawCheckItemBitmap() 
 316     wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
]; 
 318     // the bitmaps returned by GetIndicator() 
 319     wxBitmap m_bmpIndicators
[IndicatorType_Max
] 
 320                             [IndicatorState_MaxMenu
] 
 321                             [IndicatorStatus_Max
]; 
 324     wxBitmap m_bmpFrameButtons
[FrameButton_Max
]; 
 326     // standard defaults for the above bitmaps 
 327     static const char **ms_xpmChecked
[IndicatorStatus_Max
]; 
 328     static const char **ms_xpmIndicators
[IndicatorType_Max
] 
 329                                         [IndicatorState_MaxMenu
] 
 330                                         [IndicatorStatus_Max
]; 
 331     static const char **ms_xpmFrameButtons
[FrameButton_Max
]; 
 333     // first row is for the normal state, second - for the disabled 
 334     wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
]; 
 337 // ---------------------------------------------------------------------------- 
 338 // wxWin32InputHandler and derived classes: process the keyboard and mouse 
 339 // messages according to Windows standards 
 340 // ---------------------------------------------------------------------------- 
 342 class wxWin32InputHandler 
: public wxInputHandler
 
 345     wxWin32InputHandler() { } 
 347     virtual bool HandleKey(wxInputConsumer 
*control
, 
 348                            const wxKeyEvent
& event
, 
 350     virtual bool HandleMouse(wxInputConsumer 
*control
, 
 351                              const wxMouseEvent
& event
); 
 355 class wxWin32ScrollBarInputHandler 
: public wxStdScrollBarInputHandler
 
 358     wxWin32ScrollBarInputHandler(wxRenderer 
*renderer
, 
 359                                  wxInputHandler 
*handler
); 
 361     virtual bool HandleMouse(wxInputConsumer 
*control
, 
 362                              const wxMouseEvent
& event
); 
 363     virtual bool HandleMouseMove(wxInputConsumer 
*control
, 
 364                                  const wxMouseEvent
& event
); 
 366     virtual bool OnScrollTimer(wxScrollBar 
*scrollbar
, 
 367                                const wxControlAction
& action
); 
 370     virtual void Highlight(wxScrollBar 
* WXUNUSED(scrollbar
), 
 373         // we don't highlight anything 
 376     // the first and last event which caused the thumb to move 
 377     wxMouseEvent m_eventStartDrag
, 
 380     // have we paused the scrolling because the mouse moved? 
 383     // we remember the interval of the timer to be able to restart it 
 386 #endif // wxUSE_SCROLLBAR 
 389 class wxWin32CheckboxInputHandler 
: public wxStdInputHandler
 
 392     wxWin32CheckboxInputHandler(wxInputHandler 
*handler
) 
 393         : wxStdInputHandler(handler
) { } 
 395     virtual bool HandleKey(wxInputConsumer 
*control
, 
 396                            const wxKeyEvent
& event
, 
 399 #endif // wxUSE_CHECKBOX 
 402 class wxWin32TextCtrlInputHandler 
: public wxStdInputHandler
 
 405     wxWin32TextCtrlInputHandler(wxInputHandler 
*handler
) 
 406         : wxStdInputHandler(handler
) { } 
 408     virtual bool HandleKey(wxInputConsumer 
*control
, 
 409                            const wxKeyEvent
& event
, 
 412 #endif // wxUSE_TEXTCTRL 
 414 class wxWin32StatusBarInputHandler 
: public wxStdInputHandler
 
 417     wxWin32StatusBarInputHandler(wxInputHandler 
*handler
); 
 419     virtual bool HandleMouse(wxInputConsumer 
*consumer
, 
 420                              const wxMouseEvent
& event
); 
 422     virtual bool HandleMouseMove(wxInputConsumer 
*consumer
, 
 423                                  const wxMouseEvent
& event
); 
 426     // is the given point over the statusbar grip? 
 427     bool IsOnGrip(wxWindow 
*statbar
, const wxPoint
& pt
) const; 
 430     // the cursor we had replaced with the resize one 
 431     wxCursor m_cursorOld
; 
 433     // was the mouse over the grip last time we checked? 
 437 class wxWin32SystemMenuEvtHandler
; 
 439 class wxWin32FrameInputHandler 
: public wxStdInputHandler
 
 442     wxWin32FrameInputHandler(wxInputHandler 
*handler
); 
 443     virtual ~wxWin32FrameInputHandler(); 
 445     virtual bool HandleMouse(wxInputConsumer 
*control
, 
 446                              const wxMouseEvent
& event
); 
 448     virtual bool HandleActivation(wxInputConsumer 
*consumer
, bool activated
); 
 451     void PopupSystemMenu(wxTopLevelWindow 
*window
) const; 
 452 #endif // wxUSE_MENUS 
 455     // was the mouse over the grip last time we checked? 
 456     wxWin32SystemMenuEvtHandler 
*m_menuHandler
; 
 459 // ---------------------------------------------------------------------------- 
 460 // wxWin32ColourScheme: uses (default) Win32 colours 
 461 // ---------------------------------------------------------------------------- 
 463 class wxWin32ColourScheme 
: public wxColourScheme
 
 466     virtual wxColour 
Get(StdColour col
) const; 
 467     virtual wxColour 
GetBackground(wxWindow 
*win
) const; 
 470 // ---------------------------------------------------------------------------- 
 471 // wxWin32ArtProvider 
 472 // ---------------------------------------------------------------------------- 
 474 class wxWin32ArtProvider 
: public wxArtProvider
 
 477     virtual wxBitmap 
CreateBitmap(const wxArtID
& id
, 
 478                                   const wxArtClient
& client
, 
 482 // ---------------------------------------------------------------------------- 
 484 // ---------------------------------------------------------------------------- 
 486 WX_DEFINE_ARRAY_PTR(wxInputHandler 
*, wxArrayHandlers
); 
 488 class wxWin32Theme 
: public wxTheme
 
 492     virtual ~wxWin32Theme(); 
 494     virtual wxRenderer 
*GetRenderer(); 
 495     virtual wxArtProvider 
*GetArtProvider(); 
 496     virtual wxInputHandler 
*GetInputHandler(const wxString
& control
, 
 497                                             wxInputConsumer 
*consumer
); 
 498     virtual wxColourScheme 
*GetColourScheme(); 
 501     wxWin32Renderer 
*m_renderer
; 
 503     wxWin32ArtProvider 
*m_artProvider
; 
 505     // the names of the already created handlers and the handlers themselves 
 506     // (these arrays are synchronized) 
 507     wxSortedArrayString m_handlerNames
; 
 508     wxArrayHandlers m_handlers
; 
 510     wxWin32ColourScheme 
*m_scheme
; 
 512     WX_DECLARE_THEME(win32
) 
 515 // ---------------------------------------------------------------------------- 
 517 // ---------------------------------------------------------------------------- 
 519 // frame buttons bitmaps 
 520 static const char *frame_button_close_xpm
[] = { 
 535 static const char *frame_button_help_xpm
[] = { 
 550 static const char *frame_button_maximize_xpm
[] = { 
 565 static const char *frame_button_minimize_xpm
[] = { 
 580 static const char *frame_button_restore_xpm
[] = { 
 595 const char **wxWin32Renderer::ms_xpmFrameButtons
[FrameButton_Max
] = 
 597     frame_button_close_xpm
, 
 598     frame_button_minimize_xpm
, 
 599     frame_button_maximize_xpm
, 
 600     frame_button_restore_xpm
, 
 601     frame_button_help_xpm
, 
 606 static const char *checked_menu_xpm
[] = { 
 607 /* columns rows colors chars-per-pixel */ 
 623 static const char *selected_checked_menu_xpm
[] = { 
 624 /* columns rows colors chars-per-pixel */ 
 640 static const char *disabled_checked_menu_xpm
[] = { 
 641 /* columns rows colors chars-per-pixel */ 
 658 static const char *selected_disabled_checked_menu_xpm
[] = { 
 659 /* columns rows colors chars-per-pixel */ 
 675 // checkbox and radiobox bitmaps below 
 677 static const char *checked_xpm
[] = { 
 678 /* columns rows colors chars-per-pixel */ 
 701 static const char *pressed_checked_xpm
[] = { 
 702 /* columns rows colors chars-per-pixel */ 
 724 static const char *pressed_disabled_checked_xpm
[] = { 
 725 /* columns rows colors chars-per-pixel */ 
 747 static const char *checked_item_xpm
[] = { 
 748 /* columns rows colors chars-per-pixel */ 
 769 static const char *unchecked_xpm
[] = { 
 770 /* columns rows colors chars-per-pixel */ 
 793 static const char *pressed_unchecked_xpm
[] = { 
 794 /* columns rows colors chars-per-pixel */ 
 816 static const char *unchecked_item_xpm
[] = { 
 817 /* columns rows colors chars-per-pixel */ 
 837 static const char *undetermined_xpm
[] = { 
 838 /* columns rows colors chars-per-pixel */ 
 861 static const char *pressed_undetermined_xpm
[] = { 
 862 /* columns rows colors chars-per-pixel */ 
 885 static const char *checked_radio_xpm
[] = { 
 886 /* columns rows colors chars-per-pixel */ 
 909 static const char *pressed_checked_radio_xpm
[] = { 
 910 /* columns rows colors chars-per-pixel */ 
 933 static const char *pressed_disabled_checked_radio_xpm
[] = { 
 934 /* columns rows colors chars-per-pixel */ 
 957 static const char *unchecked_radio_xpm
[] = { 
 958 /* columns rows colors chars-per-pixel */ 
 981 static const char *pressed_unchecked_radio_xpm
[] = { 
 982 /* columns rows colors chars-per-pixel */ 
1005 const char **wxWin32Renderer::ms_xpmIndicators
[IndicatorType_Max
] 
1006                                               [IndicatorState_MaxMenu
] 
1007                                               [IndicatorStatus_Max
] = 
1012         { checked_xpm
, unchecked_xpm
, undetermined_xpm 
}, 
1015         { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm 
}, 
1018         { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm 
}, 
1024         { checked_radio_xpm
, unchecked_radio_xpm
, NULL 
}, 
1027         { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL 
}, 
1030         { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL 
}, 
1036         { checked_menu_xpm
, NULL
, NULL 
}, 
1039         { selected_checked_menu_xpm
, NULL
, NULL 
}, 
1042         { disabled_checked_menu_xpm
, NULL
, NULL 
}, 
1044         // disabled selected state 
1045         { selected_disabled_checked_menu_xpm
, NULL
, NULL 
}, 
1049 const char **wxWin32Renderer::ms_xpmChecked
[IndicatorStatus_Max
] = 
1055 // ============================================================================ 
1057 // ============================================================================ 
1059 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme")); 
1061 // ---------------------------------------------------------------------------- 
1063 // ---------------------------------------------------------------------------- 
1065 wxWin32Theme::wxWin32Theme() 
1069     m_artProvider 
= NULL
; 
1072 wxWin32Theme::~wxWin32Theme() 
1076     delete m_artProvider
; 
1079 wxRenderer 
*wxWin32Theme::GetRenderer() 
1083         m_renderer 
= new wxWin32Renderer(GetColourScheme()); 
1089 wxArtProvider 
*wxWin32Theme::GetArtProvider() 
1091     if ( !m_artProvider 
) 
1093         m_artProvider 
= new wxWin32ArtProvider
; 
1096     return m_artProvider
; 
1100 wxWin32Theme::GetInputHandler(const wxString
& control
, 
1101                               wxInputConsumer 
*consumer
) 
1103     wxInputHandler 
*handler 
= NULL
; 
1104     int n 
= m_handlerNames
.Index(control
); 
1105     if ( n 
== wxNOT_FOUND 
) 
1107         static wxWin32InputHandler s_handlerDef
; 
1109         wxInputHandler 
* const 
1110           handlerStd 
= consumer
->DoGetStdInputHandler(&s_handlerDef
); 
1112         // create a new handler 
1113         if ( control 
== wxINP_HANDLER_TOPLEVEL 
) 
1115             static wxWin32FrameInputHandler 
s_handler(handlerStd
); 
1117             handler 
= &s_handler
; 
1120         else if ( control 
== wxINP_HANDLER_CHECKBOX 
) 
1122             static wxWin32CheckboxInputHandler 
s_handler(handlerStd
); 
1124             handler 
= &s_handler
; 
1126 #endif // wxUSE_CHECKBOX 
1128         else if ( control 
== wxINP_HANDLER_SCROLLBAR 
) 
1130             static wxWin32ScrollBarInputHandler
 
1131                 s_handler(GetRenderer(), handlerStd
); 
1133             handler 
= &s_handler
; 
1135 #endif // wxUSE_SCROLLBAR 
1137         else if ( control 
== wxINP_HANDLER_STATUSBAR 
) 
1139             static wxWin32StatusBarInputHandler 
s_handler(handlerStd
); 
1141             handler 
= &s_handler
; 
1143 #endif // wxUSE_STATUSBAR 
1145         else if ( control 
== wxINP_HANDLER_TEXTCTRL 
) 
1147             static wxWin32TextCtrlInputHandler 
s_handler(handlerStd
); 
1149             handler 
= &s_handler
; 
1151 #endif // wxUSE_TEXTCTRL 
1152         else // no special handler for this control 
1154             handler 
= handlerStd
; 
1157         n 
= m_handlerNames
.Add(control
); 
1158         m_handlers
.Insert(handler
, n
); 
1160     else // we already have it 
1162         handler 
= m_handlers
[n
]; 
1168 wxColourScheme 
*wxWin32Theme::GetColourScheme() 
1172         m_scheme 
= new wxWin32ColourScheme
; 
1177 // ============================================================================ 
1178 // wxWin32ColourScheme 
1179 // ============================================================================ 
1181 wxColour 
wxWin32ColourScheme::GetBackground(wxWindow 
*win
) const 
1184     if ( win
->UseBgCol() ) 
1186         // use the user specified colour 
1187         col 
= win
->GetBackgroundColour(); 
1190     if ( !win
->ShouldInheritColours() ) 
1193         wxTextCtrl 
*text 
= wxDynamicCast(win
, wxTextCtrl
); 
1194 #endif // wxUSE_TEXTCTRL 
1196         wxListBox
* listBox 
= wxDynamicCast(win
, wxListBox
); 
1197 #endif // wxUSE_LISTBOX 
1206             if ( !win
->IsEnabled() ) // not IsEditable() 
1212                     // doesn't depend on the state 
1217 #endif // wxUSE_TEXTCTRL 
1220             col 
= Get(CONTROL
); // Most controls should be this colour, not WINDOW 
1224         int flags 
= win
->GetStateFlags(); 
1226         // the colour set by the user should be used for the normal state 
1227         // and for the states for which we don't have any specific colours 
1228         if ( !col
.Ok() || (flags 
& wxCONTROL_PRESSED
) != 0 ) 
1231             if ( wxDynamicCast(win
, wxScrollBar
) ) 
1232                 col 
= Get(flags 
& wxCONTROL_PRESSED 
? SCROLLBAR_PRESSED
 
1235 #endif // wxUSE_SCROLLBAR 
1243 wxColour 
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const 
1247         // use the system colours under Windows 
1248 #if defined(__WXMSW__) 
1249         case WINDOW
:            return wxColour(GetSysColor(COLOR_WINDOW
)); 
1251         case CONTROL_PRESSED
: 
1252         case CONTROL_CURRENT
: 
1253         case CONTROL
:           return wxColour(GetSysColor(COLOR_BTNFACE
)); 
1255         case CONTROL_TEXT
:      return wxColour(GetSysColor(COLOR_BTNTEXT
)); 
1257 #if defined(COLOR_3DLIGHT) 
1258         case SCROLLBAR
:         return wxColour(GetSysColor(COLOR_3DLIGHT
)); 
1260         case SCROLLBAR
:         return wxColour(0xe0e0e0); 
1262         case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
)); 
1264         case HIGHLIGHT
:         return wxColour(GetSysColor(COLOR_HIGHLIGHT
)); 
1265         case HIGHLIGHT_TEXT
:    return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
)); 
1267 #if defined(COLOR_3DDKSHADOW) 
1268         case SHADOW_DARK
:       return wxColour(GetSysColor(COLOR_3DDKSHADOW
)); 
1270         case SHADOW_DARK
:       return wxColour(GetSysColor(COLOR_3DHADOW
)); 
1273         case CONTROL_TEXT_DISABLED
: 
1274         case SHADOW_HIGHLIGHT
:  return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
)); 
1276         case SHADOW_IN
:         return wxColour(GetSysColor(COLOR_BTNFACE
)); 
1278         case CONTROL_TEXT_DISABLED_SHADOW
: 
1279         case SHADOW_OUT
:        return wxColour(GetSysColor(COLOR_BTNSHADOW
)); 
1281         case TITLEBAR
:          return wxColour(GetSysColor(COLOR_INACTIVECAPTION
)); 
1282         case TITLEBAR_ACTIVE
:   return wxColour(GetSysColor(COLOR_ACTIVECAPTION
)); 
1283         case TITLEBAR_TEXT
:     return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
)); 
1284         case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
)); 
1286         case DESKTOP
:           return wxColour(0x808000); 
1287         case FRAME
:             return wxColour(GetSysColor(COLOR_APPWORKSPACE
)); 
1289         // use the standard Windows colours elsewhere 
1290         case WINDOW
:            return *wxWHITE
; 
1292         case CONTROL_PRESSED
: 
1293         case CONTROL_CURRENT
: 
1294         case CONTROL
:           return wxColour(0xc0c0c0); 
1296         case CONTROL_TEXT
:      return *wxBLACK
; 
1298         case SCROLLBAR
:         return wxColour(0xe0e0e0); 
1299         case SCROLLBAR_PRESSED
: return *wxBLACK
; 
1301         case HIGHLIGHT
:         return wxColour(0x800000); 
1302         case HIGHLIGHT_TEXT
:    return wxColour(0xffffff); 
1304         case SHADOW_DARK
:       return *wxBLACK
; 
1306         case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0); 
1307         case SHADOW_HIGHLIGHT
:  return wxColour(0xffffff); 
1309         case SHADOW_IN
:         return wxColour(0xc0c0c0); 
1311         case CONTROL_TEXT_DISABLED_SHADOW
: 
1312         case SHADOW_OUT
:        return wxColour(0x7f7f7f); 
1314         case TITLEBAR
:          return wxColour(0xaeaaae); 
1315         case TITLEBAR_ACTIVE
:   return wxColour(0x820300); 
1316         case TITLEBAR_TEXT
:     return wxColour(0xc0c0c0); 
1317         case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
; 
1319         case DESKTOP
:           return wxColour(0x808000); 
1320         case FRAME
:             return wxColour(0x808080); 
1323         case GAUGE
:             return Get(HIGHLIGHT
); 
1327             wxFAIL_MSG(_T("invalid standard colour")); 
1332 // ============================================================================ 
1334 // ============================================================================ 
1336 // ---------------------------------------------------------------------------- 
1338 // ---------------------------------------------------------------------------- 
1340 wxWin32Renderer::wxWin32Renderer(const wxColourScheme 
*scheme
) 
1341                : wxStdRenderer(scheme
) 
1344     m_sizeScrollbarArrow 
= wxSize(16, 16); 
1346     // init the arrow bitmaps 
1347     static const size_t ARROW_WIDTH 
= 7; 
1348     static const size_t ARROW_LENGTH 
= 4; 
1351     wxMemoryDC dcNormal
, 
1354     for ( size_t n 
= 0; n 
< Arrow_Max
; n
++ ) 
1356         bool isVertical 
= n 
> Arrow_Right
; 
1369         // disabled arrow is larger because of the shadow 
1370         m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
); 
1371         m_bmpArrows
[Arrow_Disabled
][n
].Create(w 
+ 1, h 
+ 1); 
1373         dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]); 
1374         dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]); 
1376         dcNormal
.SetBackground(*wxWHITE_BRUSH
); 
1377         dcDisabled
.SetBackground(*wxWHITE_BRUSH
); 
1381         dcNormal
.SetPen(m_penBlack
); 
1382         dcDisabled
.SetPen(m_penDarkGrey
); 
1384         // calculate the position of the point of the arrow 
1388             x1 
= (ARROW_WIDTH 
- 1)/2; 
1389             y1 
= n 
== Arrow_Up 
? 0 : ARROW_LENGTH 
- 1; 
1393             x1 
= n 
== Arrow_Left 
? 0 : ARROW_LENGTH 
- 1; 
1394             y1 
= (ARROW_WIDTH 
- 1)/2; 
1405         for ( size_t i 
= 0; i 
< ARROW_LENGTH
; i
++ ) 
1407             dcNormal
.DrawLine(x1
, y1
, x2
, y2
); 
1408             dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1415                 if ( n 
== Arrow_Up 
) 
1426             else // left or right arrow 
1431                 if ( n 
== Arrow_Left 
) 
1444         // draw the shadow for the disabled one 
1445         dcDisabled
.SetPen(m_penHighlight
); 
1450                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1454                 x1 
= ARROW_LENGTH 
- 1; 
1455                 y1 
= (ARROW_WIDTH 
- 1)/2 + 1; 
1458                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1459                 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
); 
1464                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1468                 x1 
= ARROW_WIDTH 
- 1; 
1470                 x2 
= (ARROW_WIDTH 
- 1)/2; 
1472                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1473                 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
); 
1478         // create the inverted bitmap but only for the right arrow as we only 
1479         // use it for the menus 
1480         if ( n 
== Arrow_Right 
) 
1482             m_bmpArrows
[Arrow_Inverted
][n
].Create(w
, h
); 
1483             dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inverted
][n
]); 
1485             dcInverse
.Blit(0, 0, w
, h
, 
1488             dcInverse
.SelectObject(wxNullBitmap
); 
1490             mask 
= new wxMask(m_bmpArrows
[Arrow_Inverted
][n
], *wxBLACK
); 
1491             m_bmpArrows
[Arrow_Inverted
][n
].SetMask(mask
); 
1493             m_bmpArrows
[Arrow_InvertedDisabled
][n
].Create(w
, h
); 
1494             dcInverse
.SelectObject(m_bmpArrows
[Arrow_InvertedDisabled
][n
]); 
1496             dcInverse
.Blit(0, 0, w
, h
, 
1499             dcInverse
.SelectObject(wxNullBitmap
); 
1501             mask 
= new wxMask(m_bmpArrows
[Arrow_InvertedDisabled
][n
], *wxBLACK
); 
1502             m_bmpArrows
[Arrow_InvertedDisabled
][n
].SetMask(mask
); 
1505         dcNormal
.SelectObject(wxNullBitmap
); 
1506         dcDisabled
.SelectObject(wxNullBitmap
); 
1508         mask 
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
); 
1509         m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
); 
1510         mask 
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
); 
1511         m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
); 
1513         m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
]; 
1517 bool wxWin32Renderer::AreScrollbarsInsideBorder() const 
1522 // ---------------------------------------------------------------------------- 
1524 // ---------------------------------------------------------------------------- 
1526 void wxWin32Renderer::DrawLabel(wxDC
& dc
, 
1527                                 const wxString
& label
, 
1534     // the underscores are not drawn for focused controls in wxMSW 
1535     if ( flags 
& wxCONTROL_FOCUSED 
) 
1540     if ( flags 
& wxCONTROL_DISABLED 
) 
1542         // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED 
1543         // currently only can happen for a menu item and it seems that Windows 
1544         // doesn't draw the shadow in this case, so we don't do it neither 
1545         if ( flags 
& wxCONTROL_SELECTED 
) 
1547             // just make the label text greyed out 
1548             dc
.SetTextForeground(m_penDarkGrey
.GetColour()); 
1550             flags 
&= ~wxCONTROL_DISABLED
; 
1554     wxStdRenderer::DrawLabel(dc
, label
, rect
, flags
, alignment
, 
1555                              indexAccel
, rectBounds
); 
1558 void wxWin32Renderer::DrawFrameWithLabel(wxDC
& dc
, 
1559                                          const wxString
& label
, 
1560                                          const wxRect
& rectFrame
, 
1561                                          const wxRect
& rectText
, 
1567     label2 
<< _T(' ') << label 
<< _T(' '); 
1568     if ( indexAccel 
!= -1 ) 
1570         // adjust it as we prepended a space 
1574     wxStdRenderer::DrawFrameWithLabel(dc
, label2
, rectFrame
, rectText
, 
1575                                       flags
, alignment
, indexAccel
); 
1578 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
, 
1579                                       const wxString
& label
, 
1580                                       const wxBitmap
& image
, 
1587     // the underscores are not drawn for focused controls in wxMSW 
1588     if ( flags 
& wxCONTROL_PRESSED 
) 
1593     wxStdRenderer::DrawButtonLabel(dc
, label
, image
, rect
, flags
, alignment
, 
1594                                    indexAccel
, rectBounds
); 
1597 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
, 
1598                                        const wxRect
& rectTotal
, 
1602     wxRect rect 
= rectTotal
; 
1604     wxPen 
penOut(*wxBLACK
); 
1605     if ( flags 
& wxCONTROL_PRESSED 
) 
1607         // button pressed: draw a double border around it 
1608         DrawRect(dc
, &rect
, penOut
); 
1609         DrawRect(dc
, &rect
, m_penDarkGrey
); 
1611     else // button not pressed 
1613         if ( flags 
& (wxCONTROL_FOCUSED 
| wxCONTROL_ISDEFAULT
) ) 
1615             // button either default or focused (or both): add an extra border 
1617             DrawRect(dc
, &rect
, penOut
); 
1620         // now draw a normal button border 
1621         DrawRaisedBorder(dc
, &rect
); 
1628 // ---------------------------------------------------------------------------- 
1629 // (check)listbox items 
1630 // ---------------------------------------------------------------------------- 
1632 void wxWin32Renderer::DrawCheckItemBitmap(wxDC
& dc
, 
1633                                           const wxBitmap
& bitmap
, 
1642     else // use default bitmap 
1644         IndicatorStatus i 
= flags 
& wxCONTROL_CHECKED
 
1645                                 ? IndicatorStatus_Checked
 
1646                                 : IndicatorStatus_Unchecked
; 
1648         if ( !m_bmpCheckBitmaps
[i
].Ok() ) 
1650             m_bmpCheckBitmaps
[i
] = wxBitmap(ms_xpmChecked
[i
]); 
1653         bmp 
= m_bmpCheckBitmaps
[i
]; 
1656     dc
.DrawBitmap(bmp
, rect
.x
, rect
.y 
+ (rect
.height 
- bmp
.GetHeight()) / 2 - 1, 
1657                   true /* use mask */); 
1660 // ---------------------------------------------------------------------------- 
1661 // check/radio buttons 
1662 // ---------------------------------------------------------------------------- 
1664 wxBitmap 
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
) 
1666     IndicatorState indState
; 
1667     IndicatorStatus indStatus
; 
1668     GetIndicatorsFromFlags(flags
, indState
, indStatus
); 
1670     wxBitmap
& bmp 
= m_bmpIndicators
[indType
][indState
][indStatus
]; 
1673         const char **xpm 
= ms_xpmIndicators
[indType
][indState
][indStatus
]; 
1676             // create and cache it 
1677             bmp 
= wxBitmap(xpm
); 
1684 // ---------------------------------------------------------------------------- 
1686 // ---------------------------------------------------------------------------- 
1689 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
, 
1690                                         const wxString
& label
, 
1691                                         const wxBitmap
& bitmap
, 
1692                                         const wxRect
& rectOrig
, 
1697     if (style 
== wxTOOL_STYLE_BUTTON
) 
1699         wxRect rect 
= rectOrig
; 
1700         rect
.Deflate(BORDER_THICKNESS
); 
1702         if ( flags 
& wxCONTROL_PRESSED 
) 
1704             DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
); 
1706         else if ( flags 
& wxCONTROL_CURRENT 
) 
1708             DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
); 
1711         if(tbarStyle 
& wxTB_TEXT
) 
1713             if(tbarStyle 
& wxTB_HORIZONTAL
) 
1715                 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
); 
1719                 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
); 
1724             int xpoint 
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2; 
1725             int ypoint 
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2; 
1726             dc
.DrawBitmap(bitmap
, xpoint
, ypoint
, bitmap
.GetMask() != NULL
); 
1729     else if (style 
== wxTOOL_STYLE_SEPARATOR
) 
1731         // leave a small gap aroudn the line, also account for the toolbar 
1733         if(rectOrig
.height 
> rectOrig
.width
) 
1736             DrawVerticalLine(dc
, rectOrig
.x 
+ rectOrig
.width
/2, 
1737                              rectOrig
.y 
+ 2*BORDER_THICKNESS
, 
1738                              rectOrig
.GetBottom() - BORDER_THICKNESS
); 
1743             DrawHorizontalLine(dc
, rectOrig
.y 
+ rectOrig
.height
/2, 
1744                          rectOrig
.x 
+ 2*BORDER_THICKNESS
, 
1745                          rectOrig
.GetRight() - BORDER_THICKNESS
); 
1748     // don't draw wxTOOL_STYLE_CONTROL 
1750 #endif // wxUSE_TOOLBAR 
1752 // ---------------------------------------------------------------------------- 
1754 // ---------------------------------------------------------------------------- 
1758 void wxWin32Renderer::DrawTab(wxDC
& dc
, 
1759                               const wxRect
& rectOrig
, 
1761                               const wxString
& label
, 
1762                               const wxBitmap
& bitmap
, 
1766     #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X ) 
1767     #define REVERSE_FOR_VERTICAL(X,Y) \ 
1768         SELECT_FOR_VERTICAL(X,Y)      \ 
1770         SELECT_FOR_VERTICAL(Y,X) 
1772     wxRect rect 
= rectOrig
; 
1774     bool isVertical 
= ( dir 
== wxLEFT 
) || ( dir 
== wxRIGHT 
); 
1776     // the current tab is drawn indented (to the top for default case) and 
1777     // bigger than the other ones 
1778     const wxSize indent 
= GetTabIndent(); 
1779     if ( flags 
& wxCONTROL_SELECTED 
) 
1781         rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x 
, 0), 
1782                       SELECT_FOR_VERTICAL( 0, indent
.y 
)); 
1786                 wxFAIL_MSG(_T("invaild notebook tab orientation")); 
1793                 rect
.height 
+= indent
.y
; 
1800                 rect
.width 
+= indent
.x
; 
1805     // draw the text, image and the focus around them (if necessary) 
1806     wxRect 
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
), 
1807                       REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
) 
1809     rectLabel
.Deflate(1, 1); 
1812         // draw it horizontally into memory and rotate for screen 
1814         wxBitmap bitmapRotated
, 
1815                  bitmapMem( rectLabel
.x 
+ rectLabel
.width
, 
1816                             rectLabel
.y 
+ rectLabel
.height 
); 
1817         dcMem
.SelectObject(bitmapMem
); 
1818         dcMem
.SetBackground(dc
.GetBackground()); 
1819         dcMem
.SetFont(dc
.GetFont()); 
1820         dcMem
.SetTextForeground(dc
.GetTextForeground()); 
1824                         wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) ) 
1827 #endif // wxUSE_IMAGE 
1829         DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
, 
1830                         flags
, wxALIGN_CENTRE
, indexAccel
); 
1831         dcMem
.SelectObject(wxNullBitmap
); 
1832         bitmapMem 
= bitmapMem
.GetSubBitmap(rectLabel
); 
1834         bitmapMem 
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
)); 
1835 #endif // wxUSE_IMAGE 
1836         dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false); 
1840         DrawButtonLabel(dc
, label
, bitmap
, rectLabel
, 
1841                         flags
, wxALIGN_CENTRE
, indexAccel
); 
1844     // now draw the tab border itself (maybe use DrawRoundedRectangle()?) 
1845     static const wxCoord CUTOFF 
= 2; // radius of the rounded corner 
1846     wxCoord x 
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
), 
1847             y 
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
), 
1848             x2 
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()), 
1849             y2 
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight()); 
1851     // FIXME: all this code will break if the tab indent or the border width, 
1852     //        it is tied to the fact that both of them are equal to 2 
1858             // left orientation looks like top but IsVertical makes x and y reversed 
1860             // top is not vertical so use coordinates in written order 
1861             dc
.SetPen(m_penHighlight
); 
1862             dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
), 
1863                         REVERSE_FOR_VERTICAL(x
, y 
+ CUTOFF
)); 
1864             dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y 
+ CUTOFF
), 
1865                         REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y
)); 
1866             dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y
), 
1867                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF 
+ 1, y
)); 
1869             dc
.SetPen(m_penBlack
); 
1870             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
), 
1871                         REVERSE_FOR_VERTICAL(x2
, y 
+ CUTOFF
)); 
1872             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y 
+ CUTOFF
), 
1873                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF
, y
)); 
1875             dc
.SetPen(m_penDarkGrey
); 
1876             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2 
- 1, y2
), 
1877                         REVERSE_FOR_VERTICAL(x2 
- 1, y 
+ CUTOFF 
- 1)); 
1879             if ( flags 
& wxCONTROL_SELECTED 
) 
1881                 dc
.SetPen(m_penLightGrey
); 
1883                 // overwrite the part of the border below this tab 
1884                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y2 
+ 1), 
1885                             REVERSE_FOR_VERTICAL(x2 
- 1, y2 
+ 1)); 
1887                 // and the shadow of the tab to the left of us 
1888                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y 
+ CUTOFF 
+ 1), 
1889                             REVERSE_FOR_VERTICAL(x 
+ 1, y2 
+ 1)); 
1894             // right orientation looks like bottom but IsVertical makes x and y reversed 
1896             // bottom is not vertical so use coordinates in written order 
1897             dc
.SetPen(m_penHighlight
); 
1898             // we need to continue one pixel further to overwrite the corner of 
1899             // the border for the selected tab 
1900             dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y 
- (flags 
& wxCONTROL_SELECTED 
? 1 : 0)), 
1901                         REVERSE_FOR_VERTICAL(x
, y2 
- CUTOFF
)); 
1902             dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2 
- CUTOFF
), 
1903                         REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y2
)); 
1905             dc
.SetPen(m_penBlack
); 
1906             dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y2
), 
1907                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF 
+ 1, y2
)); 
1908             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
), 
1909                         REVERSE_FOR_VERTICAL(x2
, y2 
- CUTOFF
)); 
1910             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2 
- CUTOFF
), 
1911                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF
, y2
)); 
1913             dc
.SetPen(m_penDarkGrey
); 
1914             dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y2 
- 1), 
1915                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF 
+ 1, y2 
- 1)); 
1916             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2 
- 1, y
), 
1917                         REVERSE_FOR_VERTICAL(x2 
- 1, y2 
- CUTOFF 
+ 1)); 
1919             if ( flags 
& wxCONTROL_SELECTED 
) 
1921                 dc
.SetPen(m_penLightGrey
); 
1923                 // overwrite the part of the (double!) border above this tab 
1924                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y 
- 1), 
1925                             REVERSE_FOR_VERTICAL(x2 
- 1, y 
- 1)); 
1926                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y 
- 2), 
1927                             REVERSE_FOR_VERTICAL(x2 
- 1, y 
- 2)); 
1929                 // and the shadow of the tab to the left of us 
1930                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y2 
- CUTOFF
), 
1931                             REVERSE_FOR_VERTICAL(x 
+ 1, y 
- 1)); 
1936     #undef SELECT_FOR_VERTICAL 
1937     #undef REVERSE_FOR_VERTICAL 
1940 #endif // wxUSE_NOTEBOOK 
1944 // ---------------------------------------------------------------------------- 
1946 // ---------------------------------------------------------------------------- 
1949 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
), 
1951                                     wxOrientation orient
) const 
1954     wxCoord width  
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2; 
1955     wxCoord height 
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
); 
1957     if (orient 
== wxHORIZONTAL
) 
1971 wxRect 
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
, 
1973                                            wxOrientation orient
, 
1976     bool transpose 
= (orient 
== wxVERTICAL
); 
1977     bool left  
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
1978                  (((style 
& wxSL_TOP
) != 0) & !transpose 
| 
1979                   ((style 
& wxSL_LEFT
) != 0) & transpose 
| 
1980                   ((style 
& wxSL_BOTH
) != 0)); 
1981     bool right 
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
1982                  (((style 
& wxSL_BOTTOM
) != 0) & !transpose 
| 
1983                   ((style 
& wxSL_RIGHT
) != 0) & transpose 
| 
1984                   ((style 
& wxSL_BOTH
) != 0)); 
1986     wxRect rect 
= rectOrig
; 
1988     wxSize sizeThumb 
= GetSliderThumbSize (rect
, lenThumb
, orient
); 
1990     if (orient 
== wxHORIZONTAL
) { 
1991         rect
.x 
+= SLIDER_MARGIN
; 
1994             rect
.y 
+= wxMax ((rect
.height 
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2); 
1998             rect
.y 
+= wxMax ((rect
.height 
- 2*BORDER_THICKNESS 
- sizeThumb
.y
/2), sizeThumb
.y
/2); 
2002             rect
.y 
+= sizeThumb
.y
/2; 
2004         rect
.width 
-= 2*SLIDER_MARGIN
; 
2005         rect
.height 
= 2*BORDER_THICKNESS
; 
2009         rect
.y 
+= SLIDER_MARGIN
; 
2012             rect
.x 
+= wxMax ((rect
.width 
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2); 
2016             rect
.x 
+= wxMax ((rect
.width 
- 2*BORDER_THICKNESS 
- sizeThumb
.x
/2), sizeThumb
.x
/2); 
2020             rect
.x 
+= sizeThumb
.x
/2; 
2022         rect
.width 
= 2*BORDER_THICKNESS
; 
2023         rect
.height 
-= 2*SLIDER_MARGIN
; 
2029 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
, 
2030                                       const wxRect
& rectOrig
, 
2032                                       wxOrientation orient
, 
2037     /*    show shaft geometry 
2055     if (flags 
& wxCONTROL_FOCUSED
) { 
2056         DrawFocusRect(NULL
, dc
, rectOrig
); 
2059     wxRect rect 
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
); 
2061     if (rectShaft
) *rectShaft 
= rect
; 
2063     DrawSunkenBorder(dc
, &rect
); 
2066 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
, 
2068                                       wxOrientation orient
, 
2072     /*    show thumb geometry 
2081        H         D B   where H is highlight colour 
2095        The interior of this shape is filled with the hatched brush if the thumb 
2099     DrawBackground(dc
, wxNullColour
, rect
, flags
); 
2101     bool transpose 
= (orient 
== wxVERTICAL
); 
2102     bool left  
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2103                  (((style 
& wxSL_TOP
) != 0) & !transpose 
| 
2104                   ((style 
& wxSL_LEFT
) != 0) & transpose
) & 
2105                  ((style 
& wxSL_BOTH
) == 0); 
2106     bool right 
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2107                  (((style 
& wxSL_BOTTOM
) != 0) & !transpose 
| 
2108                   ((style 
& wxSL_RIGHT
) != 0) & transpose
) & 
2109                  ((style 
& wxSL_BOTH
) == 0); 
2111     wxCoord sizeArrow 
= (transpose 
? rect
.height 
: rect
.width
) / 2; 
2112     wxCoord c 
= ((transpose 
? rect
.height 
: rect
.width
) - 2*sizeArrow
); 
2114     wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
; 
2115     x1 
= (transpose 
? rect
.y 
: rect
.x
); 
2116     x2 
= (transpose 
? rect
.GetBottom() : rect
.GetRight()); 
2117     x3 
= (x1
-1+c
) + sizeArrow
; 
2118     y1 
= (transpose 
? rect
.x 
: rect
.y
); 
2119     y2 
= (transpose 
? rect
.GetRight() : rect
.GetBottom()); 
2120     y3 
= (left  
? (y1
-1+c
) + sizeArrow 
: y1
); 
2121     y4 
= (right 
? (y2
+1-c
) - sizeArrow 
: y2
); 
2123     dc
.SetPen(m_penBlack
); 
2125         DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
); 
2127     DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
); 
2130         DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
); 
2134         DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
); 
2137     dc
.SetPen(m_penDarkGrey
); 
2138     DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
); 
2140         DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
); 
2144         DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
); 
2147     dc
.SetPen(m_penHighlight
); 
2150         DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
); 
2151         DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
); 
2155         DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
); 
2157     DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
); 
2160         DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
); 
2163     if (flags 
& wxCONTROL_PRESSED
) { 
2164         // TODO: MSW fills the entire area inside, not just the rect 
2165         wxRect rectInt 
= rect
; 
2168             rectInt
.SetLeft(y3
); 
2169             rectInt
.SetRight(y4
); 
2174             rectInt
.SetBottom(y4
); 
2178 #if !defined(__WXMGL__) 
2179         static const char *stipple_xpm
[] = { 
2180             /* columns rows colors chars-per-pixel */ 
2189         // VS: MGL can only do 8x8 stipple brushes 
2190         static const char *stipple_xpm
[] = { 
2191             /* columns rows colors chars-per-pixel */ 
2206         dc
.SetBrush(wxBrush(stipple_xpm
)); 
2208         dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
)); 
2209         dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
)); 
2210         dc
.SetPen(*wxTRANSPARENT_PEN
); 
2211         dc
.DrawRectangle(rectInt
); 
2215 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
, 
2218                                       wxOrientation orient
, 
2222                                       int WXUNUSED(flags
), 
2225     /*    show ticks geometry 
2240     if (end 
== start
) return; 
2242     bool transpose 
= (orient 
== wxVERTICAL
); 
2243     bool left  
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2244                  (((style 
& wxSL_TOP
) != 0) & !transpose 
| 
2245                   ((style 
& wxSL_LEFT
) != 0) & transpose 
| 
2246                   ((style 
& wxSL_BOTH
) != 0)); 
2247     bool right 
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2248                  (((style 
& wxSL_BOTTOM
) != 0) & !transpose 
| 
2249                   ((style 
& wxSL_RIGHT
) != 0) & transpose 
| 
2250                   ((style 
& wxSL_BOTH
) != 0)); 
2252     // default thumb size 
2253     wxSize sizeThumb 
= GetSliderThumbSize (rect
, 0, orient
); 
2254     wxCoord defaultLen 
= (transpose 
? sizeThumb
.x 
: sizeThumb
.y
); 
2256     // normal thumb size 
2257     sizeThumb 
= GetSliderThumbSize (rect
, lenThumb
, orient
); 
2258     wxCoord widthThumb  
= (transpose 
? sizeThumb
.y 
: sizeThumb
.x
); 
2260     wxRect rectShaft 
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
); 
2262     wxCoord x1
, x2
, y1
, y2
, y3
, y4 
, len
; 
2263     x1 
= (transpose 
? rectShaft
.y 
: rectShaft
.x
) + widthThumb
/2; 
2264     x2 
= (transpose 
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2; 
2265     y1 
= (transpose 
? rectShaft
.x 
: rectShaft
.y
) - defaultLen
/2; 
2266     y2 
= (transpose 
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2; 
2267     y3 
= (transpose 
? rect
.x 
: rect
.y
); 
2268     y4 
= (transpose 
? rect
.GetRight() : rect
.GetBottom()); 
2271     dc
.SetPen(m_penBlack
); 
2273     int range 
= end 
- start
; 
2274     for ( int n 
= 0; n 
< range
; n 
+= step 
) { 
2275         wxCoord x 
= x1 
+ (len
*n
) / range
; 
2277         if (left 
& (y1 
> y3
)) { 
2278             DrawLine(dc
, x
, y1
, x
, y3
, orient 
== wxVERTICAL
); 
2280         if (right 
& (y4 
> y2
)) { 
2281             DrawLine(dc
, x
, y2
, x
, y4
, orient 
== wxVERTICAL
); 
2284     // always draw the line at the end position 
2285     if (left 
& (y1 
> y3
)) { 
2286         DrawLine(dc
, x2
, y1
, x2
, y3
, orient 
== wxVERTICAL
); 
2288     if (right 
& (y4 
> y2
)) { 
2289         DrawLine(dc
, x2
, y2
, x2
, y4
, orient 
== wxVERTICAL
); 
2293 #endif // wxUSE_SLIDER 
2297 // ---------------------------------------------------------------------------- 
2299 // ---------------------------------------------------------------------------- 
2301 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer 
2302 class WXDLLEXPORT wxWin32MenuGeometryInfo 
: public wxMenuGeometryInfo
 
2305     virtual wxSize 
GetSize() const { return m_size
; } 
2307     wxCoord 
GetLabelOffset() const { return m_ofsLabel
; } 
2308     wxCoord 
GetAccelOffset() const { return m_ofsAccel
; } 
2310     wxCoord 
GetItemHeight() const { return m_heightItem
; } 
2313     // the total size of the menu 
2316     // the offset of the start of the menu item label 
2319     // the offset of the start of the accel label 
2322     // the height of a normal (not separator) item 
2323     wxCoord m_heightItem
; 
2325     friend wxMenuGeometryInfo 
* 
2326         wxWin32Renderer::GetMenuGeometry(wxWindow 
*, const wxMenu
&) const; 
2329 // FIXME: all constants are hardcoded but shouldn't be 
2330 static const wxCoord MENU_LEFT_MARGIN 
= 9; 
2331 static const wxCoord MENU_RIGHT_MARGIN 
= 18; 
2332 static const wxCoord MENU_VERT_MARGIN 
= 3; 
2334 // the margin around bitmap/check marks (on each side) 
2335 static const wxCoord MENU_BMP_MARGIN 
= 2; 
2337 // the margin between the labels and accel strings 
2338 static const wxCoord MENU_ACCEL_MARGIN 
= 8; 
2340 // the separator height in pixels: in fact, strangely enough, the real height 
2341 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into 
2343 static const wxCoord MENU_SEPARATOR_HEIGHT 
= 3; 
2345 // the size of the standard checkmark bitmap 
2346 static const wxCoord MENU_CHECK_SIZE 
= 9; 
2348 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
, 
2349                                       const wxRect
& rectOrig
, 
2350                                       const wxString
& label
, 
2354     wxRect rect 
= rectOrig
; 
2357     wxDCTextColourChanger 
colChanger(dc
); 
2359     if ( flags 
& wxCONTROL_SELECTED 
) 
2361         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
2363         const wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
2366         dc
.DrawRectangle(rect
); 
2369     // don't draw the focus rect around menu bar items 
2370     DrawLabel(dc
, label
, rect
, flags 
& ~wxCONTROL_FOCUSED
, 
2371               wxALIGN_CENTRE
, indexAccel
); 
2374 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
, 
2376                                    const wxMenuGeometryInfo
& gi
, 
2377                                    const wxString
& label
, 
2378                                    const wxString
& accel
, 
2379                                    const wxBitmap
& bitmap
, 
2383     const wxWin32MenuGeometryInfo
& geometryInfo 
= 
2384         (const wxWin32MenuGeometryInfo
&)gi
; 
2389     rect
.width 
= geometryInfo
.GetSize().x
; 
2390     rect
.height 
= geometryInfo
.GetItemHeight(); 
2392     // draw the selected item specially 
2393     wxDCTextColourChanger 
colChanger(dc
); 
2394     if ( flags 
& wxCONTROL_SELECTED 
) 
2396         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
2398         const wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
2401         dc
.DrawRectangle(rect
); 
2404     // draw the bitmap: use the bitmap provided or the standard checkmark for 
2405     // the checkable items 
2406     wxBitmap bmp 
= bitmap
; 
2407     if ( !bmp
.Ok() && (flags 
& wxCONTROL_CHECKED
) ) 
2409         bmp 
= GetIndicator(IndicatorType_Menu
, flags
); 
2414         rect
.SetRight(geometryInfo
.GetLabelOffset()); 
2415         wxControlRenderer::DrawBitmap(dc
, bmp
, rect
); 
2419     rect
.x 
= geometryInfo
.GetLabelOffset(); 
2420     rect
.SetRight(geometryInfo
.GetAccelOffset()); 
2422     DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
); 
2424     // draw the accel string 
2425     rect
.x 
= geometryInfo
.GetAccelOffset(); 
2426     rect
.SetRight(geometryInfo
.GetSize().x
); 
2428     // NB: no accel index here 
2429     DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
); 
2431     // draw the submenu indicator 
2432     if ( flags 
& wxCONTROL_ISSUBMENU 
) 
2434         rect
.x 
= geometryInfo
.GetSize().x 
- MENU_RIGHT_MARGIN
; 
2435         rect
.width 
= MENU_RIGHT_MARGIN
; 
2437         ArrowStyle arrowStyle
; 
2438         if ( flags 
& wxCONTROL_DISABLED 
) 
2439             arrowStyle 
= flags 
& wxCONTROL_SELECTED 
? Arrow_InvertedDisabled
 
2441         else if ( flags 
& wxCONTROL_SELECTED 
) 
2442             arrowStyle 
= Arrow_Inverted
; 
2444             arrowStyle 
= Arrow_Normal
; 
2446         DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
); 
2450 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
, 
2452                                         const wxMenuGeometryInfo
& geomInfo
) 
2454     DrawHorizontalLine(dc
, y 
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
); 
2457 wxSize 
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const 
2459     wxSize size 
= sizeText
; 
2461     // FIXME: menubar height is configurable under Windows 
2468 wxMenuGeometryInfo 
*wxWin32Renderer::GetMenuGeometry(wxWindow 
*win
, 
2469                                                      const wxMenu
& menu
) const 
2471     // prepare the dc: for now we draw all the items with the system font 
2473     dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
2475     // the height of a normal item 
2476     wxCoord heightText 
= dc
.GetCharHeight(); 
2481     // the max length of label and accel strings: the menu width is the sum of 
2482     // them, even if they're for different items (as the accels should be 
2485     // the max length of the bitmap is never 0 as Windows always leaves enough 
2486     // space for a check mark indicator 
2487     wxCoord widthLabelMax 
= 0, 
2489             widthBmpMax 
= MENU_LEFT_MARGIN
; 
2491     for ( wxMenuItemList::compatibility_iterator node 
= menu
.GetMenuItems().GetFirst(); 
2493           node 
= node
->GetNext() ) 
2495         // height of this item 
2498         wxMenuItem 
*item 
= node
->GetData(); 
2499         if ( item
->IsSeparator() ) 
2501             h 
= MENU_SEPARATOR_HEIGHT
; 
2503         else // not separator 
2508             dc
.GetTextExtent(item
->GetItemLabelText(), &widthLabel
, NULL
); 
2509             if ( widthLabel 
> widthLabelMax 
) 
2511                 widthLabelMax 
= widthLabel
; 
2515             dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
); 
2516             if ( widthAccel 
> widthAccelMax 
) 
2518                 widthAccelMax 
= widthAccel
; 
2521             const wxBitmap
& bmp 
= item
->GetBitmap(); 
2524                 wxCoord widthBmp 
= bmp
.GetWidth(); 
2525                 if ( widthBmp 
> widthBmpMax 
) 
2526                     widthBmpMax 
= widthBmp
; 
2528             //else if ( item->IsCheckable() ): no need to check for this as 
2529             // MENU_LEFT_MARGIN is big enough to show the check mark 
2532         h 
+= 2*MENU_VERT_MARGIN
; 
2534         // remember the item position and height 
2535         item
->SetGeometry(height
, h
); 
2540     // bundle the metrics into a struct and return it 
2541     wxWin32MenuGeometryInfo 
*gi 
= new wxWin32MenuGeometryInfo
; 
2543     gi
->m_ofsLabel 
= widthBmpMax 
+ 2*MENU_BMP_MARGIN
; 
2544     gi
->m_ofsAccel 
= gi
->m_ofsLabel 
+ widthLabelMax
; 
2545     if ( widthAccelMax 
> 0 ) 
2547         // if we actually have any accesl, add a margin 
2548         gi
->m_ofsAccel 
+= MENU_ACCEL_MARGIN
; 
2551     gi
->m_heightItem 
= heightText 
+ 2*MENU_VERT_MARGIN
; 
2553     gi
->m_size
.x 
= gi
->m_ofsAccel 
+ widthAccelMax 
+ MENU_RIGHT_MARGIN
; 
2554     gi
->m_size
.y 
= height
; 
2559 #endif // wxUSE_MENUS 
2563 // ---------------------------------------------------------------------------- 
2565 // ---------------------------------------------------------------------------- 
2567 void wxWin32Renderer::DrawStatusField(wxDC
& dc
, 
2569                                       const wxString
& label
, 
2575     if ( flags 
& wxCONTROL_SIZEGRIP 
) 
2577         // draw the size grip: it is a normal rect except that in the lower 
2578         // right corner we have several bands which may be used for dragging 
2579         // the status bar corner 
2581         // each band consists of 4 stripes: m_penHighlight, double 
2582         // m_penDarkGrey and transparent one 
2583         wxCoord x2 
= rect
.GetRight(), 
2584                 y2 
= rect
.GetBottom(); 
2586         // draw the upper left part of the rect normally 
2587         if (style 
!= wxSB_FLAT
) 
2589             if (style 
== wxSB_RAISED
) 
2590                 dc
.SetPen(m_penHighlight
); 
2592                 dc
.SetPen(m_penDarkGrey
); 
2593             dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
); 
2594             dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop()); 
2597         // draw the grey stripes of the grip 
2599         wxCoord ofs 
= WIDTH_STATUSBAR_GRIP_BAND 
- 1; 
2600         for ( n 
= 0; n 
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs 
+= WIDTH_STATUSBAR_GRIP_BAND 
) 
2602             dc
.DrawLine(x2 
- ofs 
+ 1, y2 
- 1, x2
, y2 
- ofs
); 
2603             dc
.DrawLine(x2 
- ofs
, y2 
- 1, x2
, y2 
- ofs 
- 1); 
2606         // draw the white stripes 
2607         dc
.SetPen(m_penHighlight
); 
2608         ofs 
= WIDTH_STATUSBAR_GRIP_BAND 
+ 1; 
2609         for ( n 
= 0; n 
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs 
+= WIDTH_STATUSBAR_GRIP_BAND 
) 
2611             dc
.DrawLine(x2 
- ofs 
+ 1, y2 
- 1, x2
, y2 
- ofs
); 
2614         // draw the remaining rect boundaries 
2615         if (style 
!= wxSB_FLAT
) 
2617             if (style 
== wxSB_RAISED
) 
2618                 dc
.SetPen(m_penDarkGrey
); 
2620                 dc
.SetPen(m_penHighlight
); 
2621             ofs 
-= WIDTH_STATUSBAR_GRIP_BAND
; 
2622             dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2 
- ofs 
+ 1); 
2623             dc
.DrawLine(rect
.GetLeft(), y2
, x2 
- ofs 
+ 1, y2
); 
2629         rectIn
.width 
-= STATUSBAR_GRIP_SIZE
; 
2631         // this will prevent the standard version from drawing any borders 
2635     wxStdRenderer::DrawStatusField(dc
, rect
, label
, flags
, style
); 
2638 #endif // wxUSE_STATUSBAR 
2640 // ---------------------------------------------------------------------------- 
2642 // ---------------------------------------------------------------------------- 
2644 void wxWin32Renderer::GetComboBitmaps(wxBitmap 
*bmpNormal
, 
2645                                       wxBitmap 
* WXUNUSED(bmpFocus
), 
2646                                       wxBitmap 
*bmpPressed
, 
2647                                       wxBitmap 
*bmpDisabled
) 
2649     static const wxCoord widthCombo 
= 16; 
2650     static const wxCoord heightCombo 
= 17; 
2656         bmpNormal
->Create(widthCombo
, heightCombo
); 
2657         dcMem
.SelectObject(*bmpNormal
); 
2658         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
2659                         Arrow_Down
, Arrow_Normal
); 
2664         bmpPressed
->Create(widthCombo
, heightCombo
); 
2665         dcMem
.SelectObject(*bmpPressed
); 
2666         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
2667                         Arrow_Down
, Arrow_Pressed
); 
2672         bmpDisabled
->Create(widthCombo
, heightCombo
); 
2673         dcMem
.SelectObject(*bmpDisabled
); 
2674         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
2675                         Arrow_Down
, Arrow_Disabled
); 
2679 // ---------------------------------------------------------------------------- 
2681 // ---------------------------------------------------------------------------- 
2683 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect 
*rect
, bool isPressed
) 
2687         DrawRect(dc
, rect
, m_penDarkGrey
); 
2689         // the arrow is usually drawn inside border of width 2 and is offset by 
2690         // another pixel in both directions when it's pressed - as the border 
2691         // in this case is more narrow as well, we have to adjust rect like 
2699         DrawAntiSunkenBorder(dc
, rect
); 
2703 void wxWin32Renderer::DrawArrow(wxDC
& dc
, 
2708     ArrowStyle arrowStyle
; 
2709     if ( flags 
& wxCONTROL_PRESSED 
) 
2711         // can't be pressed and disabled 
2712         arrowStyle 
= Arrow_Pressed
; 
2716         arrowStyle 
= flags 
& wxCONTROL_DISABLED 
? Arrow_Disabled 
: Arrow_Normal
; 
2719     DrawArrowButton(dc
, rect
, GetArrowDirection(dir
), arrowStyle
); 
2722 void wxWin32Renderer::DrawArrow(wxDC
& dc
, 
2724                                 ArrowDirection arrowDir
, 
2725                                 ArrowStyle arrowStyle
) 
2727     const wxBitmap
& bmp 
= m_bmpArrows
[arrowStyle
][arrowDir
]; 
2729     // under Windows the arrows always have the same size so just centre it in 
2730     // the provided rectangle 
2731     wxCoord x 
= rect
.x 
+ (rect
.width 
- bmp
.GetWidth()) / 2, 
2732             y 
= rect
.y 
+ (rect
.height 
- bmp
.GetHeight()) / 2; 
2734     // Windows does it like this... 
2735     if ( arrowDir 
== Arrow_Left 
) 
2739     dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */); 
2742 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
, 
2743                                       const wxRect
& rectAll
, 
2744                                       ArrowDirection arrowDir
, 
2745                                       ArrowStyle arrowStyle
) 
2747     wxRect rect 
= rectAll
; 
2748     DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
); 
2749     DrawArrowBorder(dc
, &rect
, arrowStyle 
== Arrow_Pressed
); 
2750     DrawArrow(dc
, rect
, arrowDir
, arrowStyle
); 
2753 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
, 
2754                                          wxOrientation 
WXUNUSED(orient
), 
2756                                          int WXUNUSED(flags
)) 
2758     // we don't use the flags, the thumb never changes appearance 
2759     wxRect rectThumb 
= rect
; 
2760     DrawArrowBorder(dc
, &rectThumb
); 
2761     DrawBackground(dc
, wxNullColour
, rectThumb
); 
2764 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
, 
2765                                          wxOrientation 
WXUNUSED(orient
), 
2766                                          const wxRect
& rectBar
, 
2769     wxColourScheme::StdColour col 
= flags 
& wxCONTROL_PRESSED
 
2770                                     ? wxColourScheme::SCROLLBAR_PRESSED
 
2771                                     : wxColourScheme::SCROLLBAR
; 
2772     DrawBackground(dc
, m_scheme
->Get(col
), rectBar
); 
2775 // ---------------------------------------------------------------------------- 
2777 // ---------------------------------------------------------------------------- 
2779 /* Copyright (c) Julian Smart */ 
2780 static const char *error_xpm
[]={ 
2781 /* columns rows colors chars-per-pixel */ 
2858 "        $oooooooooooo%&         ", 
2859 "      *=-ooooooooooooo;:        ", 
2860 "     *oooooooooooooooooo>       ", 
2861 "     =ooooooooooooooooooo,      ", 
2862 "    $-ooooooooooooooooooo<1     ", 
2863 "   .oooooo2334ooo533oooooo6     ", 
2864 "   +ooooooo789oo2883oooooo0q    ", 
2865 "   oooooooo2w83o78eoooooooor    ", 
2866 "  toooooooooy88u884oooooooori   ", 
2867 "  Xooooooooooe888poooooooooas   ", 
2868 "  ooooooooooo4889doooooooooof   ", 
2869 "  ooooooooooo588w2oooooooooofi  ", 
2870 "  oooooooooodw8887oooooooooofi  ", 
2871 "  goooooooooh8w588jooooooookli  ", 
2872 "  tooooooooz885op8wdooooooorix  ", 
2873 "   oooooood98cood98cooooooori   ", 
2874 "   @oooooop8w2ooo5885ooooovbi   ", 
2875 "   n%ooooooooooooooooooooomiM   ", 
2876 "    &;oooooooooooooooooooNBiV   ", 
2877 "     :ooooooooooooooooooCZiA    ", 
2878 "     nSooooooooooooooooCDiF     ", 
2879 "      nG<oooooooooooooNZiiH     ", 
2880 "        160ooooooooovmBiFH      ", 
2881 "         nqrraoookrrbiiA        ", 
2888 /* Copyright (c) Julian Smart */ 
2889 static const char *info_xpm
[]={ 
2890 /* columns rows colors chars-per-pixel */ 
2912 "     ..XXXXXXXXXXXXX..          ", 
2913 "    .XXXXXXXXXXXXXXXXX.         ", 
2914 "   .XXXXXXXXoO+XXXXXXXX.        ", 
2915 "  .XXXXXXXXX@#OXXXXXXXXX.       ", 
2916 " .XXXXXXXXXX$@oXXXXXXXXXX.      ", 
2917 " .XXXXXXXXXXXXXXXXXXXXXXX.%     ", 
2918 " .XXXXXXXXX&*=-XXXXXXXXXX.%%    ", 
2919 ".XXXXXXXXXX;:#>XXXXXXXXXXX.%    ", 
2920 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%    ", 
2921 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%%   ", 
2922 " .XXXXXXXXXX;#+XXXXXXXXXX.%%%   ", 
2923 " .XXXXXXXXXX;#+XXXXXXXXXX.%%%   ", 
2924 " .XXXXXXXXXX;#+XXXXXXXXXX.%%    ", 
2925 "  .XXXXXXXX*-##+XXXXXXXX.%%%    ", 
2926 "   .XXXXXXXXXXXXXXXXXXX.%%%%    ", 
2927 "    .XXXXXXXXXXXXXXXXX.%%%%     ", 
2928 "     ..XXXXXXXXXXXXX..%%%%      ", 
2929 "      %...XXXXXXXX..%%%%%       ", 
2930 "       %%%..XXXXXX.%%%%%        ", 
2944 /* Copyright (c) Julian Smart */ 
2945 static const char *question_xpm
[]={ 
2946 /* columns rows colors chars-per-pixel */ 
2967 "     ..XXXXXXXXXXXXX..          ", 
2968 "    .XXXXXXoO++@XXXXXX.         ", 
2969 "   .XXXXXXO#$$$$#%XXXXX.        ", 
2970 "  .XXXXXX@$$#&&#$#oXXXXX.       ", 
2971 " .XXXXXXX*$$%XX%$$=XXXXXX.      ", 
2972 " .XXXXXXX+-;XXXX$$-XXXXXX.:     ", 
2973 " .XXXXXXXXXXXXX+$$&XXXXXX.::    ", 
2974 ".XXXXXXXXXXXXo;$$*oXXXXXXX.:    ", 
2975 ".XXXXXXXXXXXo*$$*oXXXXXXXX.:    ", 
2976 ".XXXXXXXXXXX+$$*oXXXXXXXXX.::   ", 
2977 " .XXXXXXXXXX-$$oXXXXXXXXX.:::   ", 
2978 " .XXXXXXXXXXX--XXXXXXXXXX.:::   ", 
2979 " .XXXXXXXXXXXXXXXXXXXXXXX.::    ", 
2980 "  .XXXXXXXXX-$$XXXXXXXXX.:::    ", 
2981 "   .XXXXXXXX-$$XXXXXXXX.::::    ", 
2982 "    .XXXXXXXO++XXXXXXX.::::     ", 
2983 "     ..XXXXXXXXXXXXX..::::      ", 
2984 "      :...XXXXXXXX..:::::       ", 
2985 "       :::..XXXXXX.:::::        ", 
2999 /* Copyright (c) Julian Smart */ 
3000 static const char *warning_xpm
[]={ 
3001 /* columns rows colors chars-per-pixel */ 
3027 "         ..XXXXO@#XXX...        ", 
3028 "        ...XXXXO@#XXXX..        ", 
3029 "        ..XXXXXO@#XXXX...       ", 
3030 "       ...XXXXXo@OXXXXX..       ", 
3031 "      ...XXXXXXo@OXXXXXX..      ", 
3032 "      ..XXXXXXX$@OXXXXXX...     ", 
3033 "     ...XXXXXXXX@XXXXXXXX..     ", 
3034 "    ...XXXXXXXXXXXXXXXXXX...    ", 
3035 "    ..XXXXXXXXXXOXXXXXXXXX..    ", 
3036 "   ...XXXXXXXXXO@#XXXXXXXXX..   ", 
3037 "   ..XXXXXXXXXXX#XXXXXXXXXX...  ", 
3038 "  ...XXXXXXXXXXXXXXXXXXXXXXX..  ", 
3039 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ", 
3040 " .............................. ", 
3041 " .............................. ", 
3048 wxBitmap 
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
, 
3049                                           const wxArtClient
& WXUNUSED(client
), 
3050                                           const wxSize
& WXUNUSED(size
)) 
3052     if ( id 
== wxART_INFORMATION 
) 
3053         return wxBitmap(info_xpm
); 
3054     if ( id 
== wxART_ERROR 
) 
3055         return wxBitmap(error_xpm
); 
3056     if ( id 
== wxART_WARNING 
) 
3057         return wxBitmap(warning_xpm
); 
3058     if ( id 
== wxART_QUESTION 
) 
3059         return wxBitmap(question_xpm
); 
3060     return wxNullBitmap
; 
3066 // ---------------------------------------------------------------------------- 
3067 // text control geometry 
3068 // ---------------------------------------------------------------------------- 
3071 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl 
*text
, 
3072                                   const wxRect
& rect
) const 
3074     wxRect rectTotal 
= wxStdRenderer::GetTextTotalArea(text
, rect
); 
3076     // this is strange but it's what Windows does 
3083 wxWin32Renderer::GetTextClientArea(const wxTextCtrl 
*text
, 
3085                                    wxCoord 
*extraSpaceBeyond
) const 
3087     wxRect rectText 
= rect
; 
3089     // undo GetTextTotalArea() 
3090     if ( rectText
.height 
> 0 ) 
3093     return wxStdRenderer::GetTextClientArea(text
, rect
, extraSpaceBeyond
); 
3096 #endif // wxUSE_TEXTCTRL 
3098 // ---------------------------------------------------------------------------- 
3100 // ---------------------------------------------------------------------------- 
3102 void wxWin32Renderer::AdjustSize(wxSize 
*size
, const wxWindow 
*window
) 
3105     if ( wxDynamicCast(window
, wxScrollBar
) ) 
3107         // we only set the width of vert scrollbars and height of the 
3109         if ( window
->GetWindowStyle() & wxSB_HORIZONTAL 
) 
3110             size
->y 
= m_sizeScrollbarArrow
.y
; 
3112             size
->x 
= m_sizeScrollbarArrow
.x
; 
3114         // skip border width adjustments, they don't make sense for us 
3117 #endif // wxUSE_SCROLLBAR 
3120     if ( wxDynamicCast(window
, wxBitmapButton
) ) 
3124 #endif // wxUSE_BMPBUTTON 
3125 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN 
3128          || wxDynamicCast(window
, wxButton
) 
3129 #  endif // wxUSE_BUTTON 
3130 #  if wxUSE_TOGGLEBTN 
3131          || wxDynamicCast(window
, wxToggleButton
) 
3132 #  endif // wxUSE_TOGGLEBTN 
3135         if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) ) 
3137             // TODO: don't harcode all this 
3138             size
->x 
+= 3*window
->GetCharWidth(); 
3140             wxCoord heightBtn 
= (11*(window
->GetCharHeight() + 8))/10; 
3141             if ( size
->y 
< heightBtn 
- 8 ) 
3142                 size
->y 
= heightBtn
; 
3147         // for compatibility with other ports, the buttons default size is never 
3148         // less than the standard one, but not when display not PDAs. 
3149         if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
) 
3151             if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) ) 
3153                 wxSize szDef 
= wxButton::GetDefaultSize(); 
3154                 if ( size
->x 
< szDef
.x 
) 
3159         // no border width adjustments for buttons 
3162 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN 
3164     wxStdRenderer::AdjustSize(size
, window
); 
3167 wxBitmap 
wxWin32Renderer::GetFrameButtonBitmap(FrameButtonType type
) 
3169     wxBitmap
& bmp 
= m_bmpFrameButtons
[type
]; 
3172         bmp 
= wxBitmap(ms_xpmFrameButtons
[type
]); 
3178 // ============================================================================ 
3180 // ============================================================================ 
3182 // ---------------------------------------------------------------------------- 
3183 // wxWin32InputHandler 
3184 // ---------------------------------------------------------------------------- 
3186 bool wxWin32InputHandler::HandleKey(wxInputConsumer 
* WXUNUSED(control
), 
3187                                     const wxKeyEvent
& WXUNUSED(event
), 
3188                                     bool WXUNUSED(pressed
)) 
3193 bool wxWin32InputHandler::HandleMouse(wxInputConsumer 
*control
, 
3194                                       const wxMouseEvent
& event
) 
3196     // clicking on the control gives it focus 
3197     if ( event
.ButtonDown() ) 
3199         wxWindow 
* const win 
= control
->GetInputWindow(); 
3201         if ( win
->CanAcceptFocus() && wxWindow::FindFocus() != win 
) 
3214 // ---------------------------------------------------------------------------- 
3215 // wxWin32ScrollBarInputHandler 
3216 // ---------------------------------------------------------------------------- 
3218 wxWin32ScrollBarInputHandler:: 
3219 wxWin32ScrollBarInputHandler(wxRenderer 
*renderer
, wxInputHandler 
*handler
) 
3220         : wxStdScrollBarInputHandler(renderer
, handler
) 
3222     m_scrollPaused 
= false; 
3226 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar 
*scrollbar
, 
3227                                                  const wxControlAction
& action
) 
3229     // stop if went beyond the position of the original click (this can only 
3230     // happen when we scroll by pages) 
3232     if ( action 
== wxACTION_SCROLL_PAGE_DOWN 
) 
3234         stop 
= scrollbar
->HitTestBar(m_ptStartScrolling
) != wxHT_SCROLLBAR_BAR_2
; 
3236     else if ( action 
== wxACTION_SCROLL_PAGE_UP 
) 
3238         stop 
= scrollbar
->HitTestBar(m_ptStartScrolling
) != wxHT_SCROLLBAR_BAR_1
; 
3243         StopScrolling(scrollbar
); 
3245         scrollbar
->Refresh(); 
3250     return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
); 
3253 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer 
*control
, 
3254                                                const wxMouseEvent
& event
) 
3256     // remember the current state 
3257     bool wasDraggingThumb 
= m_htLast 
== wxHT_SCROLLBAR_THUMB
; 
3259     // do process the message 
3260     bool rc 
= wxStdScrollBarInputHandler::HandleMouse(control
, event
); 
3262     // analyse the changes 
3263     if ( !wasDraggingThumb 
&& (m_htLast 
== wxHT_SCROLLBAR_THUMB
) ) 
3265         // we just started dragging the thumb, remember its initial position to 
3266         // be able to restore it if the drag is cancelled later 
3267         m_eventStartDrag 
= event
; 
3273 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer 
*control
, 
3274                                                    const wxMouseEvent
& event
) 
3276     // we don't highlight scrollbar elements, so there is no need to process 
3277     // mouse move events normally - only do it while mouse is captured (i.e. 
3278     // when we're dragging the thumb or pressing on something) 
3279     if ( !m_winCapture 
) 
3282     if ( event
.Entering() ) 
3284         // we're not interested in this at all 
3288     wxScrollBar 
*scrollbar 
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
); 
3290     if ( m_scrollPaused 
) 
3292         // check if the mouse returned to its original location 
3294         if ( event
.Leaving() ) 
3300         ht 
= scrollbar
->HitTestBar(event
.GetPosition()); 
3301         if ( ht 
== m_htLast 
) 
3303             // yes it did, resume scrolling 
3304             m_scrollPaused 
= false; 
3305             if ( m_timerScroll 
) 
3307                 // we were scrolling by line/page, restart timer 
3308                 m_timerScroll
->Start(m_interval
); 
3310                 Press(scrollbar
, true); 
3312             else // we were dragging the thumb 
3314                 // restore its last location 
3315                 HandleThumbMove(scrollbar
, m_eventLastDrag
); 
3321     else // normal case, scrolling hasn't been paused 
3323         // if we're scrolling the scrollbar because the arrow or the shaft was 
3324         // pressed, check that the mouse stays on the same scrollbar element 
3327         // Always let thumb jump back if we leave the scrollbar 
3328         if ( event
.Moving() ) 
3330             ht 
= scrollbar
->HitTestBar(event
.GetPosition()); 
3332         else // event.Leaving() 
3337         // Jump back only if we get far away from it 
3338         wxPoint pos 
= event
.GetPosition(); 
3339         if (scrollbar
->HasFlag( wxVERTICAL 
)) 
3341             if (pos
.x 
> -40 && pos
.x 
< scrollbar
->GetSize().x
+40) 
3346             if (pos
.y 
> -40 && pos
.y 
< scrollbar
->GetSize().y
+40) 
3349         ht 
= scrollbar
->HitTestBar(pos
); 
3352         // if we're dragging the thumb and the mouse stays in the scrollbar, it 
3353         // is still ok - we only want to catch the case when the mouse leaves 
3354         // the scrollbar here 
3355         if ( m_htLast 
== wxHT_SCROLLBAR_THUMB 
&& ht 
!= wxHT_NOWHERE 
) 
3357             ht 
= wxHT_SCROLLBAR_THUMB
; 
3360         if ( ht 
!= m_htLast 
) 
3362             // what were we doing? 2 possibilities: either an arrow/shaft was 
3363             // pressed in which case we have a timer and so we just stop it or 
3364             // we were dragging the thumb 
3365             if ( m_timerScroll 
) 
3368                 m_interval 
= m_timerScroll
->GetInterval(); 
3369                 m_timerScroll
->Stop(); 
3370                 m_scrollPaused 
= true; 
3372                 // unpress the arrow 
3373                 Press(scrollbar
, false); 
3375             else // we were dragging the thumb 
3377                 // remember the current thumb position to be able to restore it 
3378                 // if the mouse returns to it later 
3379                 m_eventLastDrag 
= event
; 
3381                 // and restore the original position (before dragging) of the 
3383                 HandleThumbMove(scrollbar
, m_eventStartDrag
); 
3390     return wxStdInputHandler::HandleMouseMove(control
, event
); 
3393 #endif // wxUSE_SCROLLBAR 
3397 // ---------------------------------------------------------------------------- 
3398 // wxWin32CheckboxInputHandler 
3399 // ---------------------------------------------------------------------------- 
3401 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer 
*control
, 
3402                                             const wxKeyEvent
& event
, 
3407         wxControlAction action
; 
3408         int keycode 
= event
.GetKeyCode(); 
3412                 action 
= wxACTION_CHECKBOX_TOGGLE
; 
3416             case WXK_NUMPAD_SUBTRACT
: 
3417                 action 
= wxACTION_CHECKBOX_CHECK
; 
3421             case WXK_NUMPAD_ADD
: 
3422             case WXK_NUMPAD_EQUAL
: 
3423                 action 
= wxACTION_CHECKBOX_CLEAR
; 
3427         if ( !action
.IsEmpty() ) 
3429             control
->PerformAction(action
); 
3438 #endif // wxUSE_CHECKBOX 
3442 // ---------------------------------------------------------------------------- 
3443 // wxWin32TextCtrlInputHandler 
3444 // ---------------------------------------------------------------------------- 
3446 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer 
*control
, 
3447                                             const wxKeyEvent
& event
, 
3450     // handle only MSW-specific text bindings here, the others are handled in 
3454         int keycode 
= event
.GetKeyCode(); 
3456         wxControlAction action
; 
3457         if ( keycode 
== WXK_DELETE 
&& event
.ShiftDown() ) 
3459             action 
= wxACTION_TEXT_CUT
; 
3461         else if ( keycode 
== WXK_INSERT 
) 
3463             if ( event
.ControlDown() ) 
3464                 action 
= wxACTION_TEXT_COPY
; 
3465             else if ( event
.ShiftDown() ) 
3466                 action 
= wxACTION_TEXT_PASTE
; 
3469         if ( action 
!= wxACTION_NONE 
) 
3471             control
->PerformAction(action
); 
3477     return wxStdInputHandler::HandleKey(control
, event
, pressed
); 
3480 #endif // wxUSE_TEXTCTRL 
3484 // ---------------------------------------------------------------------------- 
3485 // wxWin32StatusBarInputHandler 
3486 // ---------------------------------------------------------------------------- 
3488 wxWin32StatusBarInputHandler:: 
3489 wxWin32StatusBarInputHandler(wxInputHandler 
*handler
) 
3490     : wxStdInputHandler(handler
) 
3495 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow 
*statbar
, 
3496                                             const wxPoint
& pt
) const 
3498     if ( statbar
->HasFlag(wxST_SIZEGRIP
) && 
3499          statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) ) 
3502             parentTLW 
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
); 
3504         wxCHECK_MSG( parentTLW
, false, 
3505                      _T("the status bar should be a child of a TLW") ); 
3507         // a maximized window can't be resized anyhow 
3508         if ( !parentTLW
->IsMaximized() ) 
3510             // VZ: I think that the standard Windows behaviour is to only 
3511             //     show the resizing cursor when the mouse is on top of the 
3512             //     grip itself but apparently different Windows versions behave 
3513             //     differently (?) and it seems a better UI to allow resizing 
3514             //     the status bar even when the mouse is above the grip 
3515             wxSize sizeSbar 
= statbar
->GetSize(); 
3517             int diff 
= sizeSbar
.x 
- pt
.x
; 
3518             return diff 
>= 0 && diff 
< (wxCoord
)STATUSBAR_GRIP_SIZE
; 
3525 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer 
*consumer
, 
3526                                                const wxMouseEvent
& event
) 
3528     if ( event
.Button(1) ) 
3530         if ( event
.ButtonDown(1) ) 
3532             wxWindow 
*statbar 
= consumer
->GetInputWindow(); 
3534             if ( IsOnGrip(statbar
, event
.GetPosition()) ) 
3536                 wxTopLevelWindow 
*tlw 
= wxDynamicCast(statbar
->GetParent(), 
3540                     tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, 
3541                                        wxHT_TOPLEVEL_BORDER_SE
); 
3543                     statbar
->SetCursor(m_cursorOld
); 
3551     return wxStdInputHandler::HandleMouse(consumer
, event
); 
3554 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer 
*consumer
, 
3555                                                    const wxMouseEvent
& event
) 
3557     wxWindow 
*statbar 
= consumer
->GetInputWindow(); 
3559     bool isOnGrip 
= IsOnGrip(statbar
, event
.GetPosition()); 
3560     if ( isOnGrip 
!= m_isOnGrip 
) 
3562         m_isOnGrip 
= isOnGrip
; 
3565             m_cursorOld 
= statbar
->GetCursor(); 
3566             statbar
->SetCursor(wxCURSOR_SIZENWSE
); 
3570             statbar
->SetCursor(m_cursorOld
); 
3574     return wxStdInputHandler::HandleMouseMove(consumer
, event
); 
3577 #endif // wxUSE_STATUSBAR 
3579 // ---------------------------------------------------------------------------- 
3580 // wxWin32FrameInputHandler 
3581 // ---------------------------------------------------------------------------- 
3583 class wxWin32SystemMenuEvtHandler 
: public wxEvtHandler
 
3586     wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler 
*handler
); 
3588     void Attach(wxInputConsumer 
*consumer
); 
3592     DECLARE_EVENT_TABLE() 
3593     void OnSystemMenu(wxCommandEvent 
&event
); 
3594     void OnCloseFrame(wxCommandEvent 
&event
); 
3595     void OnClose(wxCloseEvent 
&event
); 
3597     wxWin32FrameInputHandler 
*m_inputHnd
; 
3598     wxTopLevelWindow         
*m_wnd
; 
3600     wxAcceleratorTable        m_oldAccelTable
; 
3604 wxWin32SystemMenuEvtHandler:: 
3605 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler 
*handler
) 
3607     m_inputHnd 
= handler
; 
3611 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer 
*consumer
) 
3613     wxASSERT_MSG( m_wnd 
== NULL
, _T("can't attach the handler twice!") ); 
3615     m_wnd 
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
); 
3616     m_wnd
->PushEventHandler(this); 
3619     // VS: This code relies on using generic implementation of 
3620     //     wxAcceleratorTable in wxUniv! 
3621     wxAcceleratorTable table 
= *m_wnd
->GetAcceleratorTable(); 
3622     m_oldAccelTable 
= table
; 
3623     table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
)); 
3624     table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
)); 
3625     m_wnd
->SetAcceleratorTable(table
); 
3629 void wxWin32SystemMenuEvtHandler::Detach() 
3634         m_wnd
->SetAcceleratorTable(m_oldAccelTable
); 
3636         m_wnd
->RemoveEventHandler(this); 
3641 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
) 
3642     EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
) 
3643     EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
) 
3644     EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
) 
3647 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent 
&WXUNUSED(event
)) 
3650     wxAcceleratorTable table 
= *m_wnd
->GetAcceleratorTable(); 
3651     m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
); 
3655     m_inputHnd
->PopupSystemMenu(m_wnd
); 
3656 #endif // wxUSE_MENUS 
3659     m_wnd
->SetAcceleratorTable(table
); 
3663 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent 
&WXUNUSED(event
)) 
3665     m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, 
3666                          wxTOPLEVEL_BUTTON_CLOSE
); 
3669 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent 
&event
) 
3676 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler 
*handler
) 
3677                         : wxStdInputHandler(handler
) 
3679     m_menuHandler 
= new wxWin32SystemMenuEvtHandler(this); 
3682 wxWin32FrameInputHandler::~wxWin32FrameInputHandler() 
3684     if ( m_menuHandler 
) 
3686         m_menuHandler
->Detach(); 
3687         delete m_menuHandler
; 
3691 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer 
*consumer
, 
3692                                            const wxMouseEvent
& event
) 
3694     if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() ) 
3696         wxTopLevelWindow 
*tlw 
= 
3697             wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
); 
3699         long hit 
= tlw
->HitTest(event
.GetPosition()); 
3701         if ( event
.LeftDClick() && hit 
== wxHT_TOPLEVEL_TITLEBAR 
) 
3703             tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, 
3704                                tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
 
3705                                                   : wxTOPLEVEL_BUTTON_MAXIMIZE
); 
3708         else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU 
) 
3710             if ( (event
.LeftDown() && hit 
== wxHT_TOPLEVEL_ICON
) || 
3711                  (event
.RightDown() && 
3712                       (hit 
== wxHT_TOPLEVEL_TITLEBAR 
|| 
3713                        hit 
== wxHT_TOPLEVEL_ICON
)) ) 
3716                 PopupSystemMenu(tlw
); 
3717 #endif // wxUSE_MENUS 
3723     return wxStdInputHandler::HandleMouse(consumer
, event
); 
3728 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow 
*window
) const 
3732     if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX 
) 
3733         menu
.Append(wxID_RESTORE_FRAME 
, _("&Restore")); 
3734     menu
.Append(wxID_MOVE_FRAME 
, _("&Move")); 
3735     if ( window
->GetWindowStyle() & wxRESIZE_BORDER 
) 
3736         menu
.Append(wxID_RESIZE_FRAME 
, _("&Size")); 
3737     if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) ) 
3738         menu
.Append(wxID_ICONIZE_FRAME 
, _("Mi&nimize")); 
3739     if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX 
) 
3740         menu
.Append(wxID_MAXIMIZE_FRAME 
, _("Ma&ximize")); 
3741     menu
.AppendSeparator(); 
3742     menu
.Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4")); 
3744     if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX 
) 
3746         if ( window
->IsMaximized() ) 
3748             menu
.Enable(wxID_MAXIMIZE_FRAME
, false); 
3749             menu
.Enable(wxID_MOVE_FRAME
, false); 
3750             if ( window
->GetWindowStyle() & wxRESIZE_BORDER 
) 
3751                 menu
.Enable(wxID_RESIZE_FRAME
, false); 
3754             menu
.Enable(wxID_RESTORE_FRAME
, false); 
3757     window
->PopupMenu(&menu
, wxPoint(0, 0)); 
3760 #endif // wxUSE_MENUS 
3762 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer 
*consumer
, 
3765     if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU 
) 
3767         // always detach if active frame changed: 
3768         m_menuHandler
->Detach(); 
3772             m_menuHandler
->Attach(consumer
); 
3776     return wxStdInputHandler::HandleActivation(consumer
, activated
); 
3779 #endif // wxUSE_THEME_WIN32