1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        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" 
  31     #include "wx/window.h" 
  33     #include "wx/dcmemory.h" 
  35     #include "wx/button.h" 
  36     #include "wx/bmpbuttn.h" 
  37     #include "wx/listbox.h" 
  38     #include "wx/checklst.h" 
  39     #include "wx/combobox.h" 
  40     #include "wx/scrolbar.h" 
  41     #include "wx/slider.h" 
  42     #include "wx/textctrl.h" 
  43     #include "wx/listbox.h" 
  44     #include "wx/toolbar.h" 
  45     #include "wx/statusbr.h" 
  48         // for COLOR_* constants 
  49         #include "wx/msw/private.h" 
  53 #include "wx/notebook.h" 
  54 #include "wx/spinbutt.h" 
  55 #include "wx/settings.h" 
  57 #include "wx/artprov.h" 
  58 #include "wx/toplevel.h" 
  61 #include "wx/univ/scrtimer.h" 
  62 #include "wx/univ/renderer.h" 
  63 #include "wx/univ/inphand.h" 
  64 #include "wx/univ/colschem.h" 
  65 #include "wx/univ/theme.h" 
  67 // ---------------------------------------------------------------------------- 
  69 // ---------------------------------------------------------------------------- 
  71 static const int BORDER_THICKNESS 
= 2; 
  73 // the offset between the label and focus rect around it 
  74 static const int FOCUS_RECT_OFFSET_X 
= 1; 
  75 static const int FOCUS_RECT_OFFSET_Y 
= 1; 
  77 static const int FRAME_BORDER_THICKNESS            
= 3; 
  78 static const int RESIZEABLE_FRAME_BORDER_THICKNESS 
= 4; 
  79 static const int FRAME_TITLEBAR_HEIGHT             
= 18; 
  80 static const int FRAME_BUTTON_WIDTH                
= 16; 
  81 static const int FRAME_BUTTON_HEIGHT               
= 14; 
  83 static const size_t NUM_STATUSBAR_GRIP_BANDS 
= 3; 
  84 static const size_t WIDTH_STATUSBAR_GRIP_BAND 
= 4; 
  85 static const size_t STATUSBAR_GRIP_SIZE 
= 
  86     WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
; 
  88 static const wxCoord SLIDER_MARGIN 
= 6; // margin around slider 
  89 static const wxCoord SLIDER_THUMB_LENGTH 
= 18; 
  90 static const wxCoord SLIDER_TICK_LENGTH 
= 6; 
 102     IndicatorState_Normal
, 
 103     IndicatorState_Pressed
, // this one is for check/radioboxes 
 104     IndicatorState_Selected 
= IndicatorState_Pressed
, // for menus 
 105     IndicatorState_Disabled
, 
 106     IndicatorState_SelectedDisabled
,    // only for the menus 
 112     IndicatorStatus_Checked
, 
 113     IndicatorStatus_Unchecked
, 
 114     IndicatorStatus_Undeterminated
, 
 118 // wxWin32Renderer: draw the GUI elements in Win32 style 
 119 // ---------------------------------------------------------------------------- 
 121 class wxWin32Renderer 
: public wxRenderer
 
 125     enum wxArrowDirection
 
 140         Arrow_InversedDisabled
, 
 144     enum wxFrameButtonType
 
 147         FrameButton_Minimize
, 
 148         FrameButton_Maximize
, 
 155     wxWin32Renderer(const wxColourScheme 
*scheme
); 
 157     // implement the base class pure virtuals 
 158     virtual void DrawBackground(wxDC
& dc
, 
 162                                 wxWindow 
*window 
= NULL
); 
 163     virtual void DrawLabel(wxDC
& dc
, 
 164                            const wxString
& label
, 
 167                            int alignment 
= wxALIGN_LEFT 
| wxALIGN_TOP
, 
 169                            wxRect 
*rectBounds 
= NULL
); 
 170     virtual void DrawButtonLabel(wxDC
& dc
, 
 171                                  const wxString
& label
, 
 172                                  const wxBitmap
& image
, 
 175                                  int alignment 
= wxALIGN_LEFT 
| wxALIGN_TOP
, 
 177                                  wxRect 
*rectBounds 
= NULL
); 
 178     virtual void DrawBorder(wxDC
& dc
, 
 182                             wxRect 
*rectIn 
= (wxRect 
*)NULL
); 
 183     virtual void DrawHorizontalLine(wxDC
& dc
, 
 184                                     wxCoord y
, wxCoord x1
, wxCoord x2
); 
 185     virtual void DrawVerticalLine(wxDC
& dc
, 
 186                                   wxCoord x
, wxCoord y1
, wxCoord y2
); 
 187     virtual void DrawFrame(wxDC
& dc
, 
 188                            const wxString
& label
, 
 191                            int alignment 
= wxALIGN_LEFT
, 
 192                            int indexAccel 
= -1); 
 193     virtual void DrawTextBorder(wxDC
& dc
, 
 197                                 wxRect 
*rectIn 
= (wxRect 
*)NULL
); 
 198     virtual void DrawButtonBorder(wxDC
& dc
, 
 201                                   wxRect 
*rectIn 
= (wxRect 
*)NULL
); 
 202     virtual void DrawArrow(wxDC
& dc
, 
 206     virtual void DrawScrollbarArrow(wxDC
& dc
, 
 210         { DrawArrow(dc
, dir
, rect
, flags
); } 
 211     virtual void DrawScrollbarThumb(wxDC
& dc
, 
 212                                     wxOrientation orient
, 
 215     virtual void DrawScrollbarShaft(wxDC
& dc
, 
 216                                     wxOrientation orient
, 
 219     virtual void DrawScrollCorner(wxDC
& dc
, 
 221     virtual void DrawItem(wxDC
& dc
, 
 222                           const wxString
& label
, 
 225     virtual void DrawCheckItem(wxDC
& dc
, 
 226                                const wxString
& label
, 
 227                                const wxBitmap
& bitmap
, 
 230     virtual void DrawCheckButton(wxDC
& dc
, 
 231                                  const wxString
& label
, 
 232                                  const wxBitmap
& bitmap
, 
 235                                  wxAlignment align 
= wxALIGN_LEFT
, 
 236                                  int indexAccel 
= -1); 
 237     virtual void DrawRadioButton(wxDC
& dc
, 
 238                                  const wxString
& label
, 
 239                                  const wxBitmap
& bitmap
, 
 242                                  wxAlignment align 
= wxALIGN_LEFT
, 
 243                                  int indexAccel 
= -1); 
 244     virtual void DrawToolBarButton(wxDC
& dc
, 
 245                                    const wxString
& label
, 
 246                                    const wxBitmap
& bitmap
, 
 250     virtual void DrawTextLine(wxDC
& dc
, 
 251                               const wxString
& text
, 
 256     virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
); 
 257     virtual void DrawTab(wxDC
& dc
, 
 260                          const wxString
& label
, 
 261                          const wxBitmap
& bitmap 
= wxNullBitmap
, 
 263                          int indexAccel 
= -1); 
 265     virtual void DrawSliderShaft(wxDC
& dc
, 
 268                                  wxOrientation orient
, 
 271                                  wxRect 
*rectShaft 
= NULL
); 
 272     virtual void DrawSliderThumb(wxDC
& dc
, 
 274                                  wxOrientation orient
, 
 277     virtual void DrawSliderTicks(wxDC
& dc
, 
 280                                  wxOrientation orient
, 
 287     virtual void DrawMenuBarItem(wxDC
& dc
, 
 289                                  const wxString
& label
, 
 291                                  int indexAccel 
= -1); 
 292     virtual void DrawMenuItem(wxDC
& dc
, 
 294                               const wxMenuGeometryInfo
& geometryInfo
, 
 295                               const wxString
& label
, 
 296                               const wxString
& accel
, 
 297                               const wxBitmap
& bitmap 
= wxNullBitmap
, 
 299                               int indexAccel 
= -1); 
 300     virtual void DrawMenuSeparator(wxDC
& dc
, 
 302                                    const wxMenuGeometryInfo
& geomInfo
); 
 304     virtual void DrawStatusField(wxDC
& dc
, 
 306                                  const wxString
& label
, 
 307                                  int flags 
= 0, int style 
= 0); 
 310     virtual void DrawFrameTitleBar(wxDC
& dc
, 
 312                                    const wxString
& title
, 
 315                                    int specialButton 
= 0, 
 316                                    int specialButtonFlags 
= 0); 
 317     virtual void DrawFrameBorder(wxDC
& dc
, 
 320     virtual void DrawFrameBackground(wxDC
& dc
, 
 323     virtual void DrawFrameTitle(wxDC
& dc
, 
 325                                 const wxString
& title
, 
 327     virtual void DrawFrameIcon(wxDC
& dc
, 
 331     virtual void DrawFrameButton(wxDC
& dc
, 
 332                                  wxCoord x
, wxCoord y
, 
 335     virtual wxRect 
GetFrameClientArea(const wxRect
& rect
, int flags
) const; 
 336     virtual wxSize 
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const; 
 337     virtual wxSize 
GetFrameMinSize(int flags
) const; 
 338     virtual wxSize 
GetFrameIconSize() const; 
 339     virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const; 
 341     virtual void GetComboBitmaps(wxBitmap 
*bmpNormal
, 
 343                                  wxBitmap 
*bmpPressed
, 
 344                                  wxBitmap 
*bmpDisabled
); 
 346     virtual void AdjustSize(wxSize 
*size
, const wxWindow 
*window
); 
 347     virtual wxRect 
GetBorderDimensions(wxBorder border
) const; 
 348     virtual bool AreScrollbarsInsideBorder() const; 
 350     virtual wxSize 
GetScrollbarArrowSize() const 
 351         { return m_sizeScrollbarArrow
; } 
 352     virtual wxRect 
GetScrollbarRect(const wxScrollBar 
*scrollbar
, 
 353                                     wxScrollBar::Element elem
, 
 354                                     int thumbPos 
= -1) const; 
 355     virtual wxCoord 
GetScrollbarSize(const wxScrollBar 
*scrollbar
); 
 356     virtual wxHitTest 
HitTestScrollbar(const wxScrollBar 
*scrollbar
, 
 357                                        const wxPoint
& pt
) const; 
 358     virtual wxCoord 
ScrollbarToPixel(const wxScrollBar 
*scrollbar
, 
 360     virtual int PixelToScrollbar(const wxScrollBar 
*scrollbar
, wxCoord coord
); 
 361     virtual wxCoord 
GetListboxItemHeight(wxCoord fontHeight
) 
 362         { return fontHeight 
+ 2; } 
 363     virtual wxSize 
GetCheckBitmapSize() const 
 364         { return wxSize(13, 13); } 
 365     virtual wxSize 
GetRadioBitmapSize() const 
 366         { return wxSize(12, 12); } 
 367     virtual wxCoord 
GetCheckItemMargin() const 
 370     virtual wxSize 
GetToolBarButtonSize(wxCoord 
*separator
) const 
 371         { if ( separator 
) *separator 
= 5; return wxSize(16, 15); } 
 372     virtual wxSize 
GetToolBarMargin() const 
 373         { return wxSize(4, 4); } 
 375     virtual wxRect 
GetTextTotalArea(const wxTextCtrl 
*text
, 
 376                                     const wxRect
& rect
) const; 
 377     virtual wxRect 
GetTextClientArea(const wxTextCtrl 
*text
, 
 379                                      wxCoord 
*extraSpaceBeyond
) const; 
 381     virtual wxSize 
GetTabIndent() const { return wxSize(2, 2); } 
 382     virtual wxSize 
GetTabPadding() const { return wxSize(6, 5); } 
 384     virtual wxCoord 
GetSliderDim() const { return SLIDER_THUMB_LENGTH 
+ 2*BORDER_THICKNESS
; } 
 385     virtual wxCoord 
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; } 
 386     virtual wxRect 
GetSliderShaftRect(const wxRect
& rect
, 
 388                                       wxOrientation orient
, 
 389                                       long style 
= 0) const; 
 390     virtual wxSize 
GetSliderThumbSize(const wxRect
& rect
, 
 392                                       wxOrientation orient
) const; 
 393     virtual wxSize 
GetProgressBarStep() const { return wxSize(16, 32); } 
 395     virtual wxSize 
GetMenuBarItemSize(const wxSize
& sizeText
) const; 
 396     virtual wxMenuGeometryInfo 
*GetMenuGeometry(wxWindow 
*win
, 
 397                                                 const wxMenu
& menu
) const; 
 399     virtual wxSize 
GetStatusBarBorders(wxCoord 
*borderBetweenFields
) const; 
 402     // helper of DrawLabel() and DrawCheckOrRadioButton() 
 403     void DoDrawLabel(wxDC
& dc
, 
 404                      const wxString
& label
, 
 407                      int alignment 
= wxALIGN_LEFT 
| wxALIGN_TOP
, 
 409                      wxRect 
*rectBounds 
= NULL
, 
 410                      const wxPoint
& focusOffset
 
 411                         = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
)); 
 413     // common part of DrawLabel() and DrawItem() 
 414     void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
); 
 416     // DrawLabel() and DrawButtonLabel() helper 
 417     void DrawLabelShadow(wxDC
& dc
, 
 418                          const wxString
& label
, 
 423     // DrawButtonBorder() helper 
 424     void DoDrawBackground(wxDC
& dc
, 
 427                           wxWindow 
*window 
= NULL 
); 
 429     // DrawBorder() helpers: all of them shift and clip the DC after drawing 
 432     // just draw a rectangle with the given pen 
 433     void DrawRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
); 
 435     // draw the lower left part of rectangle 
 436     void DrawHalfRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
); 
 438     // draw the rectange using the first brush for the left and top sides and 
 439     // the second one for the bottom and right ones 
 440     void DrawShadedRect(wxDC
& dc
, wxRect 
*rect
, 
 441                         const wxPen
& pen1
, const wxPen
& pen2
); 
 443     // draw the normal 3D border 
 444     void DrawRaisedBorder(wxDC
& dc
, wxRect 
*rect
); 
 446     // draw the sunken 3D border 
 447     void DrawSunkenBorder(wxDC
& dc
, wxRect 
*rect
); 
 449     // draw the border used for scrollbar arrows 
 450     void DrawArrowBorder(wxDC
& dc
, wxRect 
*rect
, bool isPressed 
= false); 
 452     // public DrawArrow()s helper 
 453     void DrawArrow(wxDC
& dc
, const wxRect
& rect
, 
 454                    wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
); 
 456     // DrawArrowButton is used by DrawScrollbar and DrawComboButton 
 457     void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
, 
 458                          wxArrowDirection arrowDir
, 
 459                          wxArrowStyle arrowStyle
); 
 461     // DrawCheckButton/DrawRadioButton helper 
 462     void DrawCheckOrRadioButton(wxDC
& dc
, 
 463                                 const wxString
& label
, 
 464                                 const wxBitmap
& bitmap
, 
 469                                 wxCoord focusOffsetY
); 
 471     // draw a normal or transposed line (useful for using the same code fo both 
 472     // horizontal and vertical widgets) 
 473     void DrawLine(wxDC
& dc
, 
 474                   wxCoord x1
, wxCoord y1
, 
 475                   wxCoord x2
, wxCoord y2
, 
 476                   bool transpose 
= false) 
 479             dc
.DrawLine(y1
, x1
, y2
, x2
); 
 481             dc
.DrawLine(x1
, y1
, x2
, y2
); 
 484     // get the standard check/radio button bitmap 
 485     wxBitmap 
GetIndicator(IndicatorType indType
, int flags
); 
 486     wxBitmap 
GetCheckBitmap(int flags
) 
 487         { return GetIndicator(IndicatorType_Check
, flags
); } 
 488     wxBitmap 
GetRadioBitmap(int flags
) 
 489         { return GetIndicator(IndicatorType_Radio
, flags
); } 
 492     const wxColourScheme 
*m_scheme
; 
 494     // the sizing parameters (TODO make them changeable) 
 495     wxSize m_sizeScrollbarArrow
; 
 497     // GDI objects we use for drawing 
 498     wxColour m_colDarkGrey
, 
 506     wxFont m_titlebarFont
; 
 508     // the checked and unchecked bitmaps for DrawCheckItem() 
 509     wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
]; 
 511     // the bitmaps returned by GetIndicator() 
 512     wxBitmap m_bmpIndicators
[IndicatorType_Max
] 
 514                             [IndicatorStatus_Max
]; 
 517     wxBitmap m_bmpFrameButtons
[FrameButton_Max
]; 
 519     // first row is for the normal state, second - for the disabled 
 520     wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
]; 
 523 // ---------------------------------------------------------------------------- 
 524 // wxWin32InputHandler and derived classes: process the keyboard and mouse 
 525 // messages according to Windows standards 
 526 // ---------------------------------------------------------------------------- 
 528 class wxWin32InputHandler 
: public wxInputHandler
 
 531     wxWin32InputHandler(wxWin32Renderer 
*renderer
); 
 533     virtual bool HandleKey(wxInputConsumer 
*control
, 
 534                            const wxKeyEvent
& event
, 
 536     virtual bool HandleMouse(wxInputConsumer 
*control
, 
 537                              const wxMouseEvent
& event
); 
 540     wxWin32Renderer 
*m_renderer
; 
 543 class wxWin32ScrollBarInputHandler 
: public wxStdScrollBarInputHandler
 
 546     wxWin32ScrollBarInputHandler(wxWin32Renderer 
*renderer
, 
 547                                  wxInputHandler 
*handler
); 
 549     virtual bool HandleMouse(wxInputConsumer 
*control
, const wxMouseEvent
& event
); 
 550     virtual bool HandleMouseMove(wxInputConsumer 
*control
, const wxMouseEvent
& event
); 
 552     virtual bool OnScrollTimer(wxScrollBar 
*scrollbar
, 
 553                                const wxControlAction
& action
); 
 556     virtual bool IsAllowedButton(int button
) { return button 
== 1; } 
 558     virtual void Highlight(wxScrollBar 
* WXUNUSED(scrollbar
), 
 561         // we don't highlight anything 
 564     // the first and last event which caused the thumb to move 
 565     wxMouseEvent m_eventStartDrag
, 
 568     // have we paused the scrolling because the mouse moved? 
 571     // we remember the interval of the timer to be able to restart it 
 575 class wxWin32CheckboxInputHandler 
: public wxStdCheckboxInputHandler
 
 578     wxWin32CheckboxInputHandler(wxInputHandler 
*handler
) 
 579         : wxStdCheckboxInputHandler(handler
) { } 
 581     virtual bool HandleKey(wxInputConsumer 
*control
, 
 582                            const wxKeyEvent
& event
, 
 586 class wxWin32TextCtrlInputHandler 
: public wxStdTextCtrlInputHandler
 
 589     wxWin32TextCtrlInputHandler(wxInputHandler 
*handler
) 
 590         : wxStdTextCtrlInputHandler(handler
) { } 
 592     virtual bool HandleKey(wxInputConsumer 
*control
, 
 593                            const wxKeyEvent
& event
, 
 597 class wxWin32StatusBarInputHandler 
: public wxStdInputHandler
 
 600     wxWin32StatusBarInputHandler(wxInputHandler 
*handler
); 
 602     virtual bool HandleMouse(wxInputConsumer 
*consumer
, 
 603                              const wxMouseEvent
& event
); 
 605     virtual bool HandleMouseMove(wxInputConsumer 
*consumer
, 
 606                                  const wxMouseEvent
& event
); 
 609     // is the given point over the statusbar grip? 
 610     bool IsOnGrip(wxWindow 
*statbar
, const wxPoint
& pt
) const; 
 613     // the cursor we had replaced with the resize one 
 614     wxCursor m_cursorOld
; 
 616     // was the mouse over the grip last time we checked? 
 620 class wxWin32SystemMenuEvtHandler
; 
 622 class wxWin32FrameInputHandler 
: public wxStdFrameInputHandler
 
 625     wxWin32FrameInputHandler(wxInputHandler 
*handler
); 
 626     ~wxWin32FrameInputHandler(); 
 628     virtual bool HandleMouse(wxInputConsumer 
*control
, 
 629                              const wxMouseEvent
& event
); 
 631     virtual bool HandleActivation(wxInputConsumer 
*consumer
, bool activated
); 
 633     void PopupSystemMenu(wxTopLevelWindow 
*window
, const wxPoint
& pos
) const; 
 636     // was the mouse over the grip last time we checked? 
 637     wxWin32SystemMenuEvtHandler 
*m_menuHandler
; 
 640 // ---------------------------------------------------------------------------- 
 641 // wxWin32ColourScheme: uses (default) Win32 colours 
 642 // ---------------------------------------------------------------------------- 
 644 class wxWin32ColourScheme 
: public wxColourScheme
 
 647     virtual wxColour 
Get(StdColour col
) const; 
 648     virtual wxColour 
GetBackground(wxWindow 
*win
) const; 
 651 // ---------------------------------------------------------------------------- 
 652 // wxWin32ArtProvider 
 653 // ---------------------------------------------------------------------------- 
 655 class wxWin32ArtProvider 
: public wxArtProvider
 
 658     virtual wxBitmap 
CreateBitmap(const wxArtID
& id
, 
 659                                   const wxArtClient
& client
, 
 663 // ---------------------------------------------------------------------------- 
 665 // ---------------------------------------------------------------------------- 
 667 WX_DEFINE_ARRAY_PTR(wxInputHandler 
*, wxArrayHandlers
); 
 669 class wxWin32Theme 
: public wxTheme
 
 673     virtual ~wxWin32Theme(); 
 675     virtual wxRenderer 
*GetRenderer(); 
 676     virtual wxArtProvider 
*GetArtProvider(); 
 677     virtual wxInputHandler 
*GetInputHandler(const wxString
& control
); 
 678     virtual wxColourScheme 
*GetColourScheme(); 
 681     // get the default input handler 
 682     wxInputHandler 
*GetDefaultInputHandler(); 
 684     wxWin32Renderer 
*m_renderer
; 
 686     wxWin32ArtProvider 
*m_artProvider
; 
 688     // the names of the already created handlers and the handlers themselves 
 689     // (these arrays are synchronized) 
 690     wxSortedArrayString m_handlerNames
; 
 691     wxArrayHandlers m_handlers
; 
 693     wxWin32InputHandler 
*m_handlerDefault
; 
 695     wxWin32ColourScheme 
*m_scheme
; 
 697     WX_DECLARE_THEME(win32
) 
 700 // ---------------------------------------------------------------------------- 
 702 // ---------------------------------------------------------------------------- 
 704 // frame buttons bitmaps 
 706 static const char *frame_button_close_xpm
[] = { 
 721 static const char *frame_button_help_xpm
[] = { 
 736 static const char *frame_button_maximize_xpm
[] = { 
 751 static const char *frame_button_minimize_xpm
[] = { 
 766 static const char *frame_button_restore_xpm
[] = { 
 783 static const char *checked_menu_xpm
[] = { 
 784 /* columns rows colors chars-per-pixel */ 
 800 static const char *selected_checked_menu_xpm
[] = { 
 801 /* columns rows colors chars-per-pixel */ 
 817 static const char *disabled_checked_menu_xpm
[] = { 
 818 /* columns rows colors chars-per-pixel */ 
 835 static const char *selected_disabled_checked_menu_xpm
[] = { 
 836 /* columns rows colors chars-per-pixel */ 
 852 // checkbox and radiobox bitmaps below 
 854 static const char *checked_xpm
[] = { 
 855 /* columns rows colors chars-per-pixel */ 
 878 static const char *pressed_checked_xpm
[] = { 
 879 /* columns rows colors chars-per-pixel */ 
 901 static const char *pressed_disabled_checked_xpm
[] = { 
 902 /* columns rows colors chars-per-pixel */ 
 924 static const char *checked_item_xpm
[] = { 
 925 /* columns rows colors chars-per-pixel */ 
 946 static const char *unchecked_xpm
[] = { 
 947 /* columns rows colors chars-per-pixel */ 
 970 static const char *pressed_unchecked_xpm
[] = { 
 971 /* columns rows colors chars-per-pixel */ 
 993 static const char *unchecked_item_xpm
[] = { 
 994 /* columns rows colors chars-per-pixel */ 
1014 static const char *undetermined_xpm
[] = { 
1015 /* columns rows colors chars-per-pixel */ 
1038 static const char *pressed_undetermined_xpm
[] = { 
1039 /* columns rows colors chars-per-pixel */ 
1062 static const char *checked_radio_xpm
[] = { 
1063 /* columns rows colors chars-per-pixel */ 
1086 static const char *pressed_checked_radio_xpm
[] = { 
1087 /* columns rows colors chars-per-pixel */ 
1110 static const char *pressed_disabled_checked_radio_xpm
[] = { 
1111 /* columns rows colors chars-per-pixel */ 
1134 static const char *unchecked_radio_xpm
[] = { 
1135 /* columns rows colors chars-per-pixel */ 
1158 static const char *pressed_unchecked_radio_xpm
[] = { 
1159 /* columns rows colors chars-per-pixel */ 
1182 static const char ** 
1183     xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] = 
1188         { checked_xpm
, unchecked_xpm
, undetermined_xpm 
}, 
1191         { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm 
}, 
1194         { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm 
}, 
1200         { checked_radio_xpm
, unchecked_radio_xpm
, NULL 
}, 
1203         { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL 
}, 
1206         { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL 
}, 
1212         { checked_menu_xpm
, NULL
, NULL 
}, 
1215         { selected_checked_menu_xpm
, NULL
, NULL 
}, 
1218         { disabled_checked_menu_xpm
, NULL
, NULL 
}, 
1220         // disabled selected state 
1221         { selected_disabled_checked_menu_xpm
, NULL
, NULL 
}, 
1225 static const char **xpmChecked
[IndicatorStatus_Max
] = 
1231 // ============================================================================ 
1233 // ============================================================================ 
1235 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme")); 
1237 // ---------------------------------------------------------------------------- 
1239 // ---------------------------------------------------------------------------- 
1241 wxWin32Theme::wxWin32Theme() 
1245     m_handlerDefault 
= NULL
; 
1246     m_artProvider 
= NULL
; 
1249 wxWin32Theme::~wxWin32Theme() 
1251     size_t count 
= m_handlers
.GetCount(); 
1252     for ( size_t n 
= 0; n 
< count
; n
++ ) 
1254         if ( m_handlers
[n
] != m_handlerDefault 
) 
1255             delete m_handlers
[n
]; 
1258     delete m_handlerDefault
; 
1262     wxArtProvider::RemoveProvider(m_artProvider
); 
1265 wxRenderer 
*wxWin32Theme::GetRenderer() 
1269         m_renderer 
= new wxWin32Renderer(GetColourScheme()); 
1275 wxArtProvider 
*wxWin32Theme::GetArtProvider() 
1277     if ( !m_artProvider 
) 
1279         m_artProvider 
= new wxWin32ArtProvider
; 
1282     return m_artProvider
; 
1285 wxInputHandler 
*wxWin32Theme::GetDefaultInputHandler() 
1287     if ( !m_handlerDefault 
) 
1289         m_handlerDefault 
= new wxWin32InputHandler(m_renderer
); 
1292     return m_handlerDefault
; 
1295 wxInputHandler 
*wxWin32Theme::GetInputHandler(const wxString
& control
) 
1297     wxInputHandler 
*handler
; 
1298     int n 
= m_handlerNames
.Index(control
); 
1299     if ( n 
== wxNOT_FOUND 
) 
1301         // create a new handler 
1302         if ( control 
== wxINP_HANDLER_SCROLLBAR 
) 
1303             handler 
= new wxWin32ScrollBarInputHandler(m_renderer
, 
1304                                                        GetDefaultInputHandler()); 
1306         else if ( control 
== wxINP_HANDLER_BUTTON 
) 
1307             handler 
= new wxStdButtonInputHandler(GetDefaultInputHandler()); 
1308 #endif // wxUSE_BUTTON 
1310         else if ( control 
== wxINP_HANDLER_CHECKBOX 
) 
1311             handler 
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler()); 
1312 #endif // wxUSE_CHECKBOX 
1314         else if ( control 
== wxINP_HANDLER_COMBOBOX 
) 
1315             handler 
= new wxStdComboBoxInputHandler(GetDefaultInputHandler()); 
1316 #endif // wxUSE_COMBOBOX 
1318         else if ( control 
== wxINP_HANDLER_LISTBOX 
) 
1319             handler 
= new wxStdListboxInputHandler(GetDefaultInputHandler()); 
1320 #endif // wxUSE_LISTBOX 
1321 #if wxUSE_CHECKLISTBOX 
1322         else if ( control 
== wxINP_HANDLER_CHECKLISTBOX 
) 
1323             handler 
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler()); 
1324 #endif // wxUSE_CHECKLISTBOX 
1326         else if ( control 
== wxINP_HANDLER_TEXTCTRL 
) 
1327             handler 
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler()); 
1328 #endif // wxUSE_TEXTCTRL 
1330         else if ( control 
== wxINP_HANDLER_SLIDER 
) 
1331             handler 
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler()); 
1332 #endif // wxUSE_SLIDER 
1334         else if ( control 
== wxINP_HANDLER_SPINBTN 
) 
1335             handler 
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler()); 
1336 #endif // wxUSE_SPINBTN 
1338         else if ( control 
== wxINP_HANDLER_NOTEBOOK 
) 
1339             handler 
= new wxStdNotebookInputHandler(GetDefaultInputHandler()); 
1340 #endif // wxUSE_NOTEBOOK 
1342         else if ( control 
== wxINP_HANDLER_STATUSBAR 
) 
1343             handler 
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler()); 
1344 #endif // wxUSE_STATUSBAR 
1346         else if ( control 
== wxINP_HANDLER_TOOLBAR 
) 
1347             handler 
= new wxStdToolbarInputHandler(GetDefaultInputHandler()); 
1348 #endif // wxUSE_TOOLBAR 
1349         else if ( control 
== wxINP_HANDLER_TOPLEVEL 
) 
1350             handler 
= new wxWin32FrameInputHandler(GetDefaultInputHandler()); 
1352             handler 
= GetDefaultInputHandler(); 
1354         n 
= m_handlerNames
.Add(control
); 
1355         m_handlers
.Insert(handler
, n
); 
1357     else // we already have it 
1359         handler 
= m_handlers
[n
]; 
1365 wxColourScheme 
*wxWin32Theme::GetColourScheme() 
1369         m_scheme 
= new wxWin32ColourScheme
; 
1374 // ============================================================================ 
1375 // wxWin32ColourScheme 
1376 // ============================================================================ 
1378 wxColour 
wxWin32ColourScheme::GetBackground(wxWindow 
*win
) const 
1381     if ( win
->UseBgCol() ) 
1383         // use the user specified colour 
1384         col 
= win
->GetBackgroundColour(); 
1387     if ( !win
->ShouldInheritColours() ) 
1389         wxTextCtrl 
*text 
= wxDynamicCast(win
, wxTextCtrl
); 
1391         wxListBox
* listBox 
= wxDynamicCast(win
, wxListBox
); 
1399             if ( !win
->IsEnabled() ) // not IsEditable() 
1405                     // doesn't depend on the state 
1412             col 
= Get(CONTROL
); // Most controls should be this colour, not WINDOW 
1416         int flags 
= win
->GetStateFlags(); 
1418         // the colour set by the user should be used for the normal state 
1419         // and for the states for which we don't have any specific colours 
1420         if ( !col
.Ok() || (flags 
& wxCONTROL_PRESSED
) != 0 ) 
1422             if ( wxDynamicCast(win
, wxScrollBar
) ) 
1423                 col 
= Get(flags 
& wxCONTROL_PRESSED 
? SCROLLBAR_PRESSED
 
1433 wxColour 
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const 
1437         // use the system colours under Windows 
1438 #if defined(__WXMSW__) 
1439         case WINDOW
:            return wxColour(GetSysColor(COLOR_WINDOW
)); 
1441         case CONTROL_PRESSED
: 
1442         case CONTROL_CURRENT
: 
1443         case CONTROL
:           return wxColour(GetSysColor(COLOR_BTNFACE
)); 
1445         case CONTROL_TEXT
:      return wxColour(GetSysColor(COLOR_BTNTEXT
)); 
1447 #if defined(COLOR_3DLIGHT) 
1448         case SCROLLBAR
:         return wxColour(GetSysColor(COLOR_3DLIGHT
)); 
1450         case SCROLLBAR
:         return wxColour(0xe0e0e0); 
1452         case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
)); 
1454         case HIGHLIGHT
:         return wxColour(GetSysColor(COLOR_HIGHLIGHT
)); 
1455         case HIGHLIGHT_TEXT
:    return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
)); 
1457 #if defined(COLOR_3DDKSHADOW) 
1458         case SHADOW_DARK
:       return wxColour(GetSysColor(COLOR_3DDKSHADOW
)); 
1460         case SHADOW_DARK
:       return wxColour(GetSysColor(COLOR_3DHADOW
)); 
1463         case CONTROL_TEXT_DISABLED
: 
1464         case SHADOW_HIGHLIGHT
:  return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
)); 
1466         case SHADOW_IN
:         return wxColour(GetSysColor(COLOR_BTNFACE
)); 
1468         case CONTROL_TEXT_DISABLED_SHADOW
: 
1469         case SHADOW_OUT
:        return wxColour(GetSysColor(COLOR_BTNSHADOW
)); 
1471         case TITLEBAR
:          return wxColour(GetSysColor(COLOR_INACTIVECAPTION
)); 
1472         case TITLEBAR_ACTIVE
:   return wxColour(GetSysColor(COLOR_ACTIVECAPTION
)); 
1473         case TITLEBAR_TEXT
:     return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
)); 
1474         case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
)); 
1476         case DESKTOP
:           return wxColour(0x808000); 
1478         // use the standard Windows colours elsewhere 
1479         case WINDOW
:            return *wxWHITE
; 
1481         case CONTROL_PRESSED
: 
1482         case CONTROL_CURRENT
: 
1483         case CONTROL
:           return wxColour(0xc0c0c0); 
1485         case CONTROL_TEXT
:      return *wxBLACK
; 
1487         case SCROLLBAR
:         return wxColour(0xe0e0e0); 
1488         case SCROLLBAR_PRESSED
: return *wxBLACK
; 
1490         case HIGHLIGHT
:         return wxColour(0x800000); 
1491         case HIGHLIGHT_TEXT
:    return wxColour(0xffffff); 
1493         case SHADOW_DARK
:       return *wxBLACK
; 
1495         case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0); 
1496         case SHADOW_HIGHLIGHT
:  return wxColour(0xffffff); 
1498         case SHADOW_IN
:         return wxColour(0xc0c0c0); 
1500         case CONTROL_TEXT_DISABLED_SHADOW
: 
1501         case SHADOW_OUT
:        return wxColour(0x7f7f7f); 
1503         case TITLEBAR
:          return wxColour(0xaeaaae); 
1504         case TITLEBAR_ACTIVE
:   return wxColour(0x820300); 
1505         case TITLEBAR_TEXT
:     return wxColour(0xc0c0c0); 
1506         case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
; 
1508         case DESKTOP
:           return wxColour(0x808000); 
1511         case GAUGE
:             return Get(HIGHLIGHT
); 
1515             wxFAIL_MSG(_T("invalid standard colour")); 
1520 // ============================================================================ 
1522 // ============================================================================ 
1524 // ---------------------------------------------------------------------------- 
1526 // ---------------------------------------------------------------------------- 
1528 wxWin32Renderer::wxWin32Renderer(const wxColourScheme 
*scheme
) 
1532     m_sizeScrollbarArrow 
= wxSize(16, 16); 
1534     // init colours and pens 
1535     m_penBlack 
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
); 
1537     m_colDarkGrey 
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
); 
1538     m_penDarkGrey 
= wxPen(m_colDarkGrey
, 0, wxSOLID
); 
1540     m_penLightGrey 
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
); 
1542     m_colHighlight 
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
); 
1543     m_penHighlight 
= wxPen(m_colHighlight
, 0, wxSOLID
); 
1545     m_titlebarFont 
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
); 
1546     m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
); 
1548     // init the arrow bitmaps 
1549     static const size_t ARROW_WIDTH 
= 7; 
1550     static const size_t ARROW_LENGTH 
= 4; 
1553     wxMemoryDC dcNormal
, 
1556     for ( size_t n 
= 0; n 
< Arrow_Max
; n
++ ) 
1558         bool isVertical 
= n 
> Arrow_Right
; 
1571         // disabled arrow is larger because of the shadow 
1572         m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
); 
1573         m_bmpArrows
[Arrow_Disabled
][n
].Create(w 
+ 1, h 
+ 1); 
1575         dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]); 
1576         dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]); 
1578         dcNormal
.SetBackground(*wxWHITE_BRUSH
); 
1579         dcDisabled
.SetBackground(*wxWHITE_BRUSH
); 
1583         dcNormal
.SetPen(m_penBlack
); 
1584         dcDisabled
.SetPen(m_penDarkGrey
); 
1586         // calculate the position of the point of the arrow 
1590             x1 
= (ARROW_WIDTH 
- 1)/2; 
1591             y1 
= n 
== Arrow_Up 
? 0 : ARROW_LENGTH 
- 1; 
1595             x1 
= n 
== Arrow_Left 
? 0 : ARROW_LENGTH 
- 1; 
1596             y1 
= (ARROW_WIDTH 
- 1)/2; 
1607         for ( size_t i 
= 0; i 
< ARROW_LENGTH
; i
++ ) 
1609             dcNormal
.DrawLine(x1
, y1
, x2
, y2
); 
1610             dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1617                 if ( n 
== Arrow_Up 
) 
1628             else // left or right arrow 
1633                 if ( n 
== Arrow_Left 
) 
1646         // draw the shadow for the disabled one 
1647         dcDisabled
.SetPen(m_penHighlight
); 
1652                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1656                 x1 
= ARROW_LENGTH 
- 1; 
1657                 y1 
= (ARROW_WIDTH 
- 1)/2 + 1; 
1660                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1661                 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
); 
1666                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1670                 x1 
= ARROW_WIDTH 
- 1; 
1672                 x2 
= (ARROW_WIDTH 
- 1)/2; 
1674                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1675                 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
); 
1680         // create the inversed bitmap but only for the right arrow as we only 
1681         // use it for the menus 
1682         if ( n 
== Arrow_Right 
) 
1684             m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
); 
1685             dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]); 
1687             dcInverse
.Blit(0, 0, w
, h
, 
1690             dcInverse
.SelectObject(wxNullBitmap
); 
1692             mask 
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
); 
1693             m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
); 
1695             m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
); 
1696             dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]); 
1698             dcInverse
.Blit(0, 0, w
, h
, 
1701             dcInverse
.SelectObject(wxNullBitmap
); 
1703             mask 
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
); 
1704             m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
); 
1707         dcNormal
.SelectObject(wxNullBitmap
); 
1708         dcDisabled
.SelectObject(wxNullBitmap
); 
1710         mask 
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
); 
1711         m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
); 
1712         mask 
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
); 
1713         m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
); 
1715         m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
]; 
1718     // init the frame buttons bitmaps 
1719     m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
); 
1720     m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
); 
1721     m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
); 
1722     m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
); 
1723     m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
); 
1726 // ---------------------------------------------------------------------------- 
1728 // ---------------------------------------------------------------------------- 
1731    The raised border in Win32 looks like this: 
1733    IIIIIIIIIIIIIIIIIIIIIIB 
1735    I                    GB  I = white       (HILIGHT) 
1736    I                    GB  H = light grey  (LIGHT) 
1737    I                    GB  G = dark grey   (SHADOI) 
1738    I                    GB  B = black       (DKSHADOI) 
1739    I                    GB  I = hIghlight (COLOR_3DHILIGHT) 
1741    IGGGGGGGGGGGGGGGGGGGGGB 
1742    BBBBBBBBBBBBBBBBBBBBBBB 
1744    The sunken border looks like this: 
1746    GGGGGGGGGGGGGGGGGGGGGGI 
1747    GBBBBBBBBBBBBBBBBBBBBHI 
1754    GHHHHHHHHHHHHHHHHHHHHHI 
1755    IIIIIIIIIIIIIIIIIIIIIII 
1757    The static border (used for the controls which don't get focus) is like 
1760    GGGGGGGGGGGGGGGGGGGGGGW 
1768    WWWWWWWWWWWWWWWWWWWWWWW 
1770    The most complicated is the double border: 
1772    HHHHHHHHHHHHHHHHHHHHHHB 
1773    HWWWWWWWWWWWWWWWWWWWWGB 
1774    HWHHHHHHHHHHHHHHHHHHHGB 
1779    HWHHHHHHHHHHHHHHHHHHHGB 
1780    HGGGGGGGGGGGGGGGGGGGGGB 
1781    BBBBBBBBBBBBBBBBBBBBBBB 
1783    And the simple border is, well, simple: 
1785    BBBBBBBBBBBBBBBBBBBBBBB 
1794    BBBBBBBBBBBBBBBBBBBBBBB 
1797 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
) 
1801     dc
.SetBrush(*wxTRANSPARENT_BRUSH
); 
1802     dc
.DrawRectangle(*rect
); 
1808 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
) 
1810     // draw the bottom and right sides 
1812     dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(), 
1813                 rect
->GetRight() + 1, rect
->GetBottom()); 
1814     dc
.DrawLine(rect
->GetRight(), rect
->GetTop(), 
1815                 rect
->GetRight(), rect
->GetBottom()); 
1821 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect 
*rect
, 
1822                                      const wxPen
& pen1
, const wxPen
& pen2
) 
1824     // draw the rectangle 
1826     dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(), 
1827                 rect
->GetLeft(), rect
->GetBottom()); 
1828     dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(), 
1829                 rect
->GetRight(), rect
->GetTop()); 
1831     dc
.DrawLine(rect
->GetRight(), rect
->GetTop(), 
1832                 rect
->GetRight(), rect
->GetBottom()); 
1833     dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(), 
1834                 rect
->GetRight() + 1, rect
->GetBottom()); 
1840 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect 
*rect
) 
1842     DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
); 
1843     DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
); 
1846 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect 
*rect
) 
1848     DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
); 
1849     DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
); 
1852 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect 
*rect
, bool isPressed
) 
1856         DrawRect(dc
, rect
, m_penDarkGrey
); 
1858         // the arrow is usually drawn inside border of width 2 and is offset by 
1859         // another pixel in both directions when it's pressed - as the border 
1860         // in this case is more narrow as well, we have to adjust rect like 
1868         DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
); 
1869         DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
); 
1873 void wxWin32Renderer::DrawBorder(wxDC
& dc
, 
1875                                  const wxRect
& rectTotal
, 
1876                                  int WXUNUSED(flags
), 
1881     wxRect rect 
= rectTotal
; 
1885         case wxBORDER_SUNKEN
: 
1886             for ( i 
= 0; i 
< BORDER_THICKNESS 
/ 2; i
++ ) 
1888                 DrawSunkenBorder(dc
, &rect
); 
1892         case wxBORDER_STATIC
: 
1893             DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
); 
1896         case wxBORDER_RAISED
: 
1897             for ( i 
= 0; i 
< BORDER_THICKNESS 
/ 2; i
++ ) 
1899                 DrawRaisedBorder(dc
, &rect
); 
1903         case wxBORDER_DOUBLE
: 
1904             DrawArrowBorder(dc
, &rect
); 
1905             DrawRect(dc
, &rect
, m_penLightGrey
); 
1908         case wxBORDER_SIMPLE
: 
1909             for ( i 
= 0; i 
< BORDER_THICKNESS 
/ 2; i
++ ) 
1911                 DrawRect(dc
, &rect
, m_penBlack
); 
1916             wxFAIL_MSG(_T("unknown border type")); 
1919         case wxBORDER_DEFAULT
: 
1928 wxRect 
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const 
1933         case wxBORDER_RAISED
: 
1934         case wxBORDER_SUNKEN
: 
1935             width 
= BORDER_THICKNESS
; 
1938         case wxBORDER_SIMPLE
: 
1939         case wxBORDER_STATIC
: 
1943         case wxBORDER_DOUBLE
: 
1949             // char *crash = NULL; 
1951             wxFAIL_MSG(_T("unknown border type")); 
1955         case wxBORDER_DEFAULT
: 
1965     rect
.height 
= width
; 
1970 bool wxWin32Renderer::AreScrollbarsInsideBorder() const 
1975 // ---------------------------------------------------------------------------- 
1977 // ---------------------------------------------------------------------------- 
1979 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
, 
1985     // text controls are not special under windows 
1986     DrawBorder(dc
, border
, rect
, flags
, rectIn
); 
1989 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
, 
1990                                        const wxRect
& rectTotal
, 
1994     wxRect rect 
= rectTotal
; 
1996     if ( flags 
& wxCONTROL_PRESSED 
) 
1998         // button pressed: draw a double border around it 
1999         DrawRect(dc
, &rect
, m_penBlack
); 
2000         DrawRect(dc
, &rect
, m_penDarkGrey
); 
2004         // button not pressed 
2006         if ( flags 
& (wxCONTROL_FOCUSED 
| wxCONTROL_ISDEFAULT
) ) 
2008             // button either default or focused (or both): add an extra border around it 
2009             DrawRect(dc
, &rect
, m_penBlack
); 
2012         // now draw a normal button 
2013         DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
); 
2014         DrawHalfRect(dc
, &rect
, m_penDarkGrey
); 
2023 // ---------------------------------------------------------------------------- 
2025 // ---------------------------------------------------------------------------- 
2027 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
, 
2028                                          wxCoord y
, wxCoord x1
, wxCoord x2
) 
2030     dc
.SetPen(m_penDarkGrey
); 
2031     dc
.DrawLine(x1
, y
, x2 
+ 1, y
); 
2032     dc
.SetPen(m_penHighlight
); 
2034     dc
.DrawLine(x1
, y
, x2 
+ 1, y
); 
2037 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
, 
2038                                        wxCoord x
, wxCoord y1
, wxCoord y2
) 
2040     dc
.SetPen(m_penDarkGrey
); 
2041     dc
.DrawLine(x
, y1
, x
, y2 
+ 1); 
2042     dc
.SetPen(m_penHighlight
); 
2044     dc
.DrawLine(x
, y1
, x
, y2 
+ 1); 
2047 void wxWin32Renderer::DrawFrame(wxDC
& dc
, 
2048                                 const wxString
& label
, 
2054     wxCoord height 
= 0; // of the label 
2055     wxRect rectFrame 
= rect
; 
2056     if ( !label
.empty() ) 
2058         // the text should touch the top border of the rect, so the frame 
2059         // itself should be lower 
2060         dc
.GetTextExtent(label
, NULL
, &height
); 
2061         rectFrame
.y 
+= height 
/ 2; 
2062         rectFrame
.height 
-= height 
/ 2; 
2064         // we have to draw each part of the frame individually as we can't 
2065         // erase the background beyond the label as it might contain some 
2066         // pixmap already, so drawing everything and then overwriting part of 
2067         // the frame with label doesn't work 
2069         // TODO: the +5 and space insertion should be customizable 
2072         rectText
.x 
= rectFrame
.x 
+ 5; 
2073         rectText
.y 
= rect
.y
; 
2074         rectText
.width 
= rectFrame
.width 
- 7; // +2 border width 
2075         rectText
.height 
= height
; 
2078         label2 
<< _T(' ') << label 
<< _T(' '); 
2079         if ( indexAccel 
!= -1 ) 
2081             // adjust it as we prepended a space 
2086         DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
); 
2088         StandardDrawFrame(dc
, rectFrame
, rectLabel
); 
2092         // just draw the complete frame 
2093         DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
); 
2094         DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
); 
2098 // ---------------------------------------------------------------------------- 
2100 // ---------------------------------------------------------------------------- 
2102 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
) 
2104     // VZ: this doesn't work under Windows, the dotted pen has dots of 3 
2105     //     pixels each while we really need dots here... PS_ALTERNATE might 
2106     //     work, but it is for NT 5 only 
2108     DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
)); 
2110     // draw the pixels manually: note that to behave in the same manner as 
2111     // DrawRect(), we must exclude the bottom and right borders from the 
2113     wxCoord x1 
= rect
.GetLeft(), 
2115             x2 
= rect
.GetRight(), 
2116             y2 
= rect
.GetBottom(); 
2118     dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
)); 
2120     // this seems to be closer than what Windows does than wxINVERT although 
2121     // I'm still not sure if it's correct 
2122     dc
.SetLogicalFunction(wxAND_REVERSE
); 
2125     for ( z 
= x1 
+ 1; z 
< x2
; z 
+= 2 ) 
2126         dc
.DrawPoint(z
, rect
.GetTop()); 
2128     wxCoord shift 
= z 
== x2 
? 0 : 1; 
2129     for ( z 
= y1 
+ shift
; z 
< y2
; z 
+= 2 ) 
2130         dc
.DrawPoint(x2
, z
); 
2132     shift 
= z 
== y2 
? 0 : 1; 
2133     for ( z 
= x2 
- shift
; z 
> x1
; z 
-= 2 ) 
2134         dc
.DrawPoint(z
, y2
); 
2136     shift 
= z 
== x1 
? 0 : 1; 
2137     for ( z 
= y2 
- shift
; z 
> y1
; z 
-= 2 ) 
2138         dc
.DrawPoint(x1
, z
); 
2140     dc
.SetLogicalFunction(wxCOPY
); 
2144 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
, 
2145                                       const wxString
& label
, 
2150     // draw shadow of the text 
2151     dc
.SetTextForeground(m_colHighlight
); 
2152     wxRect rectShadow 
= rect
; 
2155     dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
); 
2157     // make the text grey 
2158     dc
.SetTextForeground(m_colDarkGrey
); 
2161 void wxWin32Renderer::DrawLabel(wxDC
& dc
, 
2162                                 const wxString
& label
, 
2169     DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
); 
2172 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
, 
2173                                   const wxString
& label
, 
2179                                   const wxPoint
& focusOffset
) 
2181     // the underscores are not drawn for focused controls in wxMSW 
2182     if ( flags 
& wxCONTROL_FOCUSED 
) 
2187     if ( flags 
& wxCONTROL_DISABLED 
) 
2189         // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED 
2190         // currently only can happen for a menu item and it seems that Windows 
2191         // doesn't draw the shadow in this case, so we don't do it neither 
2192         if ( flags 
& wxCONTROL_SELECTED 
) 
2194             // just make the label text greyed out 
2195             dc
.SetTextForeground(m_colDarkGrey
); 
2197         else // draw normal disabled label 
2199             DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
); 
2204     dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
); 
2206     if ( flags 
& wxCONTROL_DISABLED 
) 
2208         // restore the fg colour 
2209         dc
.SetTextForeground(*wxBLACK
); 
2212     if ( flags 
& wxCONTROL_FOCUSED 
) 
2214         if ( focusOffset
.x 
|| focusOffset
.y 
) 
2216             rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
); 
2219         DrawFocusRect(dc
, rectLabel
); 
2223         *rectBounds 
= rectLabel
; 
2226 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
, 
2227                                       const wxString
& label
, 
2228                                       const wxBitmap
& image
, 
2235     // the underscores are not drawn for focused controls in wxMSW 
2236     if ( flags 
& wxCONTROL_PRESSED 
) 
2241     wxRect rectLabel 
= rect
; 
2242     if ( !label
.empty() ) 
2244         // shift the label if a button is pressed 
2245         if ( flags 
& wxCONTROL_PRESSED 
) 
2251         if ( flags 
& wxCONTROL_DISABLED 
) 
2253             DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
); 
2256         // leave enough space for the focus rectangle 
2257         if ( flags 
& wxCONTROL_FOCUSED 
) 
2259             rectLabel
.Inflate(-2); 
2263     dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
); 
2265     if ( !label
.empty() && (flags 
& wxCONTROL_FOCUSED
) ) 
2267         if ( flags 
& wxCONTROL_PRESSED 
) 
2269             // the focus rectangle is never pressed, so undo the shift done 
2277         DrawFocusRect(dc
, rectLabel
); 
2281 // ---------------------------------------------------------------------------- 
2282 // (check)listbox items 
2283 // ---------------------------------------------------------------------------- 
2285 void wxWin32Renderer::DrawItem(wxDC
& dc
, 
2286                                const wxString
& label
, 
2290     wxDCTextColourChanger 
colChanger(dc
); 
2292     if ( flags 
& wxCONTROL_SELECTED 
) 
2294         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
2296         wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
2297         dc
.SetBrush(wxBrush(colBg
, wxSOLID
)); 
2298         dc
.SetPen(wxPen(colBg
, 0, wxSOLID
)); 
2299         dc
.DrawRectangle(rect
); 
2302     wxRect rectText 
= rect
; 
2304     rectText
.width 
-= 2; 
2305     dc
.DrawLabel(label
, wxNullBitmap
, rectText
); 
2307     if ( flags 
& wxCONTROL_FOCUSED 
) 
2309         DrawFocusRect(dc
, rect
); 
2313 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
, 
2314                                     const wxString
& label
, 
2315                                     const wxBitmap
& bitmap
, 
2324     else // use default bitmap 
2326         IndicatorStatus i 
= flags 
& wxCONTROL_CHECKED
 
2327                                 ? IndicatorStatus_Checked
 
2328                                 : IndicatorStatus_Unchecked
; 
2330         if ( !m_bmpCheckBitmaps
[i
].Ok() ) 
2332             m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]); 
2335         bmp 
= m_bmpCheckBitmaps
[i
]; 
2338     dc
.DrawBitmap(bmp
, rect
.x
, rect
.y 
+ (rect
.height 
- bmp
.GetHeight()) / 2 - 1, 
2339                   true /* use mask */); 
2341     wxRect rectLabel 
= rect
; 
2342     int bmpWidth 
= bmp
.GetWidth(); 
2343     rectLabel
.x 
+= bmpWidth
; 
2344     rectLabel
.width 
-= bmpWidth
; 
2346     DrawItem(dc
, label
, rectLabel
, flags
); 
2349 // ---------------------------------------------------------------------------- 
2350 // check/radio buttons 
2351 // ---------------------------------------------------------------------------- 
2353 wxBitmap 
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
) 
2355     IndicatorState indState
; 
2356     if ( flags 
& wxCONTROL_SELECTED 
) 
2357         indState 
= flags 
& wxCONTROL_DISABLED 
? IndicatorState_SelectedDisabled
 
2358                                               : IndicatorState_Selected
; 
2359     else if ( flags 
& wxCONTROL_DISABLED 
) 
2360         indState 
= IndicatorState_Disabled
; 
2361     else if ( flags 
& wxCONTROL_PRESSED 
) 
2362         indState 
= IndicatorState_Pressed
; 
2364         indState 
= IndicatorState_Normal
; 
2366     IndicatorStatus indStatus 
= flags 
& wxCONTROL_CHECKED
 
2367                                     ? IndicatorStatus_Checked
 
2368                                     : ( flags 
& wxCONTROL_UNDETERMINED
 
2369                                           ? IndicatorStatus_Undeterminated
 
2370                                           : IndicatorStatus_Unchecked 
); 
2372     wxBitmap bmp 
= m_bmpIndicators
[indType
][indState
][indStatus
]; 
2375         const char **xpm 
= xpmIndicators
[indType
][indState
][indStatus
]; 
2378             // create and cache it 
2379             bmp 
= wxBitmap(xpm
); 
2380             m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
; 
2387 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
, 
2388                                              const wxString
& label
, 
2389                                              const wxBitmap
& bitmap
, 
2394                                              wxCoord focusOffsetY
) 
2396     // calculate the position of the bitmap and of the label 
2397     wxCoord heightBmp 
= bitmap
.GetHeight(); 
2399             yBmp 
= rect
.y 
+ (rect
.height 
- heightBmp
) / 2; 
2402     dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
); 
2403     rectLabel
.y 
= rect
.y 
+ (rect
.height 
- rectLabel
.height
) / 2; 
2405     // align label vertically with the bitmap - looks nicer like this 
2406     rectLabel
.y 
-= (rectLabel
.height 
- heightBmp
) % 2; 
2408     // calc horz position 
2409     if ( align 
== wxALIGN_RIGHT 
) 
2411         xBmp 
= rect
.GetRight() - bitmap
.GetWidth(); 
2412         rectLabel
.x 
= rect
.x 
+ 3; 
2413         rectLabel
.SetRight(xBmp
); 
2415     else // normal (checkbox to the left of the text) case 
2418         rectLabel
.x 
= xBmp 
+ bitmap
.GetWidth() + 5; 
2419         rectLabel
.SetRight(rect
.GetRight()); 
2422     dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */); 
2425                 dc
, label
, rectLabel
, 
2427                 wxALIGN_LEFT 
| wxALIGN_TOP
, 
2429                 NULL
,         // we don't need bounding rect 
2430                 // use custom vert focus rect offset 
2431                 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
) 
2435 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
, 
2436                                       const wxString
& label
, 
2437                                       const wxBitmap
& bitmap
, 
2447         bmp 
= GetRadioBitmap(flags
); 
2449     DrawCheckOrRadioButton(dc
, label
, 
2451                            rect
, flags
, align
, indexAccel
, 
2452                            FOCUS_RECT_OFFSET_Y
); // default focus rect offset 
2455 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
, 
2456                                       const wxString
& label
, 
2457                                       const wxBitmap
& bitmap
, 
2467         bmp 
= GetCheckBitmap(flags
); 
2469     DrawCheckOrRadioButton(dc
, label
, 
2471                            rect
, flags
, align
, indexAccel
, 
2472                            0); // no focus rect offset for checkboxes 
2475 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
, 
2476                                         const wxString
& label
, 
2477                                         const wxBitmap
& bitmap
, 
2478                                         const wxRect
& rectOrig
, 
2482     if (style 
== wxTOOL_STYLE_BUTTON
) 
2484         wxRect rect 
= rectOrig
; 
2485         rect
.Deflate(BORDER_THICKNESS
); 
2487         if ( flags 
& wxCONTROL_PRESSED 
) 
2489             DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
); 
2491         else if ( flags 
& wxCONTROL_CURRENT 
) 
2493             DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
); 
2496         dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
); 
2498     else if (style 
== wxTOOL_STYLE_SEPARATOR
) 
2500         // leave a small gap aroudn the line, also account for the toolbar 
2502         DrawVerticalLine(dc
, rectOrig
.x 
+ rectOrig
.width
/2, 
2503                          rectOrig
.y 
+ 2*BORDER_THICKNESS
, 
2504                          rectOrig
.GetBottom() - BORDER_THICKNESS
); 
2506     // don't draw wxTOOL_STYLE_CONTROL 
2509 // ---------------------------------------------------------------------------- 
2511 // ---------------------------------------------------------------------------- 
2513 void wxWin32Renderer::DrawTextLine(wxDC
& dc
, 
2514                                    const wxString
& text
, 
2520     // nothing special to do here 
2521     StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
); 
2525 wxWin32Renderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
), 
2526                                   const wxRect
& WXUNUSED(rect
)) 
2528     // we don't draw them 
2531 // ---------------------------------------------------------------------------- 
2533 // ---------------------------------------------------------------------------- 
2535 void wxWin32Renderer::DrawTab(wxDC
& dc
, 
2536                               const wxRect
& rectOrig
, 
2538                               const wxString
& label
, 
2539                               const wxBitmap
& bitmap
, 
2543     #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X ) 
2544     #define REVERSE_FOR_VERTICAL(X,Y) \ 
2545         SELECT_FOR_VERTICAL(X,Y)      \ 
2547         SELECT_FOR_VERTICAL(Y,X) 
2549     wxRect rect 
= rectOrig
; 
2551     bool isVertical 
= ( dir 
== wxLEFT 
) || ( dir 
== wxRIGHT 
); 
2553     // the current tab is drawn indented (to the top for default case) and 
2554     // bigger than the other ones 
2555     const wxSize indent 
= GetTabIndent(); 
2556     if ( flags 
& wxCONTROL_SELECTED 
) 
2558         rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x 
, 0), 
2559                       SELECT_FOR_VERTICAL( 0, indent
.y 
)); 
2563                 wxFAIL_MSG(_T("invaild notebook tab orientation")); 
2570                 rect
.height 
+= indent
.y
; 
2577                 rect
.width 
+= indent
.x
; 
2582     // draw the text, image and the focus around them (if necessary) 
2583     wxRect 
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
), 
2584                       REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
) 
2586     rectLabel
.Deflate(1, 1); 
2589         // draw it horizontally into memory and rotate for screen 
2591         wxBitmap bitmapRotated
, 
2592                  bitmapMem( rectLabel
.x 
+ rectLabel
.width
, 
2593                             rectLabel
.y 
+ rectLabel
.height 
); 
2594         dcMem
.SelectObject(bitmapMem
); 
2595         dcMem
.SetBackground(dc
.GetBackground()); 
2596         dcMem
.SetFont(dc
.GetFont()); 
2597         dcMem
.SetTextForeground(dc
.GetTextForeground()); 
2599         bitmapRotated 
= wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) ); 
2600         DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
, 
2601                         flags
, wxALIGN_CENTRE
, indexAccel
); 
2602         dcMem
.SelectObject(wxNullBitmap
); 
2603         bitmapMem 
= bitmapMem
.GetSubBitmap(rectLabel
); 
2604         bitmapMem 
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
)); 
2605         dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false); 
2609         DrawButtonLabel(dc
, label
, bitmap
, rectLabel
, 
2610                         flags
, wxALIGN_CENTRE
, indexAccel
); 
2613     // now draw the tab border itself (maybe use DrawRoundedRectangle()?) 
2614     static const wxCoord CUTOFF 
= 2; // radius of the rounded corner 
2615     wxCoord x 
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
), 
2616             y 
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
), 
2617             x2 
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()), 
2618             y2 
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight()); 
2620     // FIXME: all this code will break if the tab indent or the border width, 
2621     //        it is tied to the fact that both of them are equal to 2 
2627             // left orientation looks like top but IsVertical makes x and y reversed 
2629             // top is not vertical so use coordinates in written order 
2630             dc
.SetPen(m_penHighlight
); 
2631             dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
), 
2632                         REVERSE_FOR_VERTICAL(x
, y 
+ CUTOFF
)); 
2633             dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y 
+ CUTOFF
), 
2634                         REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y
)); 
2635             dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y
), 
2636                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF 
+ 1, y
)); 
2638             dc
.SetPen(m_penBlack
); 
2639             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
), 
2640                         REVERSE_FOR_VERTICAL(x2
, y 
+ CUTOFF
)); 
2641             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y 
+ CUTOFF
), 
2642                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF
, y
)); 
2644             dc
.SetPen(m_penDarkGrey
); 
2645             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2 
- 1, y2
), 
2646                         REVERSE_FOR_VERTICAL(x2 
- 1, y 
+ CUTOFF 
- 1)); 
2648             if ( flags 
& wxCONTROL_SELECTED 
) 
2650                 dc
.SetPen(m_penLightGrey
); 
2652                 // overwrite the part of the border below this tab 
2653                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y2 
+ 1), 
2654                             REVERSE_FOR_VERTICAL(x2 
- 1, y2 
+ 1)); 
2656                 // and the shadow of the tab to the left of us 
2657                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y 
+ CUTOFF 
+ 1), 
2658                             REVERSE_FOR_VERTICAL(x 
+ 1, y2 
+ 1)); 
2663             // right orientation looks like bottom but IsVertical makes x and y reversed 
2665             // bottom is not vertical so use coordinates in written order 
2666             dc
.SetPen(m_penHighlight
); 
2667             // we need to continue one pixel further to overwrite the corner of 
2668             // the border for the selected tab 
2669             dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y 
- (flags 
& wxCONTROL_SELECTED 
? 1 : 0)), 
2670                         REVERSE_FOR_VERTICAL(x
, y2 
- CUTOFF
)); 
2671             dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2 
- CUTOFF
), 
2672                         REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y2
)); 
2674             dc
.SetPen(m_penBlack
); 
2675             dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y2
), 
2676                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF 
+ 1, y2
)); 
2677             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
), 
2678                         REVERSE_FOR_VERTICAL(x2
, y2 
- CUTOFF
)); 
2679             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2 
- CUTOFF
), 
2680                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF
, y2
)); 
2682             dc
.SetPen(m_penDarkGrey
); 
2683             dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ CUTOFF
, y2 
- 1), 
2684                         REVERSE_FOR_VERTICAL(x2 
- CUTOFF 
+ 1, y2 
- 1)); 
2685             dc
.DrawLine(REVERSE_FOR_VERTICAL(x2 
- 1, y
), 
2686                         REVERSE_FOR_VERTICAL(x2 
- 1, y2 
- CUTOFF 
+ 1)); 
2688             if ( flags 
& wxCONTROL_SELECTED 
) 
2690                 dc
.SetPen(m_penLightGrey
); 
2692                 // overwrite the part of the (double!) border above this tab 
2693                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y 
- 1), 
2694                             REVERSE_FOR_VERTICAL(x2 
- 1, y 
- 1)); 
2695                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y 
- 2), 
2696                             REVERSE_FOR_VERTICAL(x2 
- 1, y 
- 2)); 
2698                 // and the shadow of the tab to the left of us 
2699                 dc
.DrawLine(REVERSE_FOR_VERTICAL(x 
+ 1, y2 
- CUTOFF
), 
2700                             REVERSE_FOR_VERTICAL(x 
+ 1, y 
- 1)); 
2705     #undef SELECT_FOR_VERTICAL 
2706     #undef REVERSE_FOR_VERTICAL 
2709 // ---------------------------------------------------------------------------- 
2711 // ---------------------------------------------------------------------------- 
2714 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
), 
2716                                     wxOrientation orient
) const 
2719     wxCoord width  
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2; 
2720     wxCoord height 
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
); 
2722     if (orient 
== wxHORIZONTAL
) 
2736 wxRect 
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
, 
2738                                            wxOrientation orient
, 
2741     bool transpose 
= (orient 
== wxVERTICAL
); 
2742     bool left  
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2743                  (((style 
& wxSL_TOP
) != 0) & !transpose 
| 
2744                   ((style 
& wxSL_LEFT
) != 0) & transpose 
| 
2745                   ((style 
& wxSL_BOTH
) != 0)); 
2746     bool right 
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2747                  (((style 
& wxSL_BOTTOM
) != 0) & !transpose 
| 
2748                   ((style 
& wxSL_RIGHT
) != 0) & transpose 
| 
2749                   ((style 
& wxSL_BOTH
) != 0)); 
2751     wxRect rect 
= rectOrig
; 
2753     wxSize sizeThumb 
= GetSliderThumbSize (rect
, lenThumb
, orient
); 
2755     if (orient 
== wxHORIZONTAL
) { 
2756         rect
.x 
+= SLIDER_MARGIN
; 
2759             rect
.y 
+= wxMax ((rect
.height 
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2); 
2763             rect
.y 
+= wxMax ((rect
.height 
- 2*BORDER_THICKNESS 
- sizeThumb
.y
/2), sizeThumb
.y
/2); 
2767             rect
.y 
+= sizeThumb
.y
/2; 
2769         rect
.width 
-= 2*SLIDER_MARGIN
; 
2770         rect
.height 
= 2*BORDER_THICKNESS
; 
2774         rect
.y 
+= SLIDER_MARGIN
; 
2777             rect
.x 
+= wxMax ((rect
.width 
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2); 
2781             rect
.x 
+= wxMax ((rect
.width 
- 2*BORDER_THICKNESS 
- sizeThumb
.x
/2), sizeThumb
.x
/2); 
2785             rect
.x 
+= sizeThumb
.x
/2; 
2787         rect
.width 
= 2*BORDER_THICKNESS
; 
2788         rect
.height 
-= 2*SLIDER_MARGIN
; 
2794 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
, 
2795                                       const wxRect
& rectOrig
, 
2797                                       wxOrientation orient
, 
2802     /*    show shaft geometry 
2820     if (flags 
& wxCONTROL_FOCUSED
) { 
2821         DrawFocusRect(dc
, rectOrig
); 
2824     wxRect rect 
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
); 
2826     if (rectShaft
) *rectShaft 
= rect
; 
2828     DrawSunkenBorder(dc
, &rect
); 
2831 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
, 
2833                                       wxOrientation orient
, 
2837     /*    show thumb geometry 
2846        H         D B   where H is hightlight colour 
2860        The interior of this shape is filled with the hatched brush if the thumb 
2864     DrawBackground(dc
, wxNullColour
, rect
, flags
); 
2866     bool transpose 
= (orient 
== wxVERTICAL
); 
2867     bool left  
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2868                  (((style 
& wxSL_TOP
) != 0) & !transpose 
| 
2869                   ((style 
& wxSL_LEFT
) != 0) & transpose
) & 
2870                  ((style 
& wxSL_BOTH
) == 0); 
2871     bool right 
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2872                  (((style 
& wxSL_BOTTOM
) != 0) & !transpose 
| 
2873                   ((style 
& wxSL_RIGHT
) != 0) & transpose
) & 
2874                  ((style 
& wxSL_BOTH
) == 0); 
2876     wxCoord sizeArrow 
= (transpose 
? rect
.height 
: rect
.width
) / 2; 
2877     wxCoord c 
= ((transpose 
? rect
.height 
: rect
.width
) - 2*sizeArrow
); 
2879     wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
; 
2880     x1 
= (transpose 
? rect
.y 
: rect
.x
); 
2881     x2 
= (transpose 
? rect
.GetBottom() : rect
.GetRight()); 
2882     x3 
= (x1
-1+c
) + sizeArrow
; 
2883     y1 
= (transpose 
? rect
.x 
: rect
.y
); 
2884     y2 
= (transpose 
? rect
.GetRight() : rect
.GetBottom()); 
2885     y3 
= (left  
? (y1
-1+c
) + sizeArrow 
: y1
); 
2886     y4 
= (right 
? (y2
+1-c
) - sizeArrow 
: y2
); 
2888     dc
.SetPen(m_penBlack
); 
2890         DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
); 
2892     DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
); 
2895         DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
); 
2899         DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
); 
2902     dc
.SetPen(m_penDarkGrey
); 
2903     DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
); 
2905         DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
); 
2909         DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
); 
2912     dc
.SetPen(m_penHighlight
); 
2915         DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
); 
2916         DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
); 
2920         DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
); 
2922     DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
); 
2925         DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
); 
2928     if (flags 
& wxCONTROL_PRESSED
) { 
2929         // TODO: MSW fills the entire area inside, not just the rect 
2930         wxRect rectInt 
= rect
; 
2933             rectInt
.SetLeft(y3
); 
2934             rectInt
.SetRight(y4
); 
2939             rectInt
.SetBottom(y4
); 
2943 #if !defined(__WXMGL__) 
2944         static const char *stipple_xpm
[] = { 
2945             /* columns rows colors chars-per-pixel */ 
2954         // VS: MGL can only do 8x8 stipple brushes 
2955         static const char *stipple_xpm
[] = { 
2956             /* columns rows colors chars-per-pixel */ 
2971         dc
.SetBrush(wxBrush(stipple_xpm
)); 
2973         dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
)); 
2974         dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
)); 
2975         dc
.SetPen(*wxTRANSPARENT_PEN
); 
2976         dc
.DrawRectangle(rectInt
); 
2980 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
, 
2983                                       wxOrientation orient
, 
2987                                       int WXUNUSED(flags
), 
2990     /*    show ticks geometry 
3005     if (end 
== start
) return; 
3007     bool transpose 
= (orient 
== wxVERTICAL
); 
3008     bool left  
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
3009                  (((style 
& wxSL_TOP
) != 0) & !transpose 
| 
3010                   ((style 
& wxSL_LEFT
) != 0) & transpose 
| 
3011                   ((style 
& wxSL_BOTH
) != 0)); 
3012     bool right 
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
3013                  (((style 
& wxSL_BOTTOM
) != 0) & !transpose 
| 
3014                   ((style 
& wxSL_RIGHT
) != 0) & transpose 
| 
3015                   ((style 
& wxSL_BOTH
) != 0)); 
3017     // default thumb size 
3018     wxSize sizeThumb 
= GetSliderThumbSize (rect
, 0, orient
); 
3019     wxCoord defaultLen 
= (transpose 
? sizeThumb
.x 
: sizeThumb
.y
); 
3021     // normal thumb size 
3022     sizeThumb 
= GetSliderThumbSize (rect
, lenThumb
, orient
); 
3023     wxCoord widthThumb  
= (transpose 
? sizeThumb
.y 
: sizeThumb
.x
); 
3025     wxRect rectShaft 
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
); 
3027     wxCoord x1
, x2
, y1
, y2
, y3
, y4 
, len
; 
3028     x1 
= (transpose 
? rectShaft
.y 
: rectShaft
.x
) + widthThumb
/2; 
3029     x2 
= (transpose 
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2; 
3030     y1 
= (transpose 
? rectShaft
.x 
: rectShaft
.y
) - defaultLen
/2; 
3031     y2 
= (transpose 
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2; 
3032     y3 
= (transpose 
? rect
.x 
: rect
.y
); 
3033     y4 
= (transpose 
? rect
.GetRight() : rect
.GetBottom()); 
3036     dc
.SetPen(m_penBlack
); 
3038     int range 
= end 
- start
; 
3039     for ( int n 
= 0; n 
< range
; n 
+= step 
) { 
3040         wxCoord x 
= x1 
+ (len
*n
) / range
; 
3042         if (left 
& (y1 
> y3
)) { 
3043             DrawLine(dc
, x
, y1
, x
, y3
, orient 
== wxVERTICAL
); 
3045         if (right 
& (y4 
> y2
)) { 
3046             DrawLine(dc
, x
, y2
, x
, y4
, orient 
== wxVERTICAL
); 
3049     // always draw the line at the end position 
3050     if (left 
& (y1 
> y3
)) { 
3051         DrawLine(dc
, x2
, y1
, x2
, y3
, orient 
== wxVERTICAL
); 
3053     if (right 
& (y4 
> y2
)) { 
3054         DrawLine(dc
, x2
, y2
, x2
, y4
, orient 
== wxVERTICAL
); 
3058 // ---------------------------------------------------------------------------- 
3060 // ---------------------------------------------------------------------------- 
3062 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer 
3063 class WXDLLEXPORT wxWin32MenuGeometryInfo 
: public wxMenuGeometryInfo
 
3066     virtual wxSize 
GetSize() const { return m_size
; } 
3068     wxCoord 
GetLabelOffset() const { return m_ofsLabel
; } 
3069     wxCoord 
GetAccelOffset() const { return m_ofsAccel
; } 
3071     wxCoord 
GetItemHeight() const { return m_heightItem
; } 
3074     // the total size of the menu 
3077     // the offset of the start of the menu item label 
3080     // the offset of the start of the accel label 
3083     // the height of a normal (not separator) item 
3084     wxCoord m_heightItem
; 
3086     friend wxMenuGeometryInfo 
* 
3087         wxWin32Renderer::GetMenuGeometry(wxWindow 
*, const wxMenu
&) const; 
3090 // FIXME: all constants are hardcoded but shouldn't be 
3091 static const wxCoord MENU_LEFT_MARGIN 
= 9; 
3092 static const wxCoord MENU_RIGHT_MARGIN 
= 18; 
3093 static const wxCoord MENU_VERT_MARGIN 
= 3; 
3095 // the margin around bitmap/check marks (on each side) 
3096 static const wxCoord MENU_BMP_MARGIN 
= 2; 
3098 // the margin between the labels and accel strings 
3099 static const wxCoord MENU_ACCEL_MARGIN 
= 8; 
3101 // the separator height in pixels: in fact, strangely enough, the real height 
3102 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into 
3104 static const wxCoord MENU_SEPARATOR_HEIGHT 
= 3; 
3106 // the size of the standard checkmark bitmap 
3107 static const wxCoord MENU_CHECK_SIZE 
= 9; 
3109 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
, 
3110                                       const wxRect
& rectOrig
, 
3111                                       const wxString
& label
, 
3115     wxRect rect 
= rectOrig
; 
3118     wxDCTextColourChanger 
colChanger(dc
); 
3120     if ( flags 
& wxCONTROL_SELECTED 
) 
3122         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
3124         wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
3125         dc
.SetBrush(wxBrush(colBg
, wxSOLID
)); 
3126         dc
.SetPen(wxPen(colBg
, 0, wxSOLID
)); 
3127         dc
.DrawRectangle(rect
); 
3130     // don't draw the focus rect around menu bar items 
3131     DrawLabel(dc
, label
, rect
, flags 
& ~wxCONTROL_FOCUSED
, 
3132               wxALIGN_CENTRE
, indexAccel
); 
3135 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
, 
3137                                    const wxMenuGeometryInfo
& gi
, 
3138                                    const wxString
& label
, 
3139                                    const wxString
& accel
, 
3140                                    const wxBitmap
& bitmap
, 
3144     const wxWin32MenuGeometryInfo
& geometryInfo 
= 
3145         (const wxWin32MenuGeometryInfo
&)gi
; 
3150     rect
.width 
= geometryInfo
.GetSize().x
; 
3151     rect
.height 
= geometryInfo
.GetItemHeight(); 
3153     // draw the selected item specially 
3154     wxDCTextColourChanger 
colChanger(dc
); 
3155     if ( flags 
& wxCONTROL_SELECTED 
) 
3157         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
3159         wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
3160         dc
.SetBrush(wxBrush(colBg
, wxSOLID
)); 
3161         dc
.SetPen(wxPen(colBg
, 0, wxSOLID
)); 
3162         dc
.DrawRectangle(rect
); 
3165     // draw the bitmap: use the bitmap provided or the standard checkmark for 
3166     // the checkable items 
3167     wxBitmap bmp 
= bitmap
; 
3168     if ( !bmp
.Ok() && (flags 
& wxCONTROL_CHECKED
) ) 
3170         bmp 
= GetIndicator(IndicatorType_Menu
, flags
); 
3175         rect
.SetRight(geometryInfo
.GetLabelOffset()); 
3176         wxControlRenderer::DrawBitmap(dc
, bmp
, rect
); 
3180     rect
.x 
= geometryInfo
.GetLabelOffset(); 
3181     rect
.SetRight(geometryInfo
.GetAccelOffset()); 
3183     DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
); 
3185     // draw the accel string 
3186     rect
.x 
= geometryInfo
.GetAccelOffset(); 
3187     rect
.SetRight(geometryInfo
.GetSize().x
); 
3189     // NB: no accel index here 
3190     DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
); 
3192     // draw the submenu indicator 
3193     if ( flags 
& wxCONTROL_ISSUBMENU 
) 
3195         rect
.x 
= geometryInfo
.GetSize().x 
- MENU_RIGHT_MARGIN
; 
3196         rect
.width 
= MENU_RIGHT_MARGIN
; 
3198         wxArrowStyle arrowStyle
; 
3199         if ( flags 
& wxCONTROL_DISABLED 
) 
3200             arrowStyle 
= flags 
& wxCONTROL_SELECTED 
? Arrow_InversedDisabled
 
3202         else if ( flags 
& wxCONTROL_SELECTED 
) 
3203             arrowStyle 
= Arrow_Inversed
; 
3205             arrowStyle 
= Arrow_Normal
; 
3207         DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
); 
3211 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
, 
3213                                         const wxMenuGeometryInfo
& geomInfo
) 
3215     DrawHorizontalLine(dc
, y 
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
); 
3218 wxSize 
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const 
3220     wxSize size 
= sizeText
; 
3222     // FIXME: menubar height is configurable under Windows 
3229 wxMenuGeometryInfo 
*wxWin32Renderer::GetMenuGeometry(wxWindow 
*win
, 
3230                                                      const wxMenu
& menu
) const 
3232     // prepare the dc: for now we draw all the items with the system font 
3234     dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
3236     // the height of a normal item 
3237     wxCoord heightText 
= dc
.GetCharHeight(); 
3242     // the max length of label and accel strings: the menu width is the sum of 
3243     // them, even if they're for different items (as the accels should be 
3246     // the max length of the bitmap is never 0 as Windows always leaves enough 
3247     // space for a check mark indicator 
3248     wxCoord widthLabelMax 
= 0, 
3250             widthBmpMax 
= MENU_LEFT_MARGIN
; 
3252     for ( wxMenuItemList::compatibility_iterator node 
= menu
.GetMenuItems().GetFirst(); 
3254           node 
= node
->GetNext() ) 
3256         // height of this item 
3259         wxMenuItem 
*item 
= node
->GetData(); 
3260         if ( item
->IsSeparator() ) 
3262             h 
= MENU_SEPARATOR_HEIGHT
; 
3264         else // not separator 
3269             dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
); 
3270             if ( widthLabel 
> widthLabelMax 
) 
3272                 widthLabelMax 
= widthLabel
; 
3276             dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
); 
3277             if ( widthAccel 
> widthAccelMax 
) 
3279                 widthAccelMax 
= widthAccel
; 
3282             const wxBitmap
& bmp 
= item
->GetBitmap(); 
3285                 wxCoord widthBmp 
= bmp
.GetWidth(); 
3286                 if ( widthBmp 
> widthBmpMax 
) 
3287                     widthBmpMax 
= widthBmp
; 
3289             //else if ( item->IsCheckable() ): no need to check for this as 
3290             // MENU_LEFT_MARGIN is big enough to show the check mark 
3293         h 
+= 2*MENU_VERT_MARGIN
; 
3295         // remember the item position and height 
3296         item
->SetGeometry(height
, h
); 
3301     // bundle the metrics into a struct and return it 
3302     wxWin32MenuGeometryInfo 
*gi 
= new wxWin32MenuGeometryInfo
; 
3304     gi
->m_ofsLabel 
= widthBmpMax 
+ 2*MENU_BMP_MARGIN
; 
3305     gi
->m_ofsAccel 
= gi
->m_ofsLabel 
+ widthLabelMax
; 
3306     if ( widthAccelMax 
> 0 ) 
3308         // if we actually have any accesl, add a margin 
3309         gi
->m_ofsAccel 
+= MENU_ACCEL_MARGIN
; 
3312     gi
->m_heightItem 
= heightText 
+ 2*MENU_VERT_MARGIN
; 
3314     gi
->m_size
.x 
= gi
->m_ofsAccel 
+ widthAccelMax 
+ MENU_RIGHT_MARGIN
; 
3315     gi
->m_size
.y 
= height
; 
3320 // ---------------------------------------------------------------------------- 
3322 // ---------------------------------------------------------------------------- 
3324 static const wxCoord STATBAR_BORDER_X 
= 2; 
3325 static const wxCoord STATBAR_BORDER_Y 
= 2; 
3327 wxSize 
wxWin32Renderer::GetStatusBarBorders(wxCoord 
*borderBetweenFields
) const 
3329     if ( borderBetweenFields 
) 
3330         *borderBetweenFields 
= 2; 
3332     return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
); 
3335 void wxWin32Renderer::DrawStatusField(wxDC
& dc
, 
3337                                       const wxString
& label
, 
3338                                       int flags
, int style 
/*=0*/) 
3342     if ( flags 
& wxCONTROL_ISDEFAULT 
) 
3344         // draw the size grip: it is a normal rect except that in the lower 
3345         // right corner we have several bands which may be used for dragging 
3346         // the status bar corner 
3348         // each band consists of 4 stripes: m_penHighlight, double 
3349         // m_penDarkGrey and transparent one 
3350         wxCoord x2 
= rect
.GetRight(), 
3351                 y2 
= rect
.GetBottom(); 
3353         // draw the upper left part of the rect normally 
3354         if (style 
!= wxSB_FLAT
) 
3356             if (style 
== wxSB_RAISED
) 
3357                 dc
.SetPen(m_penHighlight
); 
3359                 dc
.SetPen(m_penDarkGrey
); 
3360             dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
); 
3361             dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop()); 
3364         // draw the grey stripes of the grip 
3366         wxCoord ofs 
= WIDTH_STATUSBAR_GRIP_BAND 
- 1; 
3367         for ( n 
= 0; n 
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs 
+= WIDTH_STATUSBAR_GRIP_BAND 
) 
3369             dc
.DrawLine(x2 
- ofs 
+ 1, y2 
- 1, x2
, y2 
- ofs
); 
3370             dc
.DrawLine(x2 
- ofs
, y2 
- 1, x2
, y2 
- ofs 
- 1); 
3373         // draw the white stripes 
3374         dc
.SetPen(m_penHighlight
); 
3375         ofs 
= WIDTH_STATUSBAR_GRIP_BAND 
+ 1; 
3376         for ( n 
= 0; n 
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs 
+= WIDTH_STATUSBAR_GRIP_BAND 
) 
3378             dc
.DrawLine(x2 
- ofs 
+ 1, y2 
- 1, x2
, y2 
- ofs
); 
3381         // draw the remaining rect boundaries 
3382         if (style 
!= wxSB_FLAT
) 
3384             if (style 
== wxSB_RAISED
) 
3385                 dc
.SetPen(m_penDarkGrey
); 
3387                 dc
.SetPen(m_penHighlight
); 
3388             ofs 
-= WIDTH_STATUSBAR_GRIP_BAND
; 
3389             dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2 
- ofs 
+ 1); 
3390             dc
.DrawLine(rect
.GetLeft(), y2
, x2 
- ofs 
+ 1, y2
); 
3396         rectIn
.width 
-= STATUSBAR_GRIP_SIZE
; 
3400         if (style 
== wxSB_RAISED
) 
3401             DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
); 
3402         else if (style 
!= wxSB_FLAT
) 
3403             DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
); 
3406     rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
); 
3408     wxDCClipper 
clipper(dc
, rectIn
); 
3409     DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT 
| wxALIGN_CENTRE_VERTICAL
); 
3412 // ---------------------------------------------------------------------------- 
3414 // ---------------------------------------------------------------------------- 
3416 void wxWin32Renderer::GetComboBitmaps(wxBitmap 
*bmpNormal
, 
3417                                       wxBitmap 
* WXUNUSED(bmpFocus
), 
3418                                       wxBitmap 
*bmpPressed
, 
3419                                       wxBitmap 
*bmpDisabled
) 
3421     static const wxCoord widthCombo 
= 16; 
3422     static const wxCoord heightCombo 
= 17; 
3428         bmpNormal
->Create(widthCombo
, heightCombo
); 
3429         dcMem
.SelectObject(*bmpNormal
); 
3430         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
3431                         Arrow_Down
, Arrow_Normal
); 
3436         bmpPressed
->Create(widthCombo
, heightCombo
); 
3437         dcMem
.SelectObject(*bmpPressed
); 
3438         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
3439                         Arrow_Down
, Arrow_Pressed
); 
3444         bmpDisabled
->Create(widthCombo
, heightCombo
); 
3445         dcMem
.SelectObject(*bmpDisabled
); 
3446         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
3447                         Arrow_Down
, Arrow_Disabled
); 
3451 // ---------------------------------------------------------------------------- 
3453 // ---------------------------------------------------------------------------- 
3455 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
, 
3456                                        const wxColour
& col
, 
3458                                        wxWindow 
* WXUNUSED(window
)) 
3460     wxBrush 
brush(col
, wxSOLID
); 
3462     dc
.SetPen(*wxTRANSPARENT_PEN
); 
3463     dc
.DrawRectangle(rect
); 
3466 void wxWin32Renderer::DrawBackground(wxDC
& dc
, 
3467                                      const wxColour
& col
, 
3469                                      int WXUNUSED(flags
), 
3472     // just fill it with the given or default bg colour 
3473     wxColour colBg 
= col
.Ok() ? col 
: wxSCHEME_COLOUR(m_scheme
, CONTROL
); 
3474     DoDrawBackground(dc
, colBg
, rect
, window 
); 
3477 // ---------------------------------------------------------------------------- 
3479 // ---------------------------------------------------------------------------- 
3481 void wxWin32Renderer::DrawArrow(wxDC
& dc
, 
3486     // get the bitmap for this arrow 
3487     wxArrowDirection arrowDir
; 
3490         case wxLEFT
:    arrowDir 
= Arrow_Left
; break; 
3491         case wxRIGHT
:   arrowDir 
= Arrow_Right
; break; 
3492         case wxUP
:      arrowDir 
= Arrow_Up
; break; 
3493         case wxDOWN
:    arrowDir 
= Arrow_Down
; break; 
3496             wxFAIL_MSG(_T("unknown arrow direction")); 
3500     wxArrowStyle arrowStyle
; 
3501     if ( flags 
& wxCONTROL_PRESSED 
) 
3503         // can't be pressed and disabled 
3504         arrowStyle 
= Arrow_Pressed
; 
3508         arrowStyle 
= flags 
& wxCONTROL_DISABLED 
? Arrow_Disabled 
: Arrow_Normal
; 
3511     DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
); 
3514 void wxWin32Renderer::DrawArrow(wxDC
& dc
, 
3516                                 wxArrowDirection arrowDir
, 
3517                                 wxArrowStyle arrowStyle
) 
3519     const wxBitmap
& bmp 
= m_bmpArrows
[arrowStyle
][arrowDir
]; 
3521     // under Windows the arrows always have the same size so just centre it in 
3522     // the provided rectangle 
3523     wxCoord x 
= rect
.x 
+ (rect
.width 
- bmp
.GetWidth()) / 2, 
3524             y 
= rect
.y 
+ (rect
.height 
- bmp
.GetHeight()) / 2; 
3526     // Windows does it like this... 
3527     if ( arrowDir 
== Arrow_Left 
) 
3531     dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */); 
3534 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
, 
3535                                       const wxRect
& rectAll
, 
3536                                       wxArrowDirection arrowDir
, 
3537                                       wxArrowStyle arrowStyle
) 
3539     wxRect rect 
= rectAll
; 
3540     DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
); 
3541     DrawArrowBorder(dc
, &rect
, arrowStyle 
== Arrow_Pressed
); 
3542     DrawArrow(dc
, rect
, arrowDir
, arrowStyle
); 
3545 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
, 
3546                                          wxOrientation 
WXUNUSED(orient
), 
3548                                          int WXUNUSED(flags
)) 
3550     // we don't use the flags, the thumb never changes appearance 
3551     wxRect rectThumb 
= rect
; 
3552     DrawArrowBorder(dc
, &rectThumb
); 
3553     DrawBackground(dc
, wxNullColour
, rectThumb
); 
3556 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
, 
3557                                          wxOrientation 
WXUNUSED(orient
), 
3558                                          const wxRect
& rectBar
, 
3561     wxColourScheme::StdColour col 
= flags 
& wxCONTROL_PRESSED
 
3562                                     ? wxColourScheme::SCROLLBAR_PRESSED
 
3563                                     : wxColourScheme::SCROLLBAR
; 
3564     DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
); 
3567 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
) 
3569     DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
); 
3572 wxRect 
wxWin32Renderer::GetScrollbarRect(const wxScrollBar 
*scrollbar
, 
3573                                          wxScrollBar::Element elem
, 
3576     return StandardGetScrollbarRect(scrollbar
, elem
, 
3577                                     thumbPos
, m_sizeScrollbarArrow
); 
3580 wxCoord 
wxWin32Renderer::GetScrollbarSize(const wxScrollBar 
*scrollbar
) 
3582     return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
); 
3585 wxHitTest 
wxWin32Renderer::HitTestScrollbar(const wxScrollBar 
*scrollbar
, 
3586                                             const wxPoint
& pt
) const 
3588     return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
); 
3591 wxCoord 
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar 
*scrollbar
, 
3594     return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
); 
3597 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar 
*scrollbar
, 
3600     return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
); 
3603 // ---------------------------------------------------------------------------- 
3604 // top level windows 
3605 // ---------------------------------------------------------------------------- 
3607 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const 
3609     wxRect client 
= GetFrameClientArea(rect
, flags
); 
3611     if ( client
.Inside(pt
) ) 
3612         return wxHT_TOPLEVEL_CLIENT_AREA
; 
3614     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3616         wxRect client 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3618         if ( flags 
& wxTOPLEVEL_ICON 
) 
3620             if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) ) 
3621                 return wxHT_TOPLEVEL_ICON
; 
3624         wxRect 
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
, 
3625                        client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2, 
3626                        FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
); 
3628         if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
3630             if ( btnRect
.Inside(pt
) ) 
3631                 return wxHT_TOPLEVEL_BUTTON_CLOSE
; 
3632             btnRect
.x 
-= FRAME_BUTTON_WIDTH 
+ 2; 
3634         if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
3636             if ( btnRect
.Inside(pt
) ) 
3637                 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
; 
3638             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
3640         if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
3642             if ( btnRect
.Inside(pt
) ) 
3643                 return wxHT_TOPLEVEL_BUTTON_RESTORE
; 
3644             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
3646         if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
3648             if ( btnRect
.Inside(pt
) ) 
3649                 return wxHT_TOPLEVEL_BUTTON_ICONIZE
; 
3650             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
3652         if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
3654             if ( btnRect
.Inside(pt
) ) 
3655                 return wxHT_TOPLEVEL_BUTTON_HELP
; 
3656             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
3659         if ( pt
.y 
>= client
.y 
&& pt
.y 
< client
.y 
+ FRAME_TITLEBAR_HEIGHT 
) 
3660             return wxHT_TOPLEVEL_TITLEBAR
; 
3663     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3665         // we are certainly at one of borders, lets decide which one: 
3668         // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined! 
3669         if ( pt
.x 
< client
.x 
) 
3670             border 
|= wxHT_TOPLEVEL_BORDER_W
; 
3671         else if ( pt
.x 
>= client
.width 
+ client
.x 
) 
3672             border 
|= wxHT_TOPLEVEL_BORDER_E
; 
3673         if ( pt
.y 
< client
.y 
) 
3674             border 
|= wxHT_TOPLEVEL_BORDER_N
; 
3675         else if ( pt
.y 
>= client
.height 
+ client
.y 
) 
3676             border 
|= wxHT_TOPLEVEL_BORDER_S
; 
3680     return wxHT_NOWHERE
; 
3683 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
, 
3685                                         const wxString
& title
, 
3689                                         int specialButtonFlags
) 
3691     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3693         DrawFrameBorder(dc
, rect
, flags
); 
3695     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3697         DrawFrameBackground(dc
, rect
, flags
); 
3698         if ( flags 
& wxTOPLEVEL_ICON 
) 
3699             DrawFrameIcon(dc
, rect
, icon
, flags
); 
3700         DrawFrameTitle(dc
, rect
, title
, flags
); 
3702         wxRect client 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3704         x 
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
; 
3705         y 
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2; 
3707         if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
3709             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
, 
3710                             (specialButton 
== wxTOPLEVEL_BUTTON_CLOSE
) ? 
3711                             specialButtonFlags 
: 0); 
3712             x 
-= FRAME_BUTTON_WIDTH 
+ 2; 
3714         if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
3716             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
, 
3717                             (specialButton 
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ? 
3718                             specialButtonFlags 
: 0); 
3719             x 
-= FRAME_BUTTON_WIDTH
; 
3721         if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
3723             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
, 
3724                             (specialButton 
== wxTOPLEVEL_BUTTON_RESTORE
) ? 
3725                             specialButtonFlags 
: 0); 
3726             x 
-= FRAME_BUTTON_WIDTH
; 
3728         if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
3730             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
, 
3731                             (specialButton 
== wxTOPLEVEL_BUTTON_ICONIZE
) ? 
3732                             specialButtonFlags 
: 0); 
3733             x 
-= FRAME_BUTTON_WIDTH
; 
3735         if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
3737             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
, 
3738                             (specialButton 
== wxTOPLEVEL_BUTTON_HELP
) ? 
3739                             specialButtonFlags 
: 0); 
3744 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
, 
3748     if ( !(flags 
& wxTOPLEVEL_BORDER
) ) return; 
3752     DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
); 
3753     DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
); 
3754     DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
); 
3755     if ( flags 
& wxTOPLEVEL_RESIZEABLE 
) 
3756         DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
); 
3759 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
, 
3763     if ( !(flags 
& wxTOPLEVEL_TITLEBAR
) ) return; 
3765     wxColour col 
= (flags 
& wxTOPLEVEL_ACTIVE
) ? 
3766                    wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) : 
3767                    wxSCHEME_COLOUR(m_scheme
, TITLEBAR
); 
3769     wxRect r 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3770     r
.height 
= FRAME_TITLEBAR_HEIGHT
; 
3772     DrawBackground(dc
, col
, r
); 
3775 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
, 
3777                                      const wxString
& title
, 
3780     wxColour col 
= (flags 
& wxTOPLEVEL_ACTIVE
) ? 
3781                    wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) : 
3782                    wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
); 
3784     wxRect r 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3785     r
.height 
= FRAME_TITLEBAR_HEIGHT
; 
3786     if ( flags 
& wxTOPLEVEL_ICON 
) 
3788         r
.x 
+= FRAME_TITLEBAR_HEIGHT
; 
3789         r
.width 
-= FRAME_TITLEBAR_HEIGHT 
+ 2; 
3797     if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
3798         r
.width 
-= FRAME_BUTTON_WIDTH 
+ 2; 
3799     if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
3800         r
.width 
-= FRAME_BUTTON_WIDTH
; 
3801     if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
3802         r
.width 
-= FRAME_BUTTON_WIDTH
; 
3803     if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
3804         r
.width 
-= FRAME_BUTTON_WIDTH
; 
3805     if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
3806         r
.width 
-= FRAME_BUTTON_WIDTH
; 
3808     dc
.SetFont(m_titlebarFont
); 
3809     dc
.SetTextForeground(col
); 
3812     dc
.GetTextExtent(title
, &textW
, NULL
); 
3813     if ( textW 
> r
.width 
) 
3815         // text is too big, let's shorten it and add "..." after it: 
3816         size_t len 
= title
.length(); 
3817         wxCoord WSoFar
, letterW
; 
3819         dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
); 
3820         if ( WSoFar 
> r
.width 
) 
3822             // not enough space to draw anything 
3828         for (size_t i 
= 0; i 
< len
; i
++) 
3830             dc
.GetTextExtent(title
[i
], &letterW
, NULL
); 
3831             if ( letterW 
+ WSoFar 
> r
.width 
) 
3837         dc
.DrawLabel(s
, wxNullBitmap
, r
, 
3838                      wxALIGN_LEFT 
| wxALIGN_CENTRE_VERTICAL
); 
3841         dc
.DrawLabel(title
, wxNullBitmap
, r
, 
3842                      wxALIGN_LEFT 
| wxALIGN_CENTRE_VERTICAL
); 
3845 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
, 
3852         wxRect r 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3853         dc
.DrawIcon(icon
, r
.x
, r
.y
); 
3857 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
, 
3858                                       wxCoord x
, wxCoord y
, 
3862     wxRect 
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
); 
3867         case wxTOPLEVEL_BUTTON_CLOSE
:    idx 
= FrameButton_Close
; break; 
3868         case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx 
= FrameButton_Maximize
; break; 
3869         case wxTOPLEVEL_BUTTON_ICONIZE
: idx 
= FrameButton_Minimize
; break; 
3870         case wxTOPLEVEL_BUTTON_RESTORE
:  idx 
= FrameButton_Restore
; break; 
3871         case wxTOPLEVEL_BUTTON_HELP
:     idx 
= FrameButton_Help
; break; 
3873             wxFAIL_MSG(wxT("incorrect button specification")); 
3876     if ( flags 
& wxCONTROL_PRESSED 
) 
3878         DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
); 
3879         DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
); 
3880         DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
); 
3881         dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true); 
3885         DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
); 
3886         DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
); 
3887         DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
); 
3888         dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true); 
3893 wxRect 
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
, 
3898     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3900         int border 
= (flags 
& wxTOPLEVEL_RESIZEABLE
) ? 
3901                         RESIZEABLE_FRAME_BORDER_THICKNESS 
: 
3902                         FRAME_BORDER_THICKNESS
; 
3905     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3907         r
.y 
+= FRAME_TITLEBAR_HEIGHT
; 
3908         r
.height 
-= FRAME_TITLEBAR_HEIGHT
; 
3914 wxSize 
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
, 
3917     wxSize 
s(clientSize
); 
3919     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3921         int border 
= (flags 
& wxTOPLEVEL_RESIZEABLE
) ? 
3922                         RESIZEABLE_FRAME_BORDER_THICKNESS 
: 
3923                         FRAME_BORDER_THICKNESS
; 
3927     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3928         s
.y 
+= FRAME_TITLEBAR_HEIGHT
; 
3933 wxSize 
wxWin32Renderer::GetFrameMinSize(int flags
) const 
3937     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3939         int border 
= (flags 
& wxTOPLEVEL_RESIZEABLE
) ? 
3940                         RESIZEABLE_FRAME_BORDER_THICKNESS 
: 
3941                         FRAME_BORDER_THICKNESS
; 
3946     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3948         s
.y 
+= FRAME_TITLEBAR_HEIGHT
; 
3950         if ( flags 
& wxTOPLEVEL_ICON 
) 
3951             s
.x 
+= FRAME_TITLEBAR_HEIGHT 
+ 2; 
3952         if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
3953             s
.x 
+= FRAME_BUTTON_WIDTH 
+ 2; 
3954         if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
3955             s
.x 
+= FRAME_BUTTON_WIDTH
; 
3956         if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
3957             s
.x 
+= FRAME_BUTTON_WIDTH
; 
3958         if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
3959             s
.x 
+= FRAME_BUTTON_WIDTH
; 
3960         if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
3961             s
.x 
+= FRAME_BUTTON_WIDTH
; 
3967 wxSize 
wxWin32Renderer::GetFrameIconSize() const 
3969     return wxSize(16, 16); 
3973 // ---------------------------------------------------------------------------- 
3975 // ---------------------------------------------------------------------------- 
3977 static char *error_xpm
[]={ 
3984 "...........########.............", 
3985 "........###aaaaaaaa###..........", 
3986 ".......#aaaaaaaaaaaaaa#.........", 
3987 ".....##aaaaaaaaaaaaaaaa##.......", 
3988 "....#aaaaaaaaaaaaaaaaaaaa#......", 
3989 "...#aaaaaaaaaaaaaaaaaaaaaa#.....", 
3990 "...#aaaaaaaaaaaaaaaaaaaaaa#b....", 
3991 "..#aaaaaacaaaaaaaaaacaaaaaa#b...", 
3992 ".#aaaaaacccaaaaaaaacccaaaaaa#...", 
3993 ".#aaaaacccccaaaaaacccccaaaaa#b..", 
3994 ".#aaaaaacccccaaaacccccaaaaaa#bb.", 
3995 "#aaaaaaaacccccaacccccaaaaaaaa#b.", 
3996 "#aaaaaaaaaccccccccccaaaaaaaaa#b.", 
3997 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb", 
3998 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb", 
3999 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb", 
4000 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb", 
4001 "#aaaaaaaaaccccccccccaaaaaaaaa#bb", 
4002 "#aaaaaaaacccccaacccccaaaaaaaa#bb", 
4003 ".#aaaaaacccccaaaacccccaaaaaa#bbb", 
4004 ".#aaaaacccccaaaaaacccccaaaaa#bbb", 
4005 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.", 
4006 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.", 
4007 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.", 
4008 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..", 
4009 "....#aaaaaaaaaaaaaaaaaaaa#bbb...", 
4010 ".....##aaaaaaaaaaaaaaaa##bbbb...", 
4011 "......b#aaaaaaaaaaaaaa#bbbbb....", 
4012 ".......b###aaaaaaaa###bbbbb.....", 
4013 ".........bb########bbbbbb.......", 
4014 "..........bbbbbbbbbbbbbb........", 
4015 ".............bbbbbbbb..........."}; 
4017 static char *info_xpm
[]={ 
4025 "...........########.............", 
4026 "........###abbbbbba###..........", 
4027 "......##abbbbbbbbbbbba##........", 
4028 ".....#abbbbbbbbbbbbbbbba#.......", 
4029 "....#bbbbbbbaccccabbbbbbbd......", 
4030 "...#bbbbbbbbccccccbbbbbbbbd.....", 
4031 "..#bbbbbbbbbccccccbbbbbbbbbd....", 
4032 ".#abbbbbbbbbaccccabbbbbbbbbad...", 
4033 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..", 
4034 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.", 
4035 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.", 
4036 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", 
4037 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", 
4038 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", 
4039 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", 
4040 "#abbbbbbbbbbbcccccbbbbbbbbbbad##", 
4041 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###", 
4042 ".#abbbbbbbbbbcccccbbbbbbbbbad###", 
4043 "..#bbbbbbbbcccccccccbbbbbbbd###.", 
4044 "...dbbbbbbbbbbbbbbbbbbbbbbd####.", 
4045 "....dbbbbbbbbbbbbbbbbbbbbd####..", 
4046 ".....dabbbbbbbbbbbbbbbbad####...", 
4047 "......ddabbbbbbbbbbbbadd####....", 
4048 ".......#dddabbbbbbaddd#####.....", 
4049 "........###dddabbbd#######......", 
4050 "..........####dbbbd#####........", 
4051 ".............#dbbbd##...........", 
4052 "...............dbbd##...........", 
4053 "................dbd##...........", 
4054 ".................dd##...........", 
4055 "..................###...........", 
4056 "...................##..........."}; 
4058 static char *question_xpm
[]={ 
4066 "...........########.............", 
4067 "........###abbbbbba###..........", 
4068 "......##abbbbbbbbbbbba##........", 
4069 ".....#abbbbbbbbbbbbbbbba#.......", 
4070 "....#bbbbbbbbbbbbbbbbbbbbc......", 
4071 "...#bbbbbbbaddddddabbbbbbbc.....", 
4072 "..#bbbbbbbadabbddddabbbbbbbc....", 
4073 ".#abbbbbbbddbbbbddddbbbbbbbac...", 
4074 ".#bbbbbbbbddddbbddddbbbbbbbbc#..", 
4075 "#abbbbbbbbddddbaddddbbbbbbbbac#.", 
4076 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.", 
4077 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##", 
4078 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##", 
4079 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##", 
4080 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##", 
4081 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##", 
4082 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###", 
4083 ".#abbbbbbbbbbddddbbbbbbbbbbac###", 
4084 "..#bbbbbbbbbbddddbbbbbbbbbbc###.", 
4085 "...cbbbbbbbbbaddabbbbbbbbbc####.", 
4086 "....cbbbbbbbbbbbbbbbbbbbbc####..", 
4087 ".....cabbbbbbbbbbbbbbbbac####...", 
4088 "......ccabbbbbbbbbbbbacc####....", 
4089 ".......#cccabbbbbbaccc#####.....", 
4090 "........###cccabbbc#######......", 
4091 "..........####cbbbc#####........", 
4092 ".............#cbbbc##...........", 
4093 "...............cbbc##...........", 
4094 "................cbc##...........", 
4095 ".................cc##...........", 
4096 "..................###...........", 
4097 "...................##..........."}; 
4099 static char *warning_xpm
[]={ 
4107 ".............###................", 
4108 "............#aabc...............", 
4109 "...........#aaaabcd.............", 
4110 "...........#aaaaacdd............", 
4111 "..........#aaaaaabcdd...........", 
4112 "..........#aaaaaaacdd...........", 
4113 ".........#aaaaaaaabcdd..........", 
4114 ".........#aaaaaaaaacdd..........", 
4115 "........#aaaaaaaaaabcdd.........", 
4116 "........#aaabcccbaaacdd.........", 
4117 ".......#aaaacccccaaabcdd........", 
4118 ".......#aaaacccccaaaacdd........", 
4119 "......#aaaaacccccaaaabcdd.......", 
4120 "......#aaaaacccccaaaaacdd.......", 
4121 ".....#aaaaaacccccaaaaabcdd......", 
4122 ".....#aaaaaa#ccc#aaaaaacdd......", 
4123 "....#aaaaaaabcccbaaaaaabcdd.....", 
4124 "....#aaaaaaaacccaaaaaaaacdd.....", 
4125 "...#aaaaaaaaa#c#aaaaaaaabcdd....", 
4126 "...#aaaaaaaaabcbaaaaaaaaacdd....", 
4127 "..#aaaaaaaaaaacaaaaaaaaaabcdd...", 
4128 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...", 
4129 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..", 
4130 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..", 
4131 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.", 
4132 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.", 
4133 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd", 
4134 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd", 
4135 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd", 
4136 "..#ccccccccccccccccccccccccddddd", 
4137 "....ddddddddddddddddddddddddddd.", 
4138 ".....ddddddddddddddddddddddddd.."}; 
4140 wxBitmap 
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
, 
4141                                           const wxArtClient
& WXUNUSED(client
), 
4142                                           const wxSize
& WXUNUSED(size
)) 
4144     if ( id 
== wxART_INFORMATION 
) 
4145         return wxBitmap(info_xpm
); 
4146     if ( id 
== wxART_ERROR 
) 
4147         return wxBitmap(error_xpm
); 
4148     if ( id 
== wxART_WARNING 
) 
4149         return wxBitmap(warning_xpm
); 
4150     if ( id 
== wxART_QUESTION 
) 
4151         return wxBitmap(question_xpm
); 
4152     return wxNullBitmap
; 
4156 // ---------------------------------------------------------------------------- 
4157 // text control geometry 
4158 // ---------------------------------------------------------------------------- 
4160 static inline int GetTextBorderWidth() 
4166 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl 
* WXUNUSED(text
), 
4167                                   const wxRect
& rect
) const 
4169     wxRect rectTotal 
= rect
; 
4171     wxCoord widthBorder 
= GetTextBorderWidth(); 
4172     rectTotal
.Inflate(widthBorder
); 
4174     // this is what Windows does 
4181 wxWin32Renderer::GetTextClientArea(const wxTextCtrl 
* WXUNUSED(text
), 
4183                                    wxCoord 
*extraSpaceBeyond
) const 
4185     wxRect rectText 
= rect
; 
4187     // undo GetTextTotalArea() 
4188     if ( rectText
.height 
> 0 ) 
4191     wxCoord widthBorder 
= GetTextBorderWidth(); 
4192     rectText
.Inflate(-widthBorder
); 
4194     if ( extraSpaceBeyond 
) 
4195         *extraSpaceBeyond 
= 0; 
4200 // ---------------------------------------------------------------------------- 
4202 // ---------------------------------------------------------------------------- 
4204 void wxWin32Renderer::AdjustSize(wxSize 
*size
, const wxWindow 
*window
) 
4207     if ( wxDynamicCast(window
, wxScrollBar
) ) 
4209         // we only set the width of vert scrollbars and height of the 
4211         if ( window
->GetWindowStyle() & wxSB_HORIZONTAL 
) 
4212             size
->y 
= m_sizeScrollbarArrow
.y
; 
4214             size
->x 
= m_sizeScrollbarArrow
.x
; 
4216         // skip border width adjustments, they don't make sense for us 
4219 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR 
4222     if ( wxDynamicCast(window
, wxBitmapButton
) ) 
4226 #endif // wxUSE_BMPBUTTON 
4228     if ( wxDynamicCast(window
, wxButton
) ) 
4230         if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) ) 
4232             // TODO: don't harcode all this 
4233             size
->x 
+= 3*window
->GetCharWidth(); 
4235             wxCoord heightBtn 
= (11*(window
->GetCharHeight() + 8))/10; 
4236             if ( size
->y 
< heightBtn 
- 8 ) 
4237                 size
->y 
= heightBtn
; 
4242         // for compatibility with other ports, the buttons default size is never 
4243         // less than the standard one, but not when display not PDAs. 
4244         if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
) 
4246             if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) ) 
4248                 wxSize szDef 
= wxButton::GetDefaultSize(); 
4249                 if ( size
->x 
< szDef
.x 
) 
4254         // no border width adjustments for buttons 
4257 #endif // wxUSE_BUTTON 
4259     // take into account the border width 
4260     wxRect rectBorder 
= GetBorderDimensions(window
->GetBorder()); 
4261     size
->x 
+= rectBorder
.x 
+ rectBorder
.width
; 
4262     size
->y 
+= rectBorder
.y 
+ rectBorder
.height
; 
4265 // ============================================================================ 
4267 // ============================================================================ 
4269 // ---------------------------------------------------------------------------- 
4270 // wxWin32InputHandler 
4271 // ---------------------------------------------------------------------------- 
4273 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer 
*renderer
) 
4275     m_renderer 
= renderer
; 
4278 bool wxWin32InputHandler::HandleKey(wxInputConsumer 
* WXUNUSED(control
), 
4279                                     const wxKeyEvent
& WXUNUSED(event
), 
4280                                     bool WXUNUSED(pressed
)) 
4285 bool wxWin32InputHandler::HandleMouse(wxInputConsumer 
*control
, 
4286                                       const wxMouseEvent
& event
) 
4288     // clicking on the control gives it focus 
4289     if ( event
.ButtonDown() ) 
4291         wxWindow 
*win 
= control
->GetInputWindow(); 
4293         if (( wxWindow::FindFocus() != control
->GetInputWindow() ) && 
4294             ( win
->AcceptsFocus() ) ) 
4305 // ---------------------------------------------------------------------------- 
4306 // wxWin32ScrollBarInputHandler 
4307 // ---------------------------------------------------------------------------- 
4309 wxWin32ScrollBarInputHandler:: 
4310 wxWin32ScrollBarInputHandler(wxWin32Renderer 
*renderer
, 
4311                              wxInputHandler 
*handler
) 
4312         : wxStdScrollBarInputHandler(renderer
, handler
) 
4314     m_scrollPaused 
= false; 
4318 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar 
*scrollbar
, 
4319                                                  const wxControlAction
& action
) 
4321     // stop if went beyond the position of the original click (this can only 
4322     // happen when we scroll by pages) 
4324     if ( action 
== wxACTION_SCROLL_PAGE_DOWN 
) 
4326         stop 
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
) 
4327                 != wxHT_SCROLLBAR_BAR_2
; 
4329     else if ( action 
== wxACTION_SCROLL_PAGE_UP 
) 
4331         stop 
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
) 
4332                 != wxHT_SCROLLBAR_BAR_1
; 
4337         StopScrolling(scrollbar
); 
4339         scrollbar
->Refresh(); 
4344     return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
); 
4347 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer 
*control
, 
4348                                                const wxMouseEvent
& event
) 
4350     // remember the current state 
4351     bool wasDraggingThumb 
= m_htLast 
== wxHT_SCROLLBAR_THUMB
; 
4353     // do process the message 
4354     bool rc 
= wxStdScrollBarInputHandler::HandleMouse(control
, event
); 
4356     // analyse the changes 
4357     if ( !wasDraggingThumb 
&& (m_htLast 
== wxHT_SCROLLBAR_THUMB
) ) 
4359         // we just started dragging the thumb, remember its initial position to 
4360         // be able to restore it if the drag is cancelled later 
4361         m_eventStartDrag 
= event
; 
4367 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer 
*control
, 
4368                                                    const wxMouseEvent
& event
) 
4370     // we don't highlight scrollbar elements, so there is no need to process 
4371     // mouse move events normally - only do it while mouse is captured (i.e. 
4372     // when we're dragging the thumb or pressing on something) 
4373     if ( !m_winCapture 
) 
4376     if ( event
.Entering() ) 
4378         // we're not interested in this at all 
4382     wxScrollBar 
*scrollbar 
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
); 
4384     if ( m_scrollPaused 
) 
4386         // check if the mouse returned to its original location 
4388         if ( event
.Leaving() ) 
4394         ht 
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition()); 
4395         if ( ht 
== m_htLast 
) 
4397             // yes it did, resume scrolling 
4398             m_scrollPaused 
= false; 
4399             if ( m_timerScroll 
) 
4401                 // we were scrolling by line/page, restart timer 
4402                 m_timerScroll
->Start(m_interval
); 
4404                 Press(scrollbar
, true); 
4406             else // we were dragging the thumb 
4408                 // restore its last location 
4409                 HandleThumbMove(scrollbar
, m_eventLastDrag
); 
4415     else // normal case, scrolling hasn't been paused 
4417         // if we're scrolling the scrollbar because the arrow or the shaft was 
4418         // pressed, check that the mouse stays on the same scrollbar element 
4421         // Always let thumb jump back if we leave the scrollbar 
4422         if ( event
.Moving() ) 
4424             ht 
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition()); 
4426         else // event.Leaving() 
4431         // Jump back only if we get far away from it 
4432         wxPoint pos 
= event
.GetPosition(); 
4433         if (scrollbar
->HasFlag( wxVERTICAL 
)) 
4435             if (pos
.x 
> -40 && pos
.x 
< scrollbar
->GetSize().x
+40) 
4440             if (pos
.y 
> -40 && pos
.y 
< scrollbar
->GetSize().y
+40) 
4443         ht 
= m_renderer
->HitTestScrollbar(scrollbar
, pos 
); 
4446         // if we're dragging the thumb and the mouse stays in the scrollbar, it 
4447         // is still ok - we only want to catch the case when the mouse leaves 
4448         // the scrollbar here 
4449         if ( m_htLast 
== wxHT_SCROLLBAR_THUMB 
&& ht 
!= wxHT_NOWHERE 
) 
4451             ht 
= wxHT_SCROLLBAR_THUMB
; 
4454         if ( ht 
!= m_htLast 
) 
4456             // what were we doing? 2 possibilities: either an arrow/shaft was 
4457             // pressed in which case we have a timer and so we just stop it or 
4458             // we were dragging the thumb 
4459             if ( m_timerScroll 
) 
4462                 m_interval 
= m_timerScroll
->GetInterval(); 
4463                 m_timerScroll
->Stop(); 
4464                 m_scrollPaused 
= true; 
4466                 // unpress the arrow 
4467                 Press(scrollbar
, false); 
4469             else // we were dragging the thumb 
4471                 // remember the current thumb position to be able to restore it 
4472                 // if the mouse returns to it later 
4473                 m_eventLastDrag 
= event
; 
4475                 // and restore the original position (before dragging) of the 
4477                 HandleThumbMove(scrollbar
, m_eventStartDrag
); 
4484     return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
); 
4487 // ---------------------------------------------------------------------------- 
4488 // wxWin32CheckboxInputHandler 
4489 // ---------------------------------------------------------------------------- 
4491 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer 
*control
, 
4492                                             const wxKeyEvent
& event
, 
4497         wxControlAction action
; 
4498         int keycode 
= event
.GetKeyCode(); 
4502                 action 
= wxACTION_CHECKBOX_TOGGLE
; 
4506             case WXK_NUMPAD_SUBTRACT
: 
4507                 action 
= wxACTION_CHECKBOX_CHECK
; 
4511             case WXK_NUMPAD_ADD
: 
4512             case WXK_NUMPAD_EQUAL
: 
4513                 action 
= wxACTION_CHECKBOX_CLEAR
; 
4517         if ( !action
.IsEmpty() ) 
4519             control
->PerformAction(action
); 
4528 // ---------------------------------------------------------------------------- 
4529 // wxWin32TextCtrlInputHandler 
4530 // ---------------------------------------------------------------------------- 
4532 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer 
*control
, 
4533                                             const wxKeyEvent
& event
, 
4536     // handle only MSW-specific text bindings here, the others are handled in 
4540         int keycode 
= event
.GetKeyCode(); 
4542         wxControlAction action
; 
4543         if ( keycode 
== WXK_DELETE 
&& event
.ShiftDown() ) 
4545             action 
= wxACTION_TEXT_CUT
; 
4547         else if ( keycode 
== WXK_INSERT 
) 
4549             if ( event
.ControlDown() ) 
4550                 action 
= wxACTION_TEXT_COPY
; 
4551             else if ( event
.ShiftDown() ) 
4552                 action 
= wxACTION_TEXT_PASTE
; 
4555         if ( action 
!= wxACTION_NONE 
) 
4557             control
->PerformAction(action
); 
4563     return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
); 
4566 // ---------------------------------------------------------------------------- 
4567 // wxWin32StatusBarInputHandler 
4568 // ---------------------------------------------------------------------------- 
4570 wxWin32StatusBarInputHandler:: 
4571 wxWin32StatusBarInputHandler(wxInputHandler 
*handler
) 
4572     : wxStdInputHandler(handler
) 
4577 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow 
*statbar
, 
4578                                             const wxPoint
& pt
) const 
4580     if ( statbar
->HasFlag(wxST_SIZEGRIP
) && 
4581          statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) ) 
4584             parentTLW 
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
); 
4586         wxCHECK_MSG( parentTLW
, false, 
4587                      _T("the status bar should be a child of a TLW") ); 
4589         // a maximized window can't be resized anyhow 
4590         if ( !parentTLW
->IsMaximized() ) 
4592             // VZ: I think that the standard Windows behaviour is to only 
4593             //     show the resizing cursor when the mouse is on top of the 
4594             //     grip itself but apparently different Windows versions behave 
4595             //     differently (?) and it seems a better UI to allow resizing 
4596             //     the status bar even when the mouse is above the grip 
4597             wxSize sizeSbar 
= statbar
->GetSize(); 
4599             int diff 
= sizeSbar
.x 
- pt
.x
; 
4600             return diff 
>= 0 && diff 
< (wxCoord
)STATUSBAR_GRIP_SIZE
; 
4607 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer 
*consumer
, 
4608                                                const wxMouseEvent
& event
) 
4610     if ( event
.Button(1) ) 
4612         if ( event
.ButtonDown(1) ) 
4614             wxWindow 
*statbar 
= consumer
->GetInputWindow(); 
4616             if ( IsOnGrip(statbar
, event
.GetPosition()) ) 
4618                 wxTopLevelWindow 
*tlw 
= wxDynamicCast(statbar
->GetParent(), 
4622                     tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, 
4623                                        wxHT_TOPLEVEL_BORDER_SE
); 
4625                     statbar
->SetCursor(m_cursorOld
); 
4633     return wxStdInputHandler::HandleMouse(consumer
, event
); 
4636 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer 
*consumer
, 
4637                                                    const wxMouseEvent
& event
) 
4639     wxWindow 
*statbar 
= consumer
->GetInputWindow(); 
4641     bool isOnGrip 
= IsOnGrip(statbar
, event
.GetPosition()); 
4642     if ( isOnGrip 
!= m_isOnGrip 
) 
4644         m_isOnGrip 
= isOnGrip
; 
4647             m_cursorOld 
= statbar
->GetCursor(); 
4648             statbar
->SetCursor(wxCURSOR_SIZENWSE
); 
4652             statbar
->SetCursor(m_cursorOld
); 
4656     return wxStdInputHandler::HandleMouseMove(consumer
, event
); 
4659 // ---------------------------------------------------------------------------- 
4660 // wxWin32FrameInputHandler 
4661 // ---------------------------------------------------------------------------- 
4663 class wxWin32SystemMenuEvtHandler 
: public wxEvtHandler
 
4666     wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler 
*handler
); 
4668     void Attach(wxInputConsumer 
*consumer
); 
4672     DECLARE_EVENT_TABLE() 
4673     void OnSystemMenu(wxCommandEvent 
&event
); 
4674     void OnCloseFrame(wxCommandEvent 
&event
); 
4675     void OnClose(wxCloseEvent 
&event
); 
4677     wxWin32FrameInputHandler 
*m_inputHnd
; 
4678     wxTopLevelWindow         
*m_wnd
; 
4680     wxAcceleratorTable        m_oldAccelTable
; 
4684 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler( 
4685                                 wxWin32FrameInputHandler 
*handler
) 
4687     m_inputHnd 
= handler
; 
4691 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer 
*consumer
) 
4693     wxASSERT_MSG( m_wnd 
== NULL
, _T("can't attach the handler twice!") ); 
4695     m_wnd 
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
); 
4696     m_wnd
->PushEventHandler(this); 
4699     // VS: This code relies on using generic implementation of 
4700     //     wxAcceleratorTable in wxUniv! 
4701     wxAcceleratorTable table 
= *m_wnd
->GetAcceleratorTable(); 
4702     m_oldAccelTable 
= table
; 
4703     table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
)); 
4704     table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
)); 
4705     m_wnd
->SetAcceleratorTable(table
); 
4709 void wxWin32SystemMenuEvtHandler::Detach() 
4714         m_wnd
->SetAcceleratorTable(m_oldAccelTable
); 
4716         m_wnd
->RemoveEventHandler(this); 
4721 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
) 
4722     EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
) 
4723     EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
) 
4724     EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
) 
4727 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent 
&WXUNUSED(event
)) 
4729     int border 
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) && 
4730                   !m_wnd
->IsMaximized()) ? 
4731                       RESIZEABLE_FRAME_BORDER_THICKNESS 
: 
4732                       FRAME_BORDER_THICKNESS
; 
4733     wxPoint pt 
= m_wnd
->GetClientAreaOrigin(); 
4734     pt
.x 
= -pt
.x 
+ border
; 
4735     pt
.y 
= -pt
.y 
+ border 
+ FRAME_TITLEBAR_HEIGHT
; 
4738     wxAcceleratorTable table 
= *m_wnd
->GetAcceleratorTable(); 
4739     m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
); 
4742     m_inputHnd
->PopupSystemMenu(m_wnd
, pt
); 
4745     m_wnd
->SetAcceleratorTable(table
); 
4749 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent 
&WXUNUSED(event
)) 
4751     m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, 
4752                          wxTOPLEVEL_BUTTON_CLOSE
); 
4755 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent 
&event
) 
4762 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler 
*handler
) 
4763         : wxStdFrameInputHandler(handler
) 
4765     m_menuHandler 
= new wxWin32SystemMenuEvtHandler(this); 
4768 wxWin32FrameInputHandler::~wxWin32FrameInputHandler() 
4770     if ( m_menuHandler 
) 
4772         m_menuHandler
->Detach(); 
4773         delete m_menuHandler
; 
4777 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer 
*consumer
, 
4778                                            const wxMouseEvent
& event
) 
4780     if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() ) 
4782         wxTopLevelWindow 
*tlw 
= 
4783             wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
); 
4785         long hit 
= tlw
->HitTest(event
.GetPosition()); 
4787         if ( event
.LeftDClick() && hit 
== wxHT_TOPLEVEL_TITLEBAR 
) 
4789             tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, 
4790                                tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
 
4791                                                   : wxTOPLEVEL_BUTTON_MAXIMIZE
); 
4794         else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU 
) 
4796             if ( (event
.LeftDown() && hit 
== wxHT_TOPLEVEL_ICON
) || 
4797                  (event
.RightDown() && 
4798                       (hit 
== wxHT_TOPLEVEL_TITLEBAR 
|| 
4799                        hit 
== wxHT_TOPLEVEL_ICON
)) ) 
4801                 PopupSystemMenu(tlw
, event
.GetPosition()); 
4807     return wxStdFrameInputHandler::HandleMouse(consumer
, event
); 
4810 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow 
*window
, 
4811                                                const wxPoint
& pos
) const 
4813     wxMenu 
*menu 
= new wxMenu
; 
4815     if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX 
) 
4816         menu
->Append(wxID_RESTORE_FRAME 
, _("&Restore")); 
4817     menu
->Append(wxID_MOVE_FRAME 
, _("&Move")); 
4818     if ( window
->GetWindowStyle() & wxRESIZE_BORDER 
) 
4819         menu
->Append(wxID_RESIZE_FRAME 
, _("&Size")); 
4820     if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) ) 
4821         menu
->Append(wxID_ICONIZE_FRAME 
, _("Mi&nimize")); 
4822     if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX 
) 
4823         menu
->Append(wxID_MAXIMIZE_FRAME 
, _("Ma&ximize")); 
4824     menu
->AppendSeparator(); 
4825     menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4")); 
4827     if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX 
) 
4829         if ( window
->IsMaximized() ) 
4831             menu
->Enable(wxID_MAXIMIZE_FRAME
, false); 
4832             menu
->Enable(wxID_MOVE_FRAME
, false); 
4833             if ( window
->GetWindowStyle() & wxRESIZE_BORDER 
) 
4834                 menu
->Enable(wxID_RESIZE_FRAME
, false); 
4837             menu
->Enable(wxID_RESTORE_FRAME
, false); 
4840     window
->PopupMenu(menu
, pos
); 
4844 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer 
*consumer
, 
4847     if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU 
) 
4849         // always detach if active frame changed: 
4850         m_menuHandler
->Detach(); 
4854             m_menuHandler
->Attach(consumer
); 
4858     return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);