1 // Name:        univ/themes/win32.cpp 
   2 // Purpose:     wxUniversal theme implementing Win32-like LNF 
   3 // Author:      Vadim Zeitlin 
   7 // Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com) 
   8 // Licence:     wxWindows licence 
   9 /////////////////////////////////////////////////////////////////////////////// 
  11 // =========================================================================== 
  13 // =========================================================================== 
  15 // --------------------------------------------------------------------------- 
  17 // --------------------------------------------------------------------------- 
  19 // For compilers that support precompilation, includes "wx.h". 
  20 #include "wx/wxprec.h" 
  30     #include "wx/window.h" 
  32     #include "wx/dcmemory.h" 
  34     #include "wx/button.h" 
  35     #include "wx/listbox.h" 
  36     #include "wx/checklst.h" 
  37     #include "wx/combobox.h" 
  38     #include "wx/scrolbar.h" 
  39     #include "wx/slider.h" 
  40     #include "wx/textctrl.h" 
  41     #include "wx/toolbar.h" 
  44         // for COLOR_* constants 
  45         #include "wx/msw/private.h" 
  49 #include "wx/notebook.h" 
  50 #include "wx/spinbutt.h" 
  51 #include "wx/settings.h" 
  53 #include "wx/artprov.h" 
  54 #include "wx/toplevel.h" 
  56 #include "wx/univ/scrtimer.h" 
  57 #include "wx/univ/renderer.h" 
  58 #include "wx/univ/inphand.h" 
  59 #include "wx/univ/colschem.h" 
  60 #include "wx/univ/theme.h" 
  62 // ---------------------------------------------------------------------------- 
  64 // ---------------------------------------------------------------------------- 
  66 static const int BORDER_THICKNESS 
= 2; 
  68 // the offset between the label and focus rect around it 
  69 static const int FOCUS_RECT_OFFSET_X 
= 1; 
  70 static const int FOCUS_RECT_OFFSET_Y 
= 1; 
  72 static const int FRAME_BORDER_THICKNESS            
= 3; 
  73 static const int RESIZEABLE_FRAME_BORDER_THICKNESS 
= 4; 
  74 static const int FRAME_TITLEBAR_HEIGHT             
= 18; 
  75 static const int FRAME_BUTTON_WIDTH                
= 16; 
  76 static const int FRAME_BUTTON_HEIGHT               
= 14; 
  78 static const size_t NUM_STATUSBAR_GRIP_BANDS 
= 3; 
  79 static const size_t WIDTH_STATUSBAR_GRIP_BAND 
= 4; 
  80 static const size_t STATUSBAR_GRIP_SIZE 
= 
  81     WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
; 
  83 static const wxCoord SLIDER_MARGIN 
= 6; // margin around slider 
  84 static const wxCoord SLIDER_THUMB_LENGTH 
= 18; 
  85 static const wxCoord SLIDER_TICK_LENGTH 
= 6; 
  97     IndicatorState_Normal
, 
  98     IndicatorState_Pressed
, // this one is for check/radioboxes 
  99     IndicatorState_Selected 
= IndicatorState_Pressed
, // for menus 
 100     IndicatorState_Disabled
, 
 101     IndicatorState_SelectedDisabled
,    // only for the menus 
 107     IndicatorStatus_Checked
, 
 108     IndicatorStatus_Unchecked
, 
 112 // wxWin32Renderer: draw the GUI elements in Win32 style 
 113 // ---------------------------------------------------------------------------- 
 115 class wxWin32Renderer 
: public wxRenderer
 
 119     enum wxArrowDirection
 
 134         Arrow_InversedDisabled
, 
 138     enum wxFrameButtonType
 
 141         FrameButton_Minimize
, 
 142         FrameButton_Maximize
, 
 149     wxWin32Renderer(const wxColourScheme 
*scheme
); 
 151     // implement the base class pure virtuals 
 152     virtual void DrawBackground(wxDC
& dc
, 
 156                                 wxWindow 
*window 
= NULL
); 
 157     virtual void DrawLabel(wxDC
& dc
, 
 158                            const wxString
& label
, 
 161                            int alignment 
= wxALIGN_LEFT 
| wxALIGN_TOP
, 
 163                            wxRect 
*rectBounds 
= NULL
); 
 164     virtual void DrawButtonLabel(wxDC
& dc
, 
 165                                  const wxString
& label
, 
 166                                  const wxBitmap
& image
, 
 169                                  int alignment 
= wxALIGN_LEFT 
| wxALIGN_TOP
, 
 171                                  wxRect 
*rectBounds 
= NULL
); 
 172     virtual void DrawBorder(wxDC
& dc
, 
 176                             wxRect 
*rectIn 
= (wxRect 
*)NULL
); 
 177     virtual void DrawHorizontalLine(wxDC
& dc
, 
 178                                     wxCoord y
, wxCoord x1
, wxCoord x2
); 
 179     virtual void DrawVerticalLine(wxDC
& dc
, 
 180                                   wxCoord x
, wxCoord y1
, wxCoord y2
); 
 181     virtual void DrawFrame(wxDC
& dc
, 
 182                            const wxString
& label
, 
 185                            int alignment 
= wxALIGN_LEFT
, 
 186                            int indexAccel 
= -1); 
 187     virtual void DrawTextBorder(wxDC
& dc
, 
 191                                 wxRect 
*rectIn 
= (wxRect 
*)NULL
); 
 192     virtual void DrawButtonBorder(wxDC
& dc
, 
 195                                   wxRect 
*rectIn 
= (wxRect 
*)NULL
); 
 196     virtual void DrawArrow(wxDC
& dc
, 
 200     virtual void DrawScrollbarArrow(wxDC
& dc
, 
 204         { DrawArrow(dc
, dir
, rect
, flags
); } 
 205     virtual void DrawScrollbarThumb(wxDC
& dc
, 
 206                                     wxOrientation orient
, 
 209     virtual void DrawScrollbarShaft(wxDC
& dc
, 
 210                                     wxOrientation orient
, 
 213     virtual void DrawScrollCorner(wxDC
& dc
, 
 215     virtual void DrawItem(wxDC
& dc
, 
 216                           const wxString
& label
, 
 219     virtual void DrawCheckItem(wxDC
& dc
, 
 220                                const wxString
& label
, 
 221                                const wxBitmap
& bitmap
, 
 224     virtual void DrawCheckButton(wxDC
& dc
, 
 225                                  const wxString
& label
, 
 226                                  const wxBitmap
& bitmap
, 
 229                                  wxAlignment align 
= wxALIGN_LEFT
, 
 230                                  int indexAccel 
= -1); 
 231     virtual void DrawRadioButton(wxDC
& dc
, 
 232                                  const wxString
& label
, 
 233                                  const wxBitmap
& bitmap
, 
 236                                  wxAlignment align 
= wxALIGN_LEFT
, 
 237                                  int indexAccel 
= -1); 
 238     virtual void DrawToolBarButton(wxDC
& dc
, 
 239                                    const wxString
& label
, 
 240                                    const wxBitmap
& bitmap
, 
 244     virtual void DrawTextLine(wxDC
& dc
, 
 245                               const wxString
& text
, 
 250     virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
); 
 251     virtual void DrawTab(wxDC
& dc
, 
 254                          const wxString
& label
, 
 255                          const wxBitmap
& bitmap 
= wxNullBitmap
, 
 257                          int indexAccel 
= -1); 
 259     virtual void DrawSliderShaft(wxDC
& dc
, 
 262                                  wxOrientation orient
, 
 265                                  wxRect 
*rectShaft 
= NULL
); 
 266     virtual void DrawSliderThumb(wxDC
& dc
, 
 268                                  wxOrientation orient
, 
 271     virtual void DrawSliderTicks(wxDC
& dc
, 
 274                                  wxOrientation orient
, 
 281     virtual void DrawMenuBarItem(wxDC
& dc
, 
 283                                  const wxString
& label
, 
 285                                  int indexAccel 
= -1); 
 286     virtual void DrawMenuItem(wxDC
& dc
, 
 288                               const wxMenuGeometryInfo
& geometryInfo
, 
 289                               const wxString
& label
, 
 290                               const wxString
& accel
, 
 291                               const wxBitmap
& bitmap 
= wxNullBitmap
, 
 293                               int indexAccel 
= -1); 
 294     virtual void DrawMenuSeparator(wxDC
& dc
, 
 296                                    const wxMenuGeometryInfo
& geomInfo
); 
 298     virtual void DrawStatusField(wxDC
& dc
, 
 300                                  const wxString
& label
, 
 304     virtual void DrawFrameTitleBar(wxDC
& dc
, 
 306                                    const wxString
& title
, 
 309                                    int specialButton 
= 0, 
 310                                    int specialButtonFlags 
= 0); 
 311     virtual void DrawFrameBorder(wxDC
& dc
, 
 314     virtual void DrawFrameBackground(wxDC
& dc
, 
 317     virtual void DrawFrameTitle(wxDC
& dc
, 
 319                                 const wxString
& title
, 
 321     virtual void DrawFrameIcon(wxDC
& dc
, 
 325     virtual void DrawFrameButton(wxDC
& dc
, 
 326                                  wxCoord x
, wxCoord y
, 
 329     virtual wxRect 
GetFrameClientArea(const wxRect
& rect
, int flags
) const; 
 330     virtual wxSize 
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const; 
 331     virtual wxSize 
GetFrameMinSize(int flags
) const; 
 332     virtual wxSize 
GetFrameIconSize() const; 
 333     virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const; 
 335     virtual void GetComboBitmaps(wxBitmap 
*bmpNormal
, 
 337                                  wxBitmap 
*bmpPressed
, 
 338                                  wxBitmap 
*bmpDisabled
); 
 340     virtual void AdjustSize(wxSize 
*size
, const wxWindow 
*window
); 
 341     virtual wxRect 
GetBorderDimensions(wxBorder border
) const; 
 342     virtual bool AreScrollbarsInsideBorder() const; 
 344     virtual wxSize 
GetScrollbarArrowSize() const 
 345         { return m_sizeScrollbarArrow
; } 
 346     virtual wxRect 
GetScrollbarRect(const wxScrollBar 
*scrollbar
, 
 347                                     wxScrollBar::Element elem
, 
 348                                     int thumbPos 
= -1) const; 
 349     virtual wxCoord 
GetScrollbarSize(const wxScrollBar 
*scrollbar
); 
 350     virtual wxHitTest 
HitTestScrollbar(const wxScrollBar 
*scrollbar
, 
 351                                        const wxPoint
& pt
) const; 
 352     virtual wxCoord 
ScrollbarToPixel(const wxScrollBar 
*scrollbar
, 
 354     virtual int PixelToScrollbar(const wxScrollBar 
*scrollbar
, wxCoord coord
); 
 355     virtual wxCoord 
GetListboxItemHeight(wxCoord fontHeight
) 
 356         { return fontHeight 
+ 2; } 
 357     virtual wxSize 
GetCheckBitmapSize() const 
 358         { return wxSize(13, 13); } 
 359     virtual wxSize 
GetRadioBitmapSize() const 
 360         { return wxSize(12, 12); } 
 361     virtual wxCoord 
GetCheckItemMargin() const 
 364     virtual wxSize 
GetToolBarButtonSize(wxCoord 
*separator
) const 
 365         { if ( separator 
) *separator 
= 5; return wxSize(16, 15); } 
 366     virtual wxSize 
GetToolBarMargin() const 
 367         { return wxSize(4, 4); } 
 369     virtual wxRect 
GetTextTotalArea(const wxTextCtrl 
*text
, 
 370                                     const wxRect
& rect
) const; 
 371     virtual wxRect 
GetTextClientArea(const wxTextCtrl 
*text
, 
 373                                      wxCoord 
*extraSpaceBeyond
) const; 
 375     virtual wxSize 
GetTabIndent() const { return wxSize(2, 2); } 
 376     virtual wxSize 
GetTabPadding() const { return wxSize(6, 5); } 
 378     virtual wxCoord 
GetSliderDim() const { return SLIDER_THUMB_LENGTH 
+ 2*BORDER_THICKNESS
; } 
 379     virtual wxCoord 
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; } 
 380     virtual wxRect 
GetSliderShaftRect(const wxRect
& rect
, 
 382                                       wxOrientation orient
, 
 383                                       long style 
= 0) const; 
 384     virtual wxSize 
GetSliderThumbSize(const wxRect
& rect
, 
 386                                       wxOrientation orient
) const; 
 387     virtual wxSize 
GetProgressBarStep() const { return wxSize(16, 32); } 
 389     virtual wxSize 
GetMenuBarItemSize(const wxSize
& sizeText
) const; 
 390     virtual wxMenuGeometryInfo 
*GetMenuGeometry(wxWindow 
*win
, 
 391                                                 const wxMenu
& menu
) const; 
 393     virtual wxSize 
GetStatusBarBorders(wxCoord 
*borderBetweenFields
) const; 
 396     // helper of DrawLabel() and DrawCheckOrRadioButton() 
 397     void DoDrawLabel(wxDC
& dc
, 
 398                      const wxString
& label
, 
 401                      int alignment 
= wxALIGN_LEFT 
| wxALIGN_TOP
, 
 403                      wxRect 
*rectBounds 
= NULL
, 
 404                      const wxPoint
& focusOffset
 
 405                         = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
)); 
 407     // common part of DrawLabel() and DrawItem() 
 408     void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
); 
 410     // DrawLabel() and DrawButtonLabel() helper 
 411     void DrawLabelShadow(wxDC
& dc
, 
 412                          const wxString
& label
, 
 417     // DrawButtonBorder() helper 
 418     void DoDrawBackground(wxDC
& dc
, 
 421                           wxWindow 
*window 
= NULL 
); 
 423     // DrawBorder() helpers: all of them shift and clip the DC after drawing 
 426     // just draw a rectangle with the given pen 
 427     void DrawRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
); 
 429     // draw the lower left part of rectangle 
 430     void DrawHalfRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
); 
 432     // draw the rectange using the first brush for the left and top sides and 
 433     // the second one for the bottom and right ones 
 434     void DrawShadedRect(wxDC
& dc
, wxRect 
*rect
, 
 435                         const wxPen
& pen1
, const wxPen
& pen2
); 
 437     // draw the normal 3D border 
 438     void DrawRaisedBorder(wxDC
& dc
, wxRect 
*rect
); 
 440     // draw the sunken 3D border 
 441     void DrawSunkenBorder(wxDC
& dc
, wxRect 
*rect
); 
 443     // draw the border used for scrollbar arrows 
 444     void DrawArrowBorder(wxDC
& dc
, wxRect 
*rect
, bool isPressed 
= FALSE
); 
 446     // public DrawArrow()s helper 
 447     void DrawArrow(wxDC
& dc
, const wxRect
& rect
, 
 448                    wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
); 
 450     // DrawArrowButton is used by DrawScrollbar and DrawComboButton 
 451     void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
, 
 452                          wxArrowDirection arrowDir
, 
 453                          wxArrowStyle arrowStyle
); 
 455     // DrawCheckButton/DrawRadioButton helper 
 456     void DrawCheckOrRadioButton(wxDC
& dc
, 
 457                                 const wxString
& label
, 
 458                                 const wxBitmap
& bitmap
, 
 463                                 wxCoord focusOffsetY
); 
 465     // draw a normal or transposed line (useful for using the same code fo both 
 466     // horizontal and vertical widgets) 
 467     void DrawLine(wxDC
& dc
, 
 468                   wxCoord x1
, wxCoord y1
, 
 469                   wxCoord x2
, wxCoord y2
, 
 470                   bool transpose 
= FALSE
) 
 473             dc
.DrawLine(y1
, x1
, y2
, x2
); 
 475             dc
.DrawLine(x1
, y1
, x2
, y2
); 
 478     // get the standard check/radio button bitmap 
 479     wxBitmap 
GetIndicator(IndicatorType indType
, int flags
); 
 480     wxBitmap 
GetCheckBitmap(int flags
) 
 481         { return GetIndicator(IndicatorType_Check
, flags
); } 
 482     wxBitmap 
GetRadioBitmap(int flags
) 
 483         { return GetIndicator(IndicatorType_Radio
, flags
); } 
 486     const wxColourScheme 
*m_scheme
; 
 488     // the sizing parameters (TODO make them changeable) 
 489     wxSize m_sizeScrollbarArrow
; 
 491     // GDI objects we use for drawing 
 492     wxColour m_colDarkGrey
, 
 500     wxFont m_titlebarFont
; 
 502     // the checked and unchecked bitmaps for DrawCheckItem() 
 503     wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
]; 
 505     // the bitmaps returned by GetIndicator() 
 506     wxBitmap m_bmpIndicators
[IndicatorType_Max
] 
 508                             [IndicatorStatus_Max
]; 
 511     wxBitmap m_bmpFrameButtons
[FrameButton_Max
]; 
 513     // first row is for the normal state, second - for the disabled 
 514     wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
]; 
 517 // ---------------------------------------------------------------------------- 
 518 // wxWin32InputHandler and derived classes: process the keyboard and mouse 
 519 // messages according to Windows standards 
 520 // ---------------------------------------------------------------------------- 
 522 class wxWin32InputHandler 
: public wxInputHandler
 
 525     wxWin32InputHandler(wxWin32Renderer 
*renderer
); 
 527     virtual bool HandleKey(wxInputConsumer 
*control
, 
 528                            const wxKeyEvent
& event
, 
 530     virtual bool HandleMouse(wxInputConsumer 
*control
, 
 531                              const wxMouseEvent
& event
); 
 534     wxWin32Renderer 
*m_renderer
; 
 537 class wxWin32ScrollBarInputHandler 
: public wxStdScrollBarInputHandler
 
 540     wxWin32ScrollBarInputHandler(wxWin32Renderer 
*renderer
, 
 541                                  wxInputHandler 
*handler
); 
 543     virtual bool HandleMouse(wxInputConsumer 
*control
, const wxMouseEvent
& event
); 
 544     virtual bool HandleMouseMove(wxInputConsumer 
*control
, const wxMouseEvent
& event
); 
 546     virtual bool OnScrollTimer(wxScrollBar 
*scrollbar
, 
 547                                const wxControlAction
& action
); 
 550     virtual bool IsAllowedButton(int button
) { return button 
== 1; } 
 552     virtual void Highlight(wxScrollBar 
*scrollbar
, bool doIt
) 
 554         // we don't highlight anything 
 557     // the first and last event which caused the thumb to move 
 558     wxMouseEvent m_eventStartDrag
, 
 561     // have we paused the scrolling because the mouse moved? 
 564     // we remember the interval of the timer to be able to restart it 
 568 class wxWin32CheckboxInputHandler 
: public wxStdCheckboxInputHandler
 
 571     wxWin32CheckboxInputHandler(wxInputHandler 
*handler
) 
 572         : wxStdCheckboxInputHandler(handler
) { } 
 574     virtual bool HandleKey(wxInputConsumer 
*control
, 
 575                            const wxKeyEvent
& event
, 
 579 class wxWin32TextCtrlInputHandler 
: public wxStdTextCtrlInputHandler
 
 582     wxWin32TextCtrlInputHandler(wxInputHandler 
*handler
) 
 583         : wxStdTextCtrlInputHandler(handler
) { } 
 585     virtual bool HandleKey(wxInputConsumer 
*control
, 
 586                            const wxKeyEvent
& event
, 
 590 class wxWin32StatusBarInputHandler 
: public wxStdInputHandler
 
 593     wxWin32StatusBarInputHandler(wxInputHandler 
*handler
); 
 595     virtual bool HandleMouse(wxInputConsumer 
*consumer
, 
 596                              const wxMouseEvent
& event
); 
 598     virtual bool HandleMouseMove(wxInputConsumer 
*consumer
, 
 599                                  const wxMouseEvent
& event
); 
 602     // is the given point over the statusbar grip? 
 603     bool IsOnGrip(wxWindow 
*statbar
, const wxPoint
& pt
) const; 
 606     // the cursor we had replaced with the resize one 
 607     wxCursor m_cursorOld
; 
 609     // was the mouse over the grip last time we checked? 
 613 class wxWin32SystemMenuEvtHandler
; 
 615 class wxWin32FrameInputHandler 
: public wxStdFrameInputHandler
 
 618     wxWin32FrameInputHandler(wxInputHandler 
*handler
); 
 619     ~wxWin32FrameInputHandler(); 
 621     virtual bool HandleMouse(wxInputConsumer 
*control
, 
 622                              const wxMouseEvent
& event
); 
 624     virtual bool HandleActivation(wxInputConsumer 
*consumer
, bool activated
); 
 626     void PopupSystemMenu(wxTopLevelWindow 
*window
, const wxPoint
& pos
) const; 
 629     // was the mouse over the grip last time we checked? 
 630     wxWin32SystemMenuEvtHandler 
*m_menuHandler
; 
 633 // ---------------------------------------------------------------------------- 
 634 // wxWin32ColourScheme: uses (default) Win32 colours 
 635 // ---------------------------------------------------------------------------- 
 637 class wxWin32ColourScheme 
: public wxColourScheme
 
 640     virtual wxColour 
Get(StdColour col
) const; 
 641     virtual wxColour 
GetBackground(wxWindow 
*win
) const; 
 644 // ---------------------------------------------------------------------------- 
 645 // wxWin32ArtProvider 
 646 // ---------------------------------------------------------------------------- 
 648 class wxWin32ArtProvider 
: public wxArtProvider
 
 651     virtual wxBitmap 
CreateBitmap(const wxArtID
& id
, 
 652                                   const wxArtClient
& client
, 
 656 // ---------------------------------------------------------------------------- 
 658 // ---------------------------------------------------------------------------- 
 660 WX_DEFINE_ARRAY(wxInputHandler 
*, wxArrayHandlers
); 
 662 class wxWin32Theme 
: public wxTheme
 
 666     virtual ~wxWin32Theme(); 
 668     virtual wxRenderer 
*GetRenderer(); 
 669     virtual wxArtProvider 
*GetArtProvider(); 
 670     virtual wxInputHandler 
*GetInputHandler(const wxString
& control
); 
 671     virtual wxColourScheme 
*GetColourScheme(); 
 674     // get the default input handler 
 675     wxInputHandler 
*GetDefaultInputHandler(); 
 677     wxWin32Renderer 
*m_renderer
; 
 679     wxWin32ArtProvider 
*m_artProvider
; 
 681     // the names of the already created handlers and the handlers themselves 
 682     // (these arrays are synchronized) 
 683     wxSortedArrayString m_handlerNames
; 
 684     wxArrayHandlers m_handlers
; 
 686     wxWin32InputHandler 
*m_handlerDefault
; 
 688     wxWin32ColourScheme 
*m_scheme
; 
 690     WX_DECLARE_THEME(win32
) 
 693 // ---------------------------------------------------------------------------- 
 695 // ---------------------------------------------------------------------------- 
 697 // frame buttons bitmaps 
 699 static const char *frame_button_close_xpm
[] = { 
 714 static const char *frame_button_help_xpm
[] = { 
 729 static const char *frame_button_maximize_xpm
[] = { 
 744 static const char *frame_button_minimize_xpm
[] = { 
 759 static const char *frame_button_restore_xpm
[] = { 
 776 static const char *checked_menu_xpm
[] = { 
 777 /* columns rows colors chars-per-pixel */ 
 793 static const char *selected_checked_menu_xpm
[] = { 
 794 /* columns rows colors chars-per-pixel */ 
 810 static const char *disabled_checked_menu_xpm
[] = { 
 811 /* columns rows colors chars-per-pixel */ 
 828 static const char *selected_disabled_checked_menu_xpm
[] = { 
 829 /* columns rows colors chars-per-pixel */ 
 845 // checkbox and radiobox bitmaps below 
 847 static const char *checked_xpm
[] = { 
 848 /* columns rows colors chars-per-pixel */ 
 871 static const char *pressed_checked_xpm
[] = { 
 872 /* columns rows colors chars-per-pixel */ 
 894 static const char *pressed_disabled_checked_xpm
[] = { 
 895 /* columns rows colors chars-per-pixel */ 
 917 static const char *checked_item_xpm
[] = { 
 918 /* columns rows colors chars-per-pixel */ 
 939 static const char *unchecked_xpm
[] = { 
 940 /* columns rows colors chars-per-pixel */ 
 963 static const char *pressed_unchecked_xpm
[] = { 
 964 /* columns rows colors chars-per-pixel */ 
 986 static const char *unchecked_item_xpm
[] = { 
 987 /* columns rows colors chars-per-pixel */ 
1007 static const char *checked_radio_xpm
[] = { 
1008 /* columns rows colors chars-per-pixel */ 
1031 static const char *pressed_checked_radio_xpm
[] = { 
1032 /* columns rows colors chars-per-pixel */ 
1055 static const char *pressed_disabled_checked_radio_xpm
[] = { 
1056 /* columns rows colors chars-per-pixel */ 
1079 static const char *unchecked_radio_xpm
[] = { 
1080 /* columns rows colors chars-per-pixel */ 
1103 static const char *pressed_unchecked_radio_xpm
[] = { 
1104 /* columns rows colors chars-per-pixel */ 
1127 static const char ** 
1128     xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] = 
1133         { checked_xpm
, unchecked_xpm 
}, 
1136         { pressed_checked_xpm
, pressed_unchecked_xpm 
}, 
1139         { pressed_disabled_checked_xpm
, pressed_unchecked_xpm 
}, 
1145         { checked_radio_xpm
, unchecked_radio_xpm 
}, 
1148         { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm 
}, 
1151         { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm 
}, 
1157         { checked_menu_xpm
, NULL 
}, 
1160         { selected_checked_menu_xpm
, NULL 
}, 
1163         { disabled_checked_menu_xpm
, NULL 
}, 
1165         // disabled selected state 
1166         { selected_disabled_checked_menu_xpm
, NULL 
}, 
1170 static const char **xpmChecked
[IndicatorStatus_Max
] = 
1176 // ============================================================================ 
1178 // ============================================================================ 
1180 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme")); 
1182 // ---------------------------------------------------------------------------- 
1184 // ---------------------------------------------------------------------------- 
1186 wxWin32Theme::wxWin32Theme() 
1190     m_handlerDefault 
= NULL
; 
1191     m_artProvider 
= NULL
; 
1194 wxWin32Theme::~wxWin32Theme() 
1196     size_t count 
= m_handlers
.GetCount(); 
1197     for ( size_t n 
= 0; n 
< count
; n
++ ) 
1199         if ( m_handlers
[n
] != m_handlerDefault 
) 
1200             delete m_handlers
[n
]; 
1203     delete m_handlerDefault
; 
1207     wxArtProvider::RemoveProvider(m_artProvider
); 
1210 wxRenderer 
*wxWin32Theme::GetRenderer() 
1214         m_renderer 
= new wxWin32Renderer(GetColourScheme()); 
1220 wxArtProvider 
*wxWin32Theme::GetArtProvider() 
1222     if ( !m_artProvider 
) 
1224         m_artProvider 
= new wxWin32ArtProvider
; 
1227     return m_artProvider
; 
1230 wxInputHandler 
*wxWin32Theme::GetDefaultInputHandler() 
1232     if ( !m_handlerDefault 
) 
1234         m_handlerDefault 
= new wxWin32InputHandler(m_renderer
); 
1237     return m_handlerDefault
; 
1240 wxInputHandler 
*wxWin32Theme::GetInputHandler(const wxString
& control
) 
1242     wxInputHandler 
*handler
; 
1243     int n 
= m_handlerNames
.Index(control
); 
1244     if ( n 
== wxNOT_FOUND 
) 
1246         // create a new handler 
1247         if ( control 
== wxINP_HANDLER_SCROLLBAR 
) 
1248             handler 
= new wxWin32ScrollBarInputHandler(m_renderer
, 
1249                                                        GetDefaultInputHandler()); 
1251         else if ( control 
== wxINP_HANDLER_BUTTON 
) 
1252             handler 
= new wxStdButtonInputHandler(GetDefaultInputHandler()); 
1253 #endif // wxUSE_BUTTON 
1255         else if ( control 
== wxINP_HANDLER_CHECKBOX 
) 
1256             handler 
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler()); 
1257 #endif // wxUSE_CHECKBOX 
1259         else if ( control 
== wxINP_HANDLER_COMBOBOX 
) 
1260             handler 
= new wxStdComboBoxInputHandler(GetDefaultInputHandler()); 
1261 #endif // wxUSE_COMBOBOX 
1263         else if ( control 
== wxINP_HANDLER_LISTBOX 
) 
1264             handler 
= new wxStdListboxInputHandler(GetDefaultInputHandler()); 
1265 #endif // wxUSE_LISTBOX 
1266 #if wxUSE_CHECKLISTBOX 
1267         else if ( control 
== wxINP_HANDLER_CHECKLISTBOX 
) 
1268             handler 
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler()); 
1269 #endif // wxUSE_CHECKLISTBOX 
1271         else if ( control 
== wxINP_HANDLER_TEXTCTRL 
) 
1272             handler 
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler()); 
1273 #endif // wxUSE_TEXTCTRL 
1275         else if ( control 
== wxINP_HANDLER_SLIDER 
) 
1276             handler 
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler()); 
1277 #endif // wxUSE_SLIDER 
1279         else if ( control 
== wxINP_HANDLER_SPINBTN 
) 
1280             handler 
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler()); 
1281 #endif // wxUSE_SPINBTN 
1283         else if ( control 
== wxINP_HANDLER_NOTEBOOK 
) 
1284             handler 
= new wxStdNotebookInputHandler(GetDefaultInputHandler()); 
1285 #endif // wxUSE_NOTEBOOK 
1287         else if ( control 
== wxINP_HANDLER_STATUSBAR 
) 
1288             handler 
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler()); 
1289 #endif // wxUSE_STATUSBAR 
1291         else if ( control 
== wxINP_HANDLER_TOOLBAR 
) 
1292             handler 
= new wxStdToolbarInputHandler(GetDefaultInputHandler()); 
1293 #endif // wxUSE_TOOLBAR 
1294         else if ( control 
== wxINP_HANDLER_TOPLEVEL 
) 
1295             handler 
= new wxWin32FrameInputHandler(GetDefaultInputHandler()); 
1297             handler 
= GetDefaultInputHandler(); 
1299         n 
= m_handlerNames
.Add(control
); 
1300         m_handlers
.Insert(handler
, n
); 
1302     else // we already have it 
1304         handler 
= m_handlers
[n
]; 
1310 wxColourScheme 
*wxWin32Theme::GetColourScheme() 
1314         m_scheme 
= new wxWin32ColourScheme
; 
1319 // ============================================================================ 
1320 // wxWin32ColourScheme 
1321 // ============================================================================ 
1323 wxColour 
wxWin32ColourScheme::GetBackground(wxWindow 
*win
) const 
1326     if ( win
->UseBgCol() ) 
1328         // use the user specified colour 
1329         col 
= win
->GetBackgroundColour(); 
1332     if ( win
->IsContainerWindow() ) 
1334         wxTextCtrl 
*text 
= wxDynamicCast(win
, wxTextCtrl
); 
1337             if ( !text
->IsEnabled() ) // not IsEditable() 
1339             //else: execute code below 
1344             // doesn't depend on the state 
1350         int flags 
= win
->GetStateFlags(); 
1352         // the colour set by the user should be used for the normal state 
1353         // and for the states for which we don't have any specific colours 
1354         if ( !col
.Ok() || (flags 
& wxCONTROL_PRESSED
) != 0 ) 
1356             if ( wxDynamicCast(win
, wxScrollBar
) ) 
1357                 col 
= Get(flags 
& wxCONTROL_PRESSED 
? SCROLLBAR_PRESSED
 
1367 wxColour 
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const 
1371         // use the system colours under Windows 
1372 #if defined(__WXMSW__) 
1373         case WINDOW
:            return wxColour(GetSysColor(COLOR_WINDOW
)); 
1375         case CONTROL_PRESSED
: 
1376         case CONTROL_CURRENT
: 
1377         case CONTROL
:           return wxColour(GetSysColor(COLOR_BTNFACE
)); 
1379         case CONTROL_TEXT
:      return wxColour(GetSysColor(COLOR_BTNTEXT
)); 
1381 #if defined(COLOR_3DLIGHT) 
1382         case SCROLLBAR
:         return wxColour(GetSysColor(COLOR_3DLIGHT
)); 
1384         case SCROLLBAR
:         return wxColour(0xe0e0e0); 
1386         case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
)); 
1388         case HIGHLIGHT
:         return wxColour(GetSysColor(COLOR_HIGHLIGHT
)); 
1389         case HIGHLIGHT_TEXT
:    return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
)); 
1391 #if defined(COLOR_3DDKSHADOW) 
1392         case SHADOW_DARK
:       return wxColour(GetSysColor(COLOR_3DDKSHADOW
)); 
1394         case SHADOW_DARK
:       return wxColour(GetSysColor(COLOR_3DHADOW
)); 
1397         case CONTROL_TEXT_DISABLED
: 
1398         case SHADOW_HIGHLIGHT
:  return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
)); 
1400         case SHADOW_IN
:         return wxColour(GetSysColor(COLOR_BTNFACE
)); 
1402         case CONTROL_TEXT_DISABLED_SHADOW
: 
1403         case SHADOW_OUT
:        return wxColour(GetSysColor(COLOR_BTNSHADOW
)); 
1405         case TITLEBAR
:          return wxColour(GetSysColor(COLOR_INACTIVECAPTION
)); 
1406         case TITLEBAR_ACTIVE
:   return wxColour(GetSysColor(COLOR_ACTIVECAPTION
)); 
1407         case TITLEBAR_TEXT
:     return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
)); 
1408         case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
)); 
1410         case DESKTOP
:           return wxColour(0x808000); 
1412         // use the standard Windows colours elsewhere 
1413         case WINDOW
:            return *wxWHITE
; 
1415         case CONTROL_PRESSED
: 
1416         case CONTROL_CURRENT
: 
1417         case CONTROL
:           return wxColour(0xc0c0c0); 
1419         case CONTROL_TEXT
:      return *wxBLACK
; 
1421         case SCROLLBAR
:         return wxColour(0xe0e0e0); 
1422         case SCROLLBAR_PRESSED
: return *wxBLACK
; 
1424         case HIGHLIGHT
:         return wxColour(0x800000); 
1425         case HIGHLIGHT_TEXT
:    return wxColour(0xffffff); 
1427         case SHADOW_DARK
:       return *wxBLACK
; 
1429         case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0); 
1430         case SHADOW_HIGHLIGHT
:  return wxColour(0xffffff); 
1432         case SHADOW_IN
:         return wxColour(0xc0c0c0); 
1434         case CONTROL_TEXT_DISABLED_SHADOW
: 
1435         case SHADOW_OUT
:        return wxColour(0x7f7f7f); 
1437         case TITLEBAR
:          return wxColour(0xaeaaae); 
1438         case TITLEBAR_ACTIVE
:   return wxColour(0x820300); 
1439         case TITLEBAR_TEXT
:     return wxColour(0xc0c0c0); 
1440         case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
; 
1442         case DESKTOP
:           return wxColour(0x808000); 
1445         case GAUGE
:             return Get(HIGHLIGHT
); 
1449             wxFAIL_MSG(_T("invalid standard colour")); 
1454 // ============================================================================ 
1456 // ============================================================================ 
1458 // ---------------------------------------------------------------------------- 
1460 // ---------------------------------------------------------------------------- 
1462 wxWin32Renderer::wxWin32Renderer(const wxColourScheme 
*scheme
) 
1466     m_sizeScrollbarArrow 
= wxSize(16, 16); 
1468     // init colours and pens 
1469     m_penBlack 
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
); 
1471     m_colDarkGrey 
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
); 
1472     m_penDarkGrey 
= wxPen(m_colDarkGrey
, 0, wxSOLID
); 
1474     m_penLightGrey 
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
); 
1476     m_colHighlight 
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
); 
1477     m_penHighlight 
= wxPen(m_colHighlight
, 0, wxSOLID
); 
1479     m_titlebarFont 
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
); 
1480     m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
); 
1482     // init the arrow bitmaps 
1483     static const size_t ARROW_WIDTH 
= 7; 
1484     static const size_t ARROW_LENGTH 
= 4; 
1487     wxMemoryDC dcNormal
, 
1490     for ( size_t n 
= 0; n 
< Arrow_Max
; n
++ ) 
1492         bool isVertical 
= n 
> Arrow_Right
; 
1505         // disabled arrow is larger because of the shadow 
1506         m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
); 
1507         m_bmpArrows
[Arrow_Disabled
][n
].Create(w 
+ 1, h 
+ 1); 
1509         dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]); 
1510         dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]); 
1512         dcNormal
.SetBackground(*wxWHITE_BRUSH
); 
1513         dcDisabled
.SetBackground(*wxWHITE_BRUSH
); 
1517         dcNormal
.SetPen(m_penBlack
); 
1518         dcDisabled
.SetPen(m_penDarkGrey
); 
1520         // calculate the position of the point of the arrow 
1524             x1 
= (ARROW_WIDTH 
- 1)/2; 
1525             y1 
= n 
== Arrow_Up 
? 0 : ARROW_LENGTH 
- 1; 
1529             x1 
= n 
== Arrow_Left 
? 0 : ARROW_LENGTH 
- 1; 
1530             y1 
= (ARROW_WIDTH 
- 1)/2; 
1541         for ( size_t i 
= 0; i 
< ARROW_LENGTH
; i
++ ) 
1543             dcNormal
.DrawLine(x1
, y1
, x2
, y2
); 
1544             dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1551                 if ( n 
== Arrow_Up 
) 
1562             else // left or right arrow 
1567                 if ( n 
== Arrow_Left 
) 
1580         // draw the shadow for the disabled one 
1581         dcDisabled
.SetPen(m_penHighlight
); 
1586                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1590                 x1 
= ARROW_LENGTH 
- 1; 
1591                 y1 
= (ARROW_WIDTH 
- 1)/2 + 1; 
1594                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1595                 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
); 
1600                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1604                 x1 
= ARROW_WIDTH 
- 1; 
1606                 x2 
= (ARROW_WIDTH 
- 1)/2; 
1608                 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
); 
1609                 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
); 
1614         // create the inversed bitmap but only for the right arrow as we only 
1615         // use it for the menus 
1616         if ( n 
== Arrow_Right 
) 
1618             m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
); 
1619             dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]); 
1621             dcInverse
.Blit(0, 0, w
, h
, 
1624             dcInverse
.SelectObject(wxNullBitmap
); 
1626             mask 
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
); 
1627             m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
); 
1629             m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
); 
1630             dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]); 
1632             dcInverse
.Blit(0, 0, w
, h
, 
1635             dcInverse
.SelectObject(wxNullBitmap
); 
1637             mask 
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
); 
1638             m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
); 
1641         dcNormal
.SelectObject(wxNullBitmap
); 
1642         dcDisabled
.SelectObject(wxNullBitmap
); 
1644         mask 
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
); 
1645         m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
); 
1646         mask 
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
); 
1647         m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
); 
1649         m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
]; 
1652     // init the frame buttons bitmaps 
1653     m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
); 
1654     m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
); 
1655     m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
); 
1656     m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
); 
1657     m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
); 
1660 // ---------------------------------------------------------------------------- 
1662 // ---------------------------------------------------------------------------- 
1665    The raised border in Win32 looks like this: 
1667    IIIIIIIIIIIIIIIIIIIIIIB 
1669    I                    GB  I = white       (HILIGHT) 
1670    I                    GB  H = light grey  (LIGHT) 
1671    I                    GB  G = dark grey   (SHADOI) 
1672    I                    GB  B = black       (DKSHADOI) 
1673    I                    GB  I = hIghlight (COLOR_3DHILIGHT) 
1675    IGGGGGGGGGGGGGGGGGGGGGB 
1676    BBBBBBBBBBBBBBBBBBBBBBB 
1678    The sunken border looks like this: 
1680    GGGGGGGGGGGGGGGGGGGGGGI 
1681    GBBBBBBBBBBBBBBBBBBBBHI 
1688    GHHHHHHHHHHHHHHHHHHHHHI 
1689    IIIIIIIIIIIIIIIIIIIIIII 
1691    The static border (used for the controls which don't get focus) is like 
1694    GGGGGGGGGGGGGGGGGGGGGGW 
1702    WWWWWWWWWWWWWWWWWWWWWWW 
1704    The most complicated is the double border: 
1706    HHHHHHHHHHHHHHHHHHHHHHB 
1707    HWWWWWWWWWWWWWWWWWWWWGB 
1708    HWHHHHHHHHHHHHHHHHHHHGB 
1713    HWHHHHHHHHHHHHHHHHHHHGB 
1714    HGGGGGGGGGGGGGGGGGGGGGB 
1715    BBBBBBBBBBBBBBBBBBBBBBB 
1717    And the simple border is, well, simple: 
1719    BBBBBBBBBBBBBBBBBBBBBBB 
1728    BBBBBBBBBBBBBBBBBBBBBBB 
1731 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
) 
1735     dc
.SetBrush(*wxTRANSPARENT_BRUSH
); 
1736     dc
.DrawRectangle(*rect
); 
1742 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
) 
1744     // draw the bottom and right sides 
1746     dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(), 
1747                 rect
->GetRight() + 1, rect
->GetBottom()); 
1748     dc
.DrawLine(rect
->GetRight(), rect
->GetTop(), 
1749                 rect
->GetRight(), rect
->GetBottom()); 
1755 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect 
*rect
, 
1756                                      const wxPen
& pen1
, const wxPen
& pen2
) 
1758     // draw the rectangle 
1760     dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(), 
1761                 rect
->GetLeft(), rect
->GetBottom()); 
1762     dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(), 
1763                 rect
->GetRight(), rect
->GetTop()); 
1765     dc
.DrawLine(rect
->GetRight(), rect
->GetTop(), 
1766                 rect
->GetRight(), rect
->GetBottom()); 
1767     dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(), 
1768                 rect
->GetRight() + 1, rect
->GetBottom()); 
1774 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect 
*rect
) 
1776     DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
); 
1777     DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
); 
1780 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect 
*rect
) 
1782     DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
); 
1783     DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
); 
1786 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect 
*rect
, bool isPressed
) 
1790         DrawRect(dc
, rect
, m_penDarkGrey
); 
1792         // the arrow is usually drawn inside border of width 2 and is offset by 
1793         // another pixel in both directions when it's pressed - as the border 
1794         // in this case is more narrow as well, we have to adjust rect like 
1802         DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
); 
1803         DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
); 
1807 void wxWin32Renderer::DrawBorder(wxDC
& dc
, 
1809                                  const wxRect
& rectTotal
, 
1810                                  int WXUNUSED(flags
), 
1815     wxRect rect 
= rectTotal
; 
1819         case wxBORDER_SUNKEN
: 
1820             for ( i 
= 0; i 
< BORDER_THICKNESS 
/ 2; i
++ ) 
1822                 DrawSunkenBorder(dc
, &rect
); 
1826         case wxBORDER_STATIC
: 
1827             DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
); 
1830         case wxBORDER_RAISED
: 
1831             for ( i 
= 0; i 
< BORDER_THICKNESS 
/ 2; i
++ ) 
1833                 DrawRaisedBorder(dc
, &rect
); 
1837         case wxBORDER_DOUBLE
: 
1838             DrawArrowBorder(dc
, &rect
); 
1839             DrawRect(dc
, &rect
, m_penLightGrey
); 
1842         case wxBORDER_SIMPLE
: 
1843             for ( i 
= 0; i 
< BORDER_THICKNESS 
/ 2; i
++ ) 
1845                 DrawRect(dc
, &rect
, m_penBlack
); 
1850             wxFAIL_MSG(_T("unknown border type")); 
1853         case wxBORDER_DEFAULT
: 
1862 wxRect 
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const 
1867         case wxBORDER_RAISED
: 
1868         case wxBORDER_SUNKEN
: 
1869             width 
= BORDER_THICKNESS
; 
1872         case wxBORDER_SIMPLE
: 
1873         case wxBORDER_STATIC
: 
1877         case wxBORDER_DOUBLE
: 
1883             // char *crash = NULL; 
1885             wxFAIL_MSG(_T("unknown border type")); 
1889         case wxBORDER_DEFAULT
: 
1899     rect
.height 
= width
; 
1904 bool wxWin32Renderer::AreScrollbarsInsideBorder() const 
1909 // ---------------------------------------------------------------------------- 
1911 // ---------------------------------------------------------------------------- 
1913 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
, 
1919     // text controls are not special under windows 
1920     DrawBorder(dc
, border
, rect
, flags
, rectIn
); 
1923 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
, 
1924                                        const wxRect
& rectTotal
, 
1928     wxRect rect 
= rectTotal
; 
1930     if ( flags 
& wxCONTROL_PRESSED 
) 
1932         // button pressed: draw a double border around it 
1933         DrawRect(dc
, &rect
, m_penBlack
); 
1934         DrawRect(dc
, &rect
, m_penDarkGrey
); 
1938         // button not pressed 
1940         if ( flags 
& (wxCONTROL_FOCUSED 
| wxCONTROL_ISDEFAULT
) ) 
1942             // button either default or focused (or both): add an extra border around it 
1943             DrawRect(dc
, &rect
, m_penBlack
); 
1946         // now draw a normal button 
1947         DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
); 
1948         DrawHalfRect(dc
, &rect
, m_penDarkGrey
); 
1957 // ---------------------------------------------------------------------------- 
1959 // ---------------------------------------------------------------------------- 
1961 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
, 
1962                                          wxCoord y
, wxCoord x1
, wxCoord x2
) 
1964     dc
.SetPen(m_penDarkGrey
); 
1965     dc
.DrawLine(x1
, y
, x2 
+ 1, y
); 
1966     dc
.SetPen(m_penHighlight
); 
1968     dc
.DrawLine(x1
, y
, x2 
+ 1, y
); 
1971 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
, 
1972                                        wxCoord x
, wxCoord y1
, wxCoord y2
) 
1974     dc
.SetPen(m_penDarkGrey
); 
1975     dc
.DrawLine(x
, y1
, x
, y2 
+ 1); 
1976     dc
.SetPen(m_penHighlight
); 
1978     dc
.DrawLine(x
, y1
, x
, y2 
+ 1); 
1981 void wxWin32Renderer::DrawFrame(wxDC
& dc
, 
1982                                 const wxString
& label
, 
1988     wxCoord height 
= 0; // of the label 
1989     wxRect rectFrame 
= rect
; 
1990     if ( !label
.empty() ) 
1992         // the text should touch the top border of the rect, so the frame 
1993         // itself should be lower 
1994         dc
.GetTextExtent(label
, NULL
, &height
); 
1995         rectFrame
.y 
+= height 
/ 2; 
1996         rectFrame
.height 
-= height 
/ 2; 
1998         // we have to draw each part of the frame individually as we can't 
1999         // erase the background beyond the label as it might contain some 
2000         // pixmap already, so drawing everything and then overwriting part of 
2001         // the frame with label doesn't work 
2003         // TODO: the +5 and space insertion should be customizable 
2006         rectText
.x 
= rectFrame
.x 
+ 5; 
2007         rectText
.y 
= rect
.y
; 
2008         rectText
.width 
= rectFrame
.width 
- 7; // +2 border width 
2009         rectText
.height 
= height
; 
2012         label2 
<< _T(' ') << label 
<< _T(' '); 
2013         if ( indexAccel 
!= -1 ) 
2015             // adjust it as we prepended a space 
2020         DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
); 
2022         StandardDrawFrame(dc
, rectFrame
, rectLabel
); 
2026         // just draw the complete frame 
2027         DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
); 
2028         DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
); 
2032 // ---------------------------------------------------------------------------- 
2034 // ---------------------------------------------------------------------------- 
2036 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
) 
2038     // VZ: this doesn't work under Windows, the dotted pen has dots of 3 
2039     //     pixels each while we really need dots here... PS_ALTERNATE might 
2040     //     work, but it is for NT 5 only 
2042     DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
)); 
2044     // draw the pixels manually: note that to behave in the same manner as 
2045     // DrawRect(), we must exclude the bottom and right borders from the 
2047     wxCoord x1 
= rect
.GetLeft(), 
2049             x2 
= rect
.GetRight(), 
2050             y2 
= rect
.GetBottom(); 
2052     dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
)); 
2054     // this seems to be closer than what Windows does than wxINVERT although 
2055     // I'm still not sure if it's correct 
2056     dc
.SetLogicalFunction(wxAND_REVERSE
); 
2059     for ( z 
= x1 
+ 1; z 
< x2
; z 
+= 2 ) 
2060         dc
.DrawPoint(z
, rect
.GetTop()); 
2062     wxCoord shift 
= z 
== x2 
? 0 : 1; 
2063     for ( z 
= y1 
+ shift
; z 
< y2
; z 
+= 2 ) 
2064         dc
.DrawPoint(x2
, z
); 
2066     shift 
= z 
== y2 
? 0 : 1; 
2067     for ( z 
= x2 
- shift
; z 
> x1
; z 
-= 2 ) 
2068         dc
.DrawPoint(z
, y2
); 
2070     shift 
= z 
== x1 
? 0 : 1; 
2071     for ( z 
= y2 
- shift
; z 
> y1
; z 
-= 2 ) 
2072         dc
.DrawPoint(x1
, z
); 
2074     dc
.SetLogicalFunction(wxCOPY
); 
2078 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
, 
2079                                       const wxString
& label
, 
2084     // draw shadow of the text 
2085     dc
.SetTextForeground(m_colHighlight
); 
2086     wxRect rectShadow 
= rect
; 
2089     dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
); 
2091     // make the text grey 
2092     dc
.SetTextForeground(m_colDarkGrey
); 
2095 void wxWin32Renderer::DrawLabel(wxDC
& dc
, 
2096                                 const wxString
& label
, 
2103     DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
); 
2106 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
, 
2107                                   const wxString
& label
, 
2113                                   const wxPoint
& focusOffset
) 
2115     // the underscores are not drawn for focused controls in wxMSW 
2116     if ( flags 
& wxCONTROL_FOCUSED 
) 
2121     if ( flags 
& wxCONTROL_DISABLED 
) 
2123         // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED 
2124         // currently only can happen for a menu item and it seems that Windows 
2125         // doesn't draw the shadow in this case, so we don't do it neither 
2126         if ( flags 
& wxCONTROL_SELECTED 
) 
2128             // just make the label text greyed out 
2129             dc
.SetTextForeground(m_colDarkGrey
); 
2131         else // draw normal disabled label 
2133             DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
); 
2138     dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
); 
2140     if ( flags 
& wxCONTROL_DISABLED 
) 
2142         // restore the fg colour 
2143         dc
.SetTextForeground(*wxBLACK
); 
2146     if ( flags 
& wxCONTROL_FOCUSED 
) 
2148         if ( focusOffset
.x 
|| focusOffset
.y 
) 
2150             rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
); 
2153         DrawFocusRect(dc
, rectLabel
); 
2157         *rectBounds 
= rectLabel
; 
2160 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
, 
2161                                       const wxString
& label
, 
2162                                       const wxBitmap
& image
, 
2169     // the underscores are not drawn for focused controls in wxMSW 
2170     if ( flags 
& wxCONTROL_PRESSED 
) 
2175     wxRect rectLabel 
= rect
; 
2176     if ( !label
.empty() ) 
2178         // shift the label if a button is pressed 
2179         if ( flags 
& wxCONTROL_PRESSED 
) 
2185         if ( flags 
& wxCONTROL_DISABLED 
) 
2187             DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
); 
2190         // leave enough space for the focus rectangle 
2191         if ( flags 
& wxCONTROL_FOCUSED 
) 
2193             rectLabel
.Inflate(-2); 
2197     dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
); 
2199     if ( !label
.empty() && (flags 
& wxCONTROL_FOCUSED
) ) 
2201         if ( flags 
& wxCONTROL_PRESSED 
) 
2203             // the focus rectangle is never pressed, so undo the shift done 
2211         DrawFocusRect(dc
, rectLabel
); 
2215 // ---------------------------------------------------------------------------- 
2216 // (check)listbox items 
2217 // ---------------------------------------------------------------------------- 
2219 void wxWin32Renderer::DrawItem(wxDC
& dc
, 
2220                                const wxString
& label
, 
2224     wxDCTextColourChanger 
colChanger(dc
); 
2226     if ( flags 
& wxCONTROL_SELECTED 
) 
2228         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
2230         wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
2231         dc
.SetBrush(wxBrush(colBg
, wxSOLID
)); 
2232         dc
.SetPen(wxPen(colBg
, 0, wxSOLID
)); 
2233         dc
.DrawRectangle(rect
); 
2236     wxRect rectText 
= rect
; 
2238     rectText
.width 
-= 2; 
2239     dc
.DrawLabel(label
, wxNullBitmap
, rectText
); 
2241     if ( flags 
& wxCONTROL_FOCUSED 
) 
2243         DrawFocusRect(dc
, rect
); 
2247 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
, 
2248                                     const wxString
& label
, 
2249                                     const wxBitmap
& bitmap
, 
2258     else // use default bitmap 
2260         IndicatorStatus i 
= flags 
& wxCONTROL_CHECKED
 
2261                                 ? IndicatorStatus_Checked
 
2262                                 : IndicatorStatus_Unchecked
; 
2264         if ( !m_bmpCheckBitmaps
[i
].Ok() ) 
2266             m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]); 
2269         bmp 
= m_bmpCheckBitmaps
[i
]; 
2272     dc
.DrawBitmap(bmp
, rect
.x
, rect
.y 
+ (rect
.height 
- bmp
.GetHeight()) / 2 - 1, 
2273                   TRUE 
/* use mask */); 
2275     wxRect rectLabel 
= rect
; 
2276     int bmpWidth 
= bmp
.GetWidth(); 
2277     rectLabel
.x 
+= bmpWidth
; 
2278     rectLabel
.width 
-= bmpWidth
; 
2280     DrawItem(dc
, label
, rectLabel
, flags
); 
2283 // ---------------------------------------------------------------------------- 
2284 // check/radio buttons 
2285 // ---------------------------------------------------------------------------- 
2287 wxBitmap 
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
) 
2289     IndicatorState indState
; 
2290     if ( flags 
& wxCONTROL_SELECTED 
) 
2291         indState 
= flags 
& wxCONTROL_DISABLED 
? IndicatorState_SelectedDisabled
 
2292                                               : IndicatorState_Selected
; 
2293     else if ( flags 
& wxCONTROL_DISABLED 
) 
2294         indState 
= IndicatorState_Disabled
; 
2295     else if ( flags 
& wxCONTROL_PRESSED 
) 
2296         indState 
= IndicatorState_Pressed
; 
2298         indState 
= IndicatorState_Normal
; 
2300     IndicatorStatus indStatus 
= flags 
& wxCONTROL_CHECKED
 
2301                                     ? IndicatorStatus_Checked
 
2302                                     : IndicatorStatus_Unchecked
; 
2304     wxBitmap bmp 
= m_bmpIndicators
[indType
][indState
][indStatus
]; 
2307         const char **xpm 
= xpmIndicators
[indType
][indState
][indStatus
]; 
2310             // create and cache it 
2311             bmp 
= wxBitmap(xpm
); 
2312             m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
; 
2319 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
, 
2320                                              const wxString
& label
, 
2321                                              const wxBitmap
& bitmap
, 
2326                                              wxCoord focusOffsetY
) 
2328     // calculate the position of the bitmap and of the label 
2329     wxCoord heightBmp 
= bitmap
.GetHeight(); 
2331             yBmp 
= rect
.y 
+ (rect
.height 
- heightBmp
) / 2; 
2334     dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
); 
2335     rectLabel
.y 
= rect
.y 
+ (rect
.height 
- rectLabel
.height
) / 2; 
2337     // align label vertically with the bitmap - looks nicer like this 
2338     rectLabel
.y 
-= (rectLabel
.height 
- heightBmp
) % 2; 
2340     // calc horz position 
2341     if ( align 
== wxALIGN_RIGHT 
) 
2343         xBmp 
= rect
.GetRight() - bitmap
.GetWidth(); 
2344         rectLabel
.x 
= rect
.x 
+ 3; 
2345         rectLabel
.SetRight(xBmp
); 
2347     else // normal (checkbox to the left of the text) case 
2350         rectLabel
.x 
= xBmp 
+ bitmap
.GetWidth() + 5; 
2351         rectLabel
.SetRight(rect
.GetRight()); 
2354     dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE 
/* use mask */); 
2357                 dc
, label
, rectLabel
, 
2359                 wxALIGN_LEFT 
| wxALIGN_TOP
, 
2361                 NULL
,         // we don't need bounding rect 
2362                 // use custom vert focus rect offset 
2363                 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
) 
2367 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
, 
2368                                       const wxString
& label
, 
2369                                       const wxBitmap
& bitmap
, 
2379         bmp 
= GetRadioBitmap(flags
); 
2381     DrawCheckOrRadioButton(dc
, label
, 
2383                            rect
, flags
, align
, indexAccel
, 
2384                            FOCUS_RECT_OFFSET_Y
); // default focus rect offset 
2387 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
, 
2388                                       const wxString
& label
, 
2389                                       const wxBitmap
& bitmap
, 
2399         bmp 
= GetCheckBitmap(flags
); 
2401     DrawCheckOrRadioButton(dc
, label
, 
2403                            rect
, flags
, align
, indexAccel
, 
2404                            0); // no focus rect offset for checkboxes 
2407 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
, 
2408                                         const wxString
& label
, 
2409                                         const wxBitmap
& bitmap
, 
2410                                         const wxRect
& rectOrig
, 
2414     if (style 
== wxTOOL_STYLE_BUTTON
) 
2416         wxRect rect 
= rectOrig
; 
2417         rect
.Deflate(BORDER_THICKNESS
); 
2419         if ( flags 
& wxCONTROL_PRESSED 
) 
2421             DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
); 
2423         else if ( flags 
& wxCONTROL_CURRENT 
) 
2425             DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
); 
2428         dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
); 
2430     else if (style 
== wxTOOL_STYLE_SEPARATOR
) 
2432         // leave a small gap aroudn the line, also account for the toolbar 
2434         DrawVerticalLine(dc
, rectOrig
.x 
+ rectOrig
.width
/2, 
2435                          rectOrig
.y 
+ 2*BORDER_THICKNESS
, 
2436                          rectOrig
.GetBottom() - BORDER_THICKNESS
); 
2438     // don't draw wxTOOL_STYLE_CONTROL 
2441 // ---------------------------------------------------------------------------- 
2443 // ---------------------------------------------------------------------------- 
2445 void wxWin32Renderer::DrawTextLine(wxDC
& dc
, 
2446                                    const wxString
& text
, 
2452     // nothing special to do here 
2453     StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
); 
2456 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
) 
2458     // we don't draw them 
2461 // ---------------------------------------------------------------------------- 
2463 // ---------------------------------------------------------------------------- 
2465 void wxWin32Renderer::DrawTab(wxDC
& dc
, 
2466                               const wxRect
& rectOrig
, 
2468                               const wxString
& label
, 
2469                               const wxBitmap
& bitmap
, 
2473     wxRect rect 
= rectOrig
; 
2475     // the current tab is drawn indented (to the top for default case) and 
2476     // bigger than the other ones 
2477     const wxSize indent 
= GetTabIndent(); 
2478     if ( flags 
& wxCONTROL_SELECTED 
) 
2483                 wxFAIL_MSG(_T("invaild notebook tab orientation")); 
2487                 rect
.Inflate(indent
.x
, 0); 
2489                 rect
.height 
+= indent
.y
; 
2493                 rect
.Inflate(indent
.x
, 0); 
2494                 rect
.height 
+= indent
.y
; 
2499                 wxFAIL_MSG(_T("TODO")); 
2504     // draw the text, image and the focus around them (if necessary) 
2505     wxRect rectLabel 
= rect
; 
2506     rectLabel
.Deflate(1, 1); 
2507     DrawButtonLabel(dc
, label
, bitmap
, rectLabel
, 
2508                     flags
, wxALIGN_CENTRE
, indexAccel
); 
2510     // now draw the tab border itself (maybe use DrawRoundedRectangle()?) 
2511     static const wxCoord CUTOFF 
= 2; // radius of the rounded corner 
2514             x2 
= rect
.GetRight(), 
2515             y2 
= rect
.GetBottom(); 
2517     // FIXME: all this code will break if the tab indent or the border width, 
2518     //        it is tied to the fact that both of them are equal to 2 
2523             dc
.SetPen(m_penHighlight
); 
2524             dc
.DrawLine(x
, y2
, x
, y 
+ CUTOFF
); 
2525             dc
.DrawLine(x
, y 
+ CUTOFF
, x 
+ CUTOFF
, y
); 
2526             dc
.DrawLine(x 
+ CUTOFF
, y
, x2 
- CUTOFF 
+ 1, y
); 
2528             dc
.SetPen(m_penBlack
); 
2529             dc
.DrawLine(x2
, y2
, x2
, y 
+ CUTOFF
); 
2530             dc
.DrawLine(x2
, y 
+ CUTOFF
, x2 
- CUTOFF
, y
); 
2532             dc
.SetPen(m_penDarkGrey
); 
2533             dc
.DrawLine(x2 
- 1, y2
, x2 
- 1, y 
+ CUTOFF 
- 1); 
2535             if ( flags 
& wxCONTROL_SELECTED 
) 
2537                 dc
.SetPen(m_penLightGrey
); 
2539                 // overwrite the part of the border below this tab 
2540                 dc
.DrawLine(x 
+ 1, y2 
+ 1, x2 
- 1, y2 
+ 1); 
2542                 // and the shadow of the tab to the left of us 
2543                 dc
.DrawLine(x 
+ 1, y 
+ CUTOFF 
+ 1, x 
+ 1, y2 
+ 1); 
2548             dc
.SetPen(m_penHighlight
); 
2549             // we need to continue one pixel further to overwrite the corner of 
2550             // the border for the selected tab 
2551             dc
.DrawLine(x
, y 
- (flags 
& wxCONTROL_SELECTED 
? 1 : 0), 
2553             dc
.DrawLine(x
, y2 
- CUTOFF
, x 
+ CUTOFF
, y2
); 
2555             dc
.SetPen(m_penBlack
); 
2556             dc
.DrawLine(x 
+ CUTOFF
, y2
, x2 
- CUTOFF 
+ 1, y2
); 
2557             dc
.DrawLine(x2
, y
, x2
, y2 
- CUTOFF
); 
2558             dc
.DrawLine(x2
, y2 
- CUTOFF
, x2 
- CUTOFF
, y2
); 
2560             dc
.SetPen(m_penDarkGrey
); 
2561             dc
.DrawLine(x 
+ CUTOFF
, y2 
- 1, x2 
- CUTOFF 
+ 1, y2 
- 1); 
2562             dc
.DrawLine(x2 
- 1, y
, x2 
- 1, y2 
- CUTOFF 
+ 1); 
2564             if ( flags 
& wxCONTROL_SELECTED 
) 
2566                 dc
.SetPen(m_penLightGrey
); 
2568                 // overwrite the part of the (double!) border above this tab 
2569                 dc
.DrawLine(x 
+ 1, y 
- 1, x2 
- 1, y 
- 1); 
2570                 dc
.DrawLine(x 
+ 1, y 
- 2, x2 
- 1, y 
- 2); 
2572                 // and the shadow of the tab to the left of us 
2573                 dc
.DrawLine(x 
+ 1, y2 
- CUTOFF
, x 
+ 1, y 
- 1); 
2579             wxFAIL_MSG(_T("TODO")); 
2583 // ---------------------------------------------------------------------------- 
2585 // ---------------------------------------------------------------------------- 
2587 wxSize 
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
, 
2589                                            wxOrientation orient
) const 
2592     wxCoord width  
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2; 
2593     wxCoord height 
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
); 
2595     if (orient 
== wxHORIZONTAL
)  
2609 wxRect 
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
, 
2611                                            wxOrientation orient
, 
2614     bool transpose 
= (orient 
== wxVERTICAL
); 
2615     bool left  
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2616                  (((style 
& wxSL_TOP
) != 0) & !transpose 
| 
2617                   ((style 
& wxSL_LEFT
) != 0) & transpose 
| 
2618                   ((style 
& wxSL_BOTH
) != 0)); 
2619     bool right 
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2620                  (((style 
& wxSL_BOTTOM
) != 0) & !transpose 
| 
2621                   ((style 
& wxSL_RIGHT
) != 0) & transpose 
| 
2622                   ((style 
& wxSL_BOTH
) != 0)); 
2624     wxRect rect 
= rectOrig
; 
2626     wxSize sizeThumb 
= GetSliderThumbSize (rect
, lenThumb
, orient
); 
2628     if (orient 
== wxHORIZONTAL
) { 
2629         rect
.x 
+= SLIDER_MARGIN
; 
2632             rect
.y 
+= wxMax ((rect
.height 
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2); 
2636             rect
.y 
+= wxMax ((rect
.height 
- 2*BORDER_THICKNESS 
- sizeThumb
.y
/2), sizeThumb
.y
/2); 
2640             rect
.y 
+= sizeThumb
.y
/2; 
2642         rect
.width 
-= 2*SLIDER_MARGIN
; 
2643         rect
.height 
= 2*BORDER_THICKNESS
; 
2647         rect
.y 
+= SLIDER_MARGIN
; 
2650             rect
.x 
+= wxMax ((rect
.width 
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2); 
2654             rect
.x 
+= wxMax ((rect
.width 
- 2*BORDER_THICKNESS 
- sizeThumb
.x
/2), sizeThumb
.x
/2); 
2658             rect
.x 
+= sizeThumb
.x
/2; 
2660         rect
.width 
= 2*BORDER_THICKNESS
; 
2661         rect
.height 
-= 2*SLIDER_MARGIN
; 
2667 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
, 
2668                                       const wxRect
& rectOrig
, 
2670                                       wxOrientation orient
, 
2675     /*    show shaft geometry 
2693     if (flags 
& wxCONTROL_FOCUSED
) { 
2694         DrawFocusRect(dc
, rectOrig
); 
2697     wxRect rect 
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
); 
2699     if (rectShaft
) *rectShaft 
= rect
; 
2701     DrawSunkenBorder(dc
, &rect
); 
2704 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
, 
2706                                       wxOrientation orient
, 
2710     /*    show thumb geometry 
2719        H         D B   where H is hightlight colour 
2733        The interior of this shape is filled with the hatched brush if the thumb 
2737     DrawBackground(dc
, wxNullColour
, rect
, flags
); 
2739     bool transpose 
= (orient 
== wxVERTICAL
); 
2740     bool left  
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2741                  (((style 
& wxSL_TOP
) != 0) & !transpose 
| 
2742                   ((style 
& wxSL_LEFT
) != 0) & transpose
) & 
2743                  ((style 
& wxSL_BOTH
) == 0); 
2744     bool right 
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2745                  (((style 
& wxSL_BOTTOM
) != 0) & !transpose 
| 
2746                   ((style 
& wxSL_RIGHT
) != 0) & transpose
) & 
2747                  ((style 
& wxSL_BOTH
) == 0); 
2749     wxCoord sizeArrow 
= (transpose 
? rect
.height 
: rect
.width
) / 2; 
2750     wxCoord c 
= ((transpose 
? rect
.height 
: rect
.width
) - 2*sizeArrow
); 
2752     wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
; 
2753     x1 
= (transpose 
? rect
.y 
: rect
.x
); 
2754     x2 
= (transpose 
? rect
.GetBottom() : rect
.GetRight()); 
2755     x3 
= (x1
-1+c
) + sizeArrow
; 
2756     y1 
= (transpose 
? rect
.x 
: rect
.y
); 
2757     y2 
= (transpose 
? rect
.GetRight() : rect
.GetBottom()); 
2758     y3 
= (left  
? (y1
-1+c
) + sizeArrow 
: y1
); 
2759     y4 
= (right 
? (y2
+1-c
) - sizeArrow 
: y2
); 
2761     dc
.SetPen(m_penBlack
); 
2763         DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
); 
2765     DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
); 
2768         DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
); 
2772         DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
); 
2775     dc
.SetPen(m_penDarkGrey
); 
2776     DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
); 
2778         DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
); 
2782         DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
); 
2785     dc
.SetPen(m_penHighlight
); 
2788         DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
); 
2789         DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
); 
2793         DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
); 
2795     DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
); 
2798         DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
); 
2801     if (flags 
& wxCONTROL_PRESSED
) { 
2802         // TODO: MSW fills the entire area inside, not just the rect 
2803         wxRect rectInt 
= rect
; 
2806             rectInt
.SetLeft(y3
); 
2807             rectInt
.SetRight(y4
); 
2812             rectInt
.SetBottom(y4
); 
2816 #if !defined(__WXMGL__) 
2817         static const char *stipple_xpm
[] = { 
2818             /* columns rows colors chars-per-pixel */ 
2827         // VS: MGL can only do 8x8 stipple brushes 
2828         static const char *stipple_xpm
[] = { 
2829             /* columns rows colors chars-per-pixel */ 
2844         dc
.SetBrush(wxBrush(stipple_xpm
)); 
2846         dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
)); 
2847         dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
)); 
2848         dc
.SetPen(*wxTRANSPARENT_PEN
); 
2849         dc
.DrawRectangle(rectInt
); 
2853 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
, 
2856                                       wxOrientation orient
, 
2863     /*    show ticks geometry 
2878     if (end 
== start
) return; 
2880     bool transpose 
= (orient 
== wxVERTICAL
); 
2881     bool left  
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2882                  (((style 
& wxSL_TOP
) != 0) & !transpose 
| 
2883                   ((style 
& wxSL_LEFT
) != 0) & transpose 
| 
2884                   ((style 
& wxSL_BOTH
) != 0)); 
2885     bool right 
= ((style 
& wxSL_AUTOTICKS
) != 0) & 
2886                  (((style 
& wxSL_BOTTOM
) != 0) & !transpose 
| 
2887                   ((style 
& wxSL_RIGHT
) != 0) & transpose 
| 
2888                   ((style 
& wxSL_BOTH
) != 0)); 
2890     // default thumb size 
2891     wxSize sizeThumb 
= GetSliderThumbSize (rect
, 0, orient
); 
2892     wxCoord defaultLen 
= (transpose 
? sizeThumb
.x 
: sizeThumb
.y
); 
2894     // normal thumb size 
2895     sizeThumb 
= GetSliderThumbSize (rect
, lenThumb
, orient
); 
2896     wxCoord widthThumb  
= (transpose 
? sizeThumb
.y 
: sizeThumb
.x
); 
2898     wxRect rectShaft 
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
); 
2900     wxCoord x1
, x2
, y1
, y2
, y3
, y4 
, len
; 
2901     x1 
= (transpose 
? rectShaft
.y 
: rectShaft
.x
) + widthThumb
/2; 
2902     x2 
= (transpose 
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2; 
2903     y1 
= (transpose 
? rectShaft
.x 
: rectShaft
.y
) - defaultLen
/2; 
2904     y2 
= (transpose 
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2; 
2905     y3 
= (transpose 
? rect
.x 
: rect
.y
); 
2906     y4 
= (transpose 
? rect
.GetRight() : rect
.GetBottom()); 
2909     dc
.SetPen(m_penBlack
); 
2911     int range 
= end 
- start
; 
2912     for ( int n 
= 0; n 
< range
; n 
+= step 
) { 
2913         wxCoord x 
= x1 
+ (len
*n
) / range
; 
2915         if (left 
& (y1 
> y3
)) { 
2916             DrawLine(dc
, x
, y1
, x
, y3
, orient 
== wxVERTICAL
); 
2918         if (right 
& (y4 
> y2
)) { 
2919             DrawLine(dc
, x
, y2
, x
, y4
, orient 
== wxVERTICAL
); 
2922     // always draw the line at the end position 
2923     if (left 
& (y1 
> y3
)) { 
2924         DrawLine(dc
, x2
, y1
, x2
, y3
, orient 
== wxVERTICAL
); 
2926     if (right 
& (y4 
> y2
)) { 
2927         DrawLine(dc
, x2
, y2
, x2
, y4
, orient 
== wxVERTICAL
); 
2931 // ---------------------------------------------------------------------------- 
2933 // ---------------------------------------------------------------------------- 
2935 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer 
2936 class WXDLLEXPORT wxWin32MenuGeometryInfo 
: public wxMenuGeometryInfo
 
2939     virtual wxSize 
GetSize() const { return m_size
; } 
2941     wxCoord 
GetLabelOffset() const { return m_ofsLabel
; } 
2942     wxCoord 
GetAccelOffset() const { return m_ofsAccel
; } 
2944     wxCoord 
GetItemHeight() const { return m_heightItem
; } 
2947     // the total size of the menu 
2950     // the offset of the start of the menu item label 
2953     // the offset of the start of the accel label 
2956     // the height of a normal (not separator) item 
2957     wxCoord m_heightItem
; 
2959     friend wxMenuGeometryInfo 
* 
2960         wxWin32Renderer::GetMenuGeometry(wxWindow 
*, const wxMenu
&) const; 
2963 // FIXME: all constants are hardcoded but shouldn't be 
2964 static const wxCoord MENU_LEFT_MARGIN 
= 9; 
2965 static const wxCoord MENU_RIGHT_MARGIN 
= 18; 
2966 static const wxCoord MENU_VERT_MARGIN 
= 3; 
2968 // the margin around bitmap/check marks (on each side) 
2969 static const wxCoord MENU_BMP_MARGIN 
= 2; 
2971 // the margin between the labels and accel strings 
2972 static const wxCoord MENU_ACCEL_MARGIN 
= 8; 
2974 // the separator height in pixels: in fact, strangely enough, the real height 
2975 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into 
2977 static const wxCoord MENU_SEPARATOR_HEIGHT 
= 3; 
2979 // the size of the standard checkmark bitmap 
2980 static const wxCoord MENU_CHECK_SIZE 
= 9; 
2982 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
, 
2983                                       const wxRect
& rectOrig
, 
2984                                       const wxString
& label
, 
2988     wxRect rect 
= rectOrig
; 
2991     wxDCTextColourChanger 
colChanger(dc
); 
2993     if ( flags 
& wxCONTROL_SELECTED 
) 
2995         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
2997         wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
2998         dc
.SetBrush(wxBrush(colBg
, wxSOLID
)); 
2999         dc
.SetPen(wxPen(colBg
, 0, wxSOLID
)); 
3000         dc
.DrawRectangle(rect
); 
3003     // don't draw the focus rect around menu bar items 
3004     DrawLabel(dc
, label
, rect
, flags 
& ~wxCONTROL_FOCUSED
, 
3005               wxALIGN_CENTRE
, indexAccel
); 
3008 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
, 
3010                                    const wxMenuGeometryInfo
& gi
, 
3011                                    const wxString
& label
, 
3012                                    const wxString
& accel
, 
3013                                    const wxBitmap
& bitmap
, 
3017     const wxWin32MenuGeometryInfo
& geometryInfo 
= 
3018         (const wxWin32MenuGeometryInfo
&)gi
; 
3023     rect
.width 
= geometryInfo
.GetSize().x
; 
3024     rect
.height 
= geometryInfo
.GetItemHeight(); 
3026     // draw the selected item specially 
3027     wxDCTextColourChanger 
colChanger(dc
); 
3028     if ( flags 
& wxCONTROL_SELECTED 
) 
3030         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
3032         wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
3033         dc
.SetBrush(wxBrush(colBg
, wxSOLID
)); 
3034         dc
.SetPen(wxPen(colBg
, 0, wxSOLID
)); 
3035         dc
.DrawRectangle(rect
); 
3038     // draw the bitmap: use the bitmap provided or the standard checkmark for 
3039     // the checkable items 
3040     wxBitmap bmp 
= bitmap
; 
3041     if ( !bmp
.Ok() && (flags 
& wxCONTROL_CHECKED
) ) 
3043         bmp 
= GetIndicator(IndicatorType_Menu
, flags
); 
3048         rect
.SetRight(geometryInfo
.GetLabelOffset()); 
3049         wxControlRenderer::DrawBitmap(dc
, bmp
, rect
); 
3053     rect
.x 
= geometryInfo
.GetLabelOffset(); 
3054     rect
.SetRight(geometryInfo
.GetAccelOffset()); 
3056     DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
); 
3058     // draw the accel string 
3059     rect
.x 
= geometryInfo
.GetAccelOffset(); 
3060     rect
.SetRight(geometryInfo
.GetSize().x
); 
3062     // NB: no accel index here 
3063     DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
); 
3065     // draw the submenu indicator 
3066     if ( flags 
& wxCONTROL_ISSUBMENU 
) 
3068         rect
.x 
= geometryInfo
.GetSize().x 
- MENU_RIGHT_MARGIN
; 
3069         rect
.width 
= MENU_RIGHT_MARGIN
; 
3071         wxArrowStyle arrowStyle
; 
3072         if ( flags 
& wxCONTROL_DISABLED 
) 
3073             arrowStyle 
= flags 
& wxCONTROL_SELECTED 
? Arrow_InversedDisabled
 
3075         else if ( flags 
& wxCONTROL_SELECTED 
) 
3076             arrowStyle 
= Arrow_Inversed
; 
3078             arrowStyle 
= Arrow_Normal
; 
3080         DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
); 
3084 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
, 
3086                                         const wxMenuGeometryInfo
& geomInfo
) 
3088     DrawHorizontalLine(dc
, y 
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
); 
3091 wxSize 
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const 
3093     wxSize size 
= sizeText
; 
3095     // FIXME: menubar height is configurable under Windows 
3102 wxMenuGeometryInfo 
*wxWin32Renderer::GetMenuGeometry(wxWindow 
*win
, 
3103                                                      const wxMenu
& menu
) const 
3105     // prepare the dc: for now we draw all the items with the system font 
3107     dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
3109     // the height of a normal item 
3110     wxCoord heightText 
= dc
.GetCharHeight(); 
3115     // the max length of label and accel strings: the menu width is the sum of 
3116     // them, even if they're for different items (as the accels should be 
3119     // the max length of the bitmap is never 0 as Windows always leaves enough 
3120     // space for a check mark indicator 
3121     wxCoord widthLabelMax 
= 0, 
3123             widthBmpMax 
= MENU_LEFT_MARGIN
; 
3125     for ( wxMenuItemList::Node 
*node 
= menu
.GetMenuItems().GetFirst(); 
3127           node 
= node
->GetNext() ) 
3129         // height of this item 
3132         wxMenuItem 
*item 
= node
->GetData(); 
3133         if ( item
->IsSeparator() ) 
3135             h 
= MENU_SEPARATOR_HEIGHT
; 
3137         else // not separator 
3142             dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
); 
3143             if ( widthLabel 
> widthLabelMax 
) 
3145                 widthLabelMax 
= widthLabel
; 
3149             dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
); 
3150             if ( widthAccel 
> widthAccelMax 
) 
3152                 widthAccelMax 
= widthAccel
; 
3155             const wxBitmap
& bmp 
= item
->GetBitmap(); 
3158                 wxCoord widthBmp 
= bmp
.GetWidth(); 
3159                 if ( widthBmp 
> widthBmpMax 
) 
3160                     widthBmpMax 
= widthBmp
; 
3162             //else if ( item->IsCheckable() ): no need to check for this as 
3163             // MENU_LEFT_MARGIN is big enough to show the check mark 
3166         h 
+= 2*MENU_VERT_MARGIN
; 
3168         // remember the item position and height 
3169         item
->SetGeometry(height
, h
); 
3174     // bundle the metrics into a struct and return it 
3175     wxWin32MenuGeometryInfo 
*gi 
= new wxWin32MenuGeometryInfo
; 
3177     gi
->m_ofsLabel 
= widthBmpMax 
+ 2*MENU_BMP_MARGIN
; 
3178     gi
->m_ofsAccel 
= gi
->m_ofsLabel 
+ widthLabelMax
; 
3179     if ( widthAccelMax 
> 0 ) 
3181         // if we actually have any accesl, add a margin 
3182         gi
->m_ofsAccel 
+= MENU_ACCEL_MARGIN
; 
3185     gi
->m_heightItem 
= heightText 
+ 2*MENU_VERT_MARGIN
; 
3187     gi
->m_size
.x 
= gi
->m_ofsAccel 
+ widthAccelMax 
+ MENU_RIGHT_MARGIN
; 
3188     gi
->m_size
.y 
= height
; 
3193 // ---------------------------------------------------------------------------- 
3195 // ---------------------------------------------------------------------------- 
3197 static const wxCoord STATBAR_BORDER_X 
= 2; 
3198 static const wxCoord STATBAR_BORDER_Y 
= 2; 
3200 wxSize 
wxWin32Renderer::GetStatusBarBorders(wxCoord 
*borderBetweenFields
) const 
3202     if ( borderBetweenFields 
) 
3203         *borderBetweenFields 
= 2; 
3205     return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
); 
3208 void wxWin32Renderer::DrawStatusField(wxDC
& dc
, 
3210                                       const wxString
& label
, 
3215     if ( flags 
& wxCONTROL_ISDEFAULT 
) 
3217         // draw the size grip: it is a normal rect except that in the lower 
3218         // right corner we have several bands which may be used for dragging 
3219         // the status bar corner 
3221         // each band consists of 4 stripes: m_penHighlight, double 
3222         // m_penDarkGrey and transparent one 
3223         wxCoord x2 
= rect
.GetRight(), 
3224                 y2 
= rect
.GetBottom(); 
3226         // draw the upper left part of the rect normally 
3227         dc
.SetPen(m_penDarkGrey
); 
3228         dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
); 
3229         dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop()); 
3231         // draw the grey stripes of the grip 
3233         wxCoord ofs 
= WIDTH_STATUSBAR_GRIP_BAND 
- 1; 
3234         for ( n 
= 0; n 
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs 
+= WIDTH_STATUSBAR_GRIP_BAND 
) 
3236             dc
.DrawLine(x2 
- ofs 
+ 1, y2 
- 1, x2
, y2 
- ofs
); 
3237             dc
.DrawLine(x2 
- ofs
, y2 
- 1, x2
, y2 
- ofs 
- 1); 
3240         // draw the white stripes 
3241         dc
.SetPen(m_penHighlight
); 
3242         ofs 
= WIDTH_STATUSBAR_GRIP_BAND 
+ 1; 
3243         for ( n 
= 0; n 
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs 
+= WIDTH_STATUSBAR_GRIP_BAND 
) 
3245             dc
.DrawLine(x2 
- ofs 
+ 1, y2 
- 1, x2
, y2 
- ofs
); 
3248         // draw the remaining rect boundaries 
3249         ofs 
-= WIDTH_STATUSBAR_GRIP_BAND
; 
3250         dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2 
- ofs 
+ 1); 
3251         dc
.DrawLine(rect
.GetLeft(), y2
, x2 
- ofs 
+ 1, y2
); 
3256         rectIn
.width 
-= STATUSBAR_GRIP_SIZE
; 
3260         DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
); 
3263     rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
); 
3265     wxDCClipper 
clipper(dc
, rectIn
); 
3266     DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT 
| wxALIGN_CENTRE_VERTICAL
); 
3269 // ---------------------------------------------------------------------------- 
3271 // ---------------------------------------------------------------------------- 
3273 void wxWin32Renderer::GetComboBitmaps(wxBitmap 
*bmpNormal
, 
3275                                       wxBitmap 
*bmpPressed
, 
3276                                       wxBitmap 
*bmpDisabled
) 
3278     static const wxCoord widthCombo 
= 16; 
3279     static const wxCoord heightCombo 
= 17; 
3285         bmpNormal
->Create(widthCombo
, heightCombo
); 
3286         dcMem
.SelectObject(*bmpNormal
); 
3287         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
3288                         Arrow_Down
, Arrow_Normal
); 
3293         bmpPressed
->Create(widthCombo
, heightCombo
); 
3294         dcMem
.SelectObject(*bmpPressed
); 
3295         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
3296                         Arrow_Down
, Arrow_Pressed
); 
3301         bmpDisabled
->Create(widthCombo
, heightCombo
); 
3302         dcMem
.SelectObject(*bmpDisabled
); 
3303         DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
), 
3304                         Arrow_Down
, Arrow_Disabled
); 
3308 // ---------------------------------------------------------------------------- 
3310 // ---------------------------------------------------------------------------- 
3312 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
, 
3313                                        const wxColour
& col
, 
3317     wxBrush 
brush(col
, wxSOLID
); 
3319     dc
.SetPen(*wxTRANSPARENT_PEN
); 
3320     dc
.DrawRectangle(rect
); 
3323 void wxWin32Renderer::DrawBackground(wxDC
& dc
, 
3324                                      const wxColour
& col
, 
3329     // just fill it with the given or default bg colour 
3330     wxColour colBg 
= col
.Ok() ? col 
: wxSCHEME_COLOUR(m_scheme
, CONTROL
); 
3331     DoDrawBackground(dc
, colBg
, rect
, window 
); 
3334 // ---------------------------------------------------------------------------- 
3336 // ---------------------------------------------------------------------------- 
3338 void wxWin32Renderer::DrawArrow(wxDC
& dc
, 
3343     // get the bitmap for this arrow 
3344     wxArrowDirection arrowDir
; 
3347         case wxLEFT
:    arrowDir 
= Arrow_Left
; break; 
3348         case wxRIGHT
:   arrowDir 
= Arrow_Right
; break; 
3349         case wxUP
:      arrowDir 
= Arrow_Up
; break; 
3350         case wxDOWN
:    arrowDir 
= Arrow_Down
; break; 
3353             wxFAIL_MSG(_T("unknown arrow direction")); 
3357     wxArrowStyle arrowStyle
; 
3358     if ( flags 
& wxCONTROL_PRESSED 
) 
3360         // can't be pressed and disabled 
3361         arrowStyle 
= Arrow_Pressed
; 
3365         arrowStyle 
= flags 
& wxCONTROL_DISABLED 
? Arrow_Disabled 
: Arrow_Normal
; 
3368     DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
); 
3371 void wxWin32Renderer::DrawArrow(wxDC
& dc
, 
3373                                 wxArrowDirection arrowDir
, 
3374                                 wxArrowStyle arrowStyle
) 
3376     const wxBitmap
& bmp 
= m_bmpArrows
[arrowStyle
][arrowDir
]; 
3378     // under Windows the arrows always have the same size so just centre it in 
3379     // the provided rectangle 
3380     wxCoord x 
= rect
.x 
+ (rect
.width 
- bmp
.GetWidth()) / 2, 
3381             y 
= rect
.y 
+ (rect
.height 
- bmp
.GetHeight()) / 2; 
3383     // Windows does it like this... 
3384     if ( arrowDir 
== Arrow_Left 
) 
3388     dc
.DrawBitmap(bmp
, x
, y
, TRUE 
/* use mask */); 
3391 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
, 
3392                                       const wxRect
& rectAll
, 
3393                                       wxArrowDirection arrowDir
, 
3394                                       wxArrowStyle arrowStyle
) 
3396     wxRect rect 
= rectAll
; 
3397     DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
); 
3398     DrawArrowBorder(dc
, &rect
, arrowStyle 
== Arrow_Pressed
); 
3399     DrawArrow(dc
, rect
, arrowDir
, arrowStyle
); 
3402 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
, 
3403                                          wxOrientation orient
, 
3407     // we don't use the flags, the thumb never changes appearance 
3408     wxRect rectThumb 
= rect
; 
3409     DrawArrowBorder(dc
, &rectThumb
); 
3410     DrawBackground(dc
, wxNullColour
, rectThumb
); 
3413 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
, 
3414                                          wxOrientation orient
, 
3415                                          const wxRect
& rectBar
, 
3418     wxColourScheme::StdColour col 
= flags 
& wxCONTROL_PRESSED
 
3419                                     ? wxColourScheme::SCROLLBAR_PRESSED
 
3420                                     : wxColourScheme::SCROLLBAR
; 
3421     DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
); 
3424 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
) 
3426     DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
); 
3429 wxRect 
wxWin32Renderer::GetScrollbarRect(const wxScrollBar 
*scrollbar
, 
3430                                          wxScrollBar::Element elem
, 
3433     return StandardGetScrollbarRect(scrollbar
, elem
, 
3434                                     thumbPos
, m_sizeScrollbarArrow
); 
3437 wxCoord 
wxWin32Renderer::GetScrollbarSize(const wxScrollBar 
*scrollbar
) 
3439     return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
); 
3442 wxHitTest 
wxWin32Renderer::HitTestScrollbar(const wxScrollBar 
*scrollbar
, 
3443                                             const wxPoint
& pt
) const 
3445     return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
); 
3448 wxCoord 
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar 
*scrollbar
, 
3451     return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
); 
3454 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar 
*scrollbar
, 
3457     return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
); 
3460 // ---------------------------------------------------------------------------- 
3461 // top level windows 
3462 // ---------------------------------------------------------------------------- 
3464 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const 
3466     wxRect client 
= GetFrameClientArea(rect
, flags
); 
3468     if ( client
.Inside(pt
) ) 
3469         return wxHT_TOPLEVEL_CLIENT_AREA
; 
3471     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3473         wxRect client 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3475         if ( flags 
& wxTOPLEVEL_ICON 
) 
3477             if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) ) 
3478                 return wxHT_TOPLEVEL_ICON
; 
3481         wxRect 
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
, 
3482                        client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2, 
3483                        FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
); 
3485         if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
3487             if ( btnRect
.Inside(pt
) ) 
3488                 return wxHT_TOPLEVEL_BUTTON_CLOSE
; 
3489             btnRect
.x 
-= FRAME_BUTTON_WIDTH 
+ 2; 
3491         if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
3493             if ( btnRect
.Inside(pt
) ) 
3494                 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
; 
3495             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
3497         if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
3499             if ( btnRect
.Inside(pt
) ) 
3500                 return wxHT_TOPLEVEL_BUTTON_RESTORE
; 
3501             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
3503         if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
3505             if ( btnRect
.Inside(pt
) ) 
3506                 return wxHT_TOPLEVEL_BUTTON_ICONIZE
; 
3507             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
3509         if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
3511             if ( btnRect
.Inside(pt
) ) 
3512                 return wxHT_TOPLEVEL_BUTTON_HELP
; 
3513             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
3516         if ( pt
.y 
>= client
.y 
&& pt
.y 
< client
.y 
+ FRAME_TITLEBAR_HEIGHT 
) 
3517             return wxHT_TOPLEVEL_TITLEBAR
; 
3520     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3522         // we are certainly at one of borders, lets decide which one: 
3525         // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined! 
3526         if ( pt
.x 
< client
.x 
) 
3527             border 
|= wxHT_TOPLEVEL_BORDER_W
; 
3528         else if ( pt
.x 
>= client
.width 
+ client
.x 
) 
3529             border 
|= wxHT_TOPLEVEL_BORDER_E
; 
3530         if ( pt
.y 
< client
.y 
) 
3531             border 
|= wxHT_TOPLEVEL_BORDER_N
; 
3532         else if ( pt
.y 
>= client
.height 
+ client
.y 
) 
3533             border 
|= wxHT_TOPLEVEL_BORDER_S
; 
3537     return wxHT_NOWHERE
; 
3540 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
, 
3542                                         const wxString
& title
, 
3546                                         int specialButtonFlags
) 
3548     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3550         DrawFrameBorder(dc
, rect
, flags
); 
3552     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3554         DrawFrameBackground(dc
, rect
, flags
); 
3555         if ( flags 
& wxTOPLEVEL_ICON 
) 
3556             DrawFrameIcon(dc
, rect
, icon
, flags
); 
3557         DrawFrameTitle(dc
, rect
, title
, flags
); 
3559         wxRect client 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3561         x 
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
; 
3562         y 
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2; 
3564         if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
3566             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
, 
3567                             (specialButton 
== wxTOPLEVEL_BUTTON_CLOSE
) ? 
3568                             specialButtonFlags 
: 0); 
3569             x 
-= FRAME_BUTTON_WIDTH 
+ 2; 
3571         if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
3573             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
, 
3574                             (specialButton 
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ? 
3575                             specialButtonFlags 
: 0); 
3576             x 
-= FRAME_BUTTON_WIDTH
; 
3578         if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
3580             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
, 
3581                             (specialButton 
== wxTOPLEVEL_BUTTON_RESTORE
) ? 
3582                             specialButtonFlags 
: 0); 
3583             x 
-= FRAME_BUTTON_WIDTH
; 
3585         if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
3587             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
, 
3588                             (specialButton 
== wxTOPLEVEL_BUTTON_ICONIZE
) ? 
3589                             specialButtonFlags 
: 0); 
3590             x 
-= FRAME_BUTTON_WIDTH
; 
3592         if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
3594             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
, 
3595                             (specialButton 
== wxTOPLEVEL_BUTTON_HELP
) ? 
3596                             specialButtonFlags 
: 0); 
3597             x 
-= FRAME_BUTTON_WIDTH
; 
3602 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
, 
3606     if ( !(flags 
& wxTOPLEVEL_BORDER
) ) return; 
3610     DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
); 
3611     DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
); 
3612     DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
); 
3613     if ( flags 
& wxTOPLEVEL_RESIZEABLE 
) 
3614         DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
); 
3617 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
, 
3621     if ( !(flags 
& wxTOPLEVEL_TITLEBAR
) ) return; 
3623     wxColour col 
= (flags 
& wxTOPLEVEL_ACTIVE
) ? 
3624                    wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) : 
3625                    wxSCHEME_COLOUR(m_scheme
, TITLEBAR
); 
3627     wxRect r 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3628     r
.height 
= FRAME_TITLEBAR_HEIGHT
; 
3630     DrawBackground(dc
, col
, r
); 
3633 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
, 
3635                                      const wxString
& title
, 
3638     wxColour col 
= (flags 
& wxTOPLEVEL_ACTIVE
) ? 
3639                    wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) : 
3640                    wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
); 
3642     wxRect r 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3643     r
.height 
= FRAME_TITLEBAR_HEIGHT
; 
3644     if ( flags 
& wxTOPLEVEL_ICON 
) 
3646         r
.x 
+= FRAME_TITLEBAR_HEIGHT
; 
3647         r
.width 
-= FRAME_TITLEBAR_HEIGHT 
+ 2; 
3655     if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
3656         r
.width 
-= FRAME_BUTTON_WIDTH 
+ 2; 
3657     if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
3658         r
.width 
-= FRAME_BUTTON_WIDTH
; 
3659     if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
3660         r
.width 
-= FRAME_BUTTON_WIDTH
; 
3661     if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
3662         r
.width 
-= FRAME_BUTTON_WIDTH
; 
3663     if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
3664         r
.width 
-= FRAME_BUTTON_WIDTH
; 
3666     dc
.SetFont(m_titlebarFont
); 
3667     dc
.SetTextForeground(col
); 
3670     dc
.GetTextExtent(title
, &textW
, NULL
); 
3671     if ( textW 
> r
.width 
) 
3673         // text is too big, let's shorten it and add "..." after it: 
3674         size_t len 
= title
.length(); 
3675         wxCoord WSoFar
, letterW
; 
3677         dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
); 
3678         if ( WSoFar 
> r
.width 
) 
3680             // not enough space to draw anything 
3686         for (size_t i 
= 0; i 
< len
; i
++) 
3688             dc
.GetTextExtent(title
[i
], &letterW
, NULL
); 
3689             if ( letterW 
+ WSoFar 
> r
.width 
) 
3695         dc
.DrawLabel(s
, wxNullBitmap
, r
, 
3696                      wxALIGN_LEFT 
| wxALIGN_CENTRE_VERTICAL
); 
3699         dc
.DrawLabel(title
, wxNullBitmap
, r
, 
3700                      wxALIGN_LEFT 
| wxALIGN_CENTRE_VERTICAL
); 
3703 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
, 
3710         wxRect r 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
3711         dc
.DrawIcon(icon
, r
.x
, r
.y
); 
3715 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
, 
3716                                       wxCoord x
, wxCoord y
, 
3720     wxRect 
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
); 
3725         case wxTOPLEVEL_BUTTON_CLOSE
:    idx 
= FrameButton_Close
; break; 
3726         case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx 
= FrameButton_Maximize
; break; 
3727         case wxTOPLEVEL_BUTTON_ICONIZE
: idx 
= FrameButton_Minimize
; break; 
3728         case wxTOPLEVEL_BUTTON_RESTORE
:  idx 
= FrameButton_Restore
; break; 
3729         case wxTOPLEVEL_BUTTON_HELP
:     idx 
= FrameButton_Help
; break; 
3731             wxFAIL_MSG(wxT("incorrect button specification")); 
3734     if ( flags 
& wxCONTROL_PRESSED 
) 
3736         DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
); 
3737         DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
); 
3738         DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
); 
3739         dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
); 
3743         DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
); 
3744         DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
); 
3745         DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
); 
3746         dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
); 
3751 wxRect 
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
, 
3756     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3758         int border 
= (flags 
& wxTOPLEVEL_RESIZEABLE
) ? 
3759                         RESIZEABLE_FRAME_BORDER_THICKNESS 
: 
3760                         FRAME_BORDER_THICKNESS
; 
3763     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3765         r
.y 
+= FRAME_TITLEBAR_HEIGHT
; 
3766         r
.height 
-= FRAME_TITLEBAR_HEIGHT
; 
3772 wxSize 
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
, 
3775     wxSize 
s(clientSize
); 
3777     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3779         int border 
= (flags 
& wxTOPLEVEL_RESIZEABLE
) ? 
3780                         RESIZEABLE_FRAME_BORDER_THICKNESS 
: 
3781                         FRAME_BORDER_THICKNESS
; 
3785     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3786         s
.y 
+= FRAME_TITLEBAR_HEIGHT
; 
3791 wxSize 
wxWin32Renderer::GetFrameMinSize(int flags
) const 
3795     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
3797         int border 
= (flags 
& wxTOPLEVEL_RESIZEABLE
) ? 
3798                         RESIZEABLE_FRAME_BORDER_THICKNESS 
: 
3799                         FRAME_BORDER_THICKNESS
; 
3804     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
3806         s
.y 
+= FRAME_TITLEBAR_HEIGHT
; 
3808         if ( flags 
& wxTOPLEVEL_ICON 
) 
3809             s
.x 
+= FRAME_TITLEBAR_HEIGHT 
+ 2; 
3810         if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
3811             s
.x 
+= FRAME_BUTTON_WIDTH 
+ 2; 
3812         if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
3813             s
.x 
+= FRAME_BUTTON_WIDTH
; 
3814         if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
3815             s
.x 
+= FRAME_BUTTON_WIDTH
; 
3816         if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
3817             s
.x 
+= FRAME_BUTTON_WIDTH
; 
3818         if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
3819             s
.x 
+= FRAME_BUTTON_WIDTH
; 
3825 wxSize 
wxWin32Renderer::GetFrameIconSize() const 
3827     return wxSize(16, 16); 
3831 // ---------------------------------------------------------------------------- 
3833 // ---------------------------------------------------------------------------- 
3835 static char *error_xpm
[]={ 
3842 "...........########.............", 
3843 "........###aaaaaaaa###..........", 
3844 ".......#aaaaaaaaaaaaaa#.........", 
3845 ".....##aaaaaaaaaaaaaaaa##.......", 
3846 "....#aaaaaaaaaaaaaaaaaaaa#......", 
3847 "...#aaaaaaaaaaaaaaaaaaaaaa#.....", 
3848 "...#aaaaaaaaaaaaaaaaaaaaaa#b....", 
3849 "..#aaaaaacaaaaaaaaaacaaaaaa#b...", 
3850 ".#aaaaaacccaaaaaaaacccaaaaaa#...", 
3851 ".#aaaaacccccaaaaaacccccaaaaa#b..", 
3852 ".#aaaaaacccccaaaacccccaaaaaa#bb.", 
3853 "#aaaaaaaacccccaacccccaaaaaaaa#b.", 
3854 "#aaaaaaaaaccccccccccaaaaaaaaa#b.", 
3855 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb", 
3856 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb", 
3857 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb", 
3858 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb", 
3859 "#aaaaaaaaaccccccccccaaaaaaaaa#bb", 
3860 "#aaaaaaaacccccaacccccaaaaaaaa#bb", 
3861 ".#aaaaaacccccaaaacccccaaaaaa#bbb", 
3862 ".#aaaaacccccaaaaaacccccaaaaa#bbb", 
3863 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.", 
3864 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.", 
3865 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.", 
3866 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..", 
3867 "....#aaaaaaaaaaaaaaaaaaaa#bbb...", 
3868 ".....##aaaaaaaaaaaaaaaa##bbbb...", 
3869 "......b#aaaaaaaaaaaaaa#bbbbb....", 
3870 ".......b###aaaaaaaa###bbbbb.....", 
3871 ".........bb########bbbbbb.......", 
3872 "..........bbbbbbbbbbbbbb........", 
3873 ".............bbbbbbbb..........."}; 
3875 static char *info_xpm
[]={ 
3883 "...........########.............", 
3884 "........###abbbbbba###..........", 
3885 "......##abbbbbbbbbbbba##........", 
3886 ".....#abbbbbbbbbbbbbbbba#.......", 
3887 "....#bbbbbbbaccccabbbbbbbd......", 
3888 "...#bbbbbbbbccccccbbbbbbbbd.....", 
3889 "..#bbbbbbbbbccccccbbbbbbbbbd....", 
3890 ".#abbbbbbbbbaccccabbbbbbbbbad...", 
3891 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..", 
3892 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.", 
3893 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.", 
3894 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", 
3895 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", 
3896 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", 
3897 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", 
3898 "#abbbbbbbbbbbcccccbbbbbbbbbbad##", 
3899 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###", 
3900 ".#abbbbbbbbbbcccccbbbbbbbbbad###", 
3901 "..#bbbbbbbbcccccccccbbbbbbbd###.", 
3902 "...dbbbbbbbbbbbbbbbbbbbbbbd####.", 
3903 "....dbbbbbbbbbbbbbbbbbbbbd####..", 
3904 ".....dabbbbbbbbbbbbbbbbad####...", 
3905 "......ddabbbbbbbbbbbbadd####....", 
3906 ".......#dddabbbbbbaddd#####.....", 
3907 "........###dddabbbd#######......", 
3908 "..........####dbbbd#####........", 
3909 ".............#dbbbd##...........", 
3910 "...............dbbd##...........", 
3911 "................dbd##...........", 
3912 ".................dd##...........", 
3913 "..................###...........", 
3914 "...................##..........."}; 
3916 static char *question_xpm
[]={ 
3924 "...........########.............", 
3925 "........###abbbbbba###..........", 
3926 "......##abbbbbbbbbbbba##........", 
3927 ".....#abbbbbbbbbbbbbbbba#.......", 
3928 "....#bbbbbbbbbbbbbbbbbbbbc......", 
3929 "...#bbbbbbbaddddddabbbbbbbc.....", 
3930 "..#bbbbbbbadabbddddabbbbbbbc....", 
3931 ".#abbbbbbbddbbbbddddbbbbbbbac...", 
3932 ".#bbbbbbbbddddbbddddbbbbbbbbc#..", 
3933 "#abbbbbbbbddddbaddddbbbbbbbbac#.", 
3934 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.", 
3935 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##", 
3936 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##", 
3937 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##", 
3938 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##", 
3939 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##", 
3940 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###", 
3941 ".#abbbbbbbbbbddddbbbbbbbbbbac###", 
3942 "..#bbbbbbbbbbddddbbbbbbbbbbc###.", 
3943 "...cbbbbbbbbbaddabbbbbbbbbc####.", 
3944 "....cbbbbbbbbbbbbbbbbbbbbc####..", 
3945 ".....cabbbbbbbbbbbbbbbbac####...", 
3946 "......ccabbbbbbbbbbbbacc####....", 
3947 ".......#cccabbbbbbaccc#####.....", 
3948 "........###cccabbbc#######......", 
3949 "..........####cbbbc#####........", 
3950 ".............#cbbbc##...........", 
3951 "...............cbbc##...........", 
3952 "................cbc##...........", 
3953 ".................cc##...........", 
3954 "..................###...........", 
3955 "...................##..........."}; 
3957 static char *warning_xpm
[]={ 
3965 ".............###................", 
3966 "............#aabc...............", 
3967 "...........#aaaabcd.............", 
3968 "...........#aaaaacdd............", 
3969 "..........#aaaaaabcdd...........", 
3970 "..........#aaaaaaacdd...........", 
3971 ".........#aaaaaaaabcdd..........", 
3972 ".........#aaaaaaaaacdd..........", 
3973 "........#aaaaaaaaaabcdd.........", 
3974 "........#aaabcccbaaacdd.........", 
3975 ".......#aaaacccccaaabcdd........", 
3976 ".......#aaaacccccaaaacdd........", 
3977 "......#aaaaacccccaaaabcdd.......", 
3978 "......#aaaaacccccaaaaacdd.......", 
3979 ".....#aaaaaacccccaaaaabcdd......", 
3980 ".....#aaaaaa#ccc#aaaaaacdd......", 
3981 "....#aaaaaaabcccbaaaaaabcdd.....", 
3982 "....#aaaaaaaacccaaaaaaaacdd.....", 
3983 "...#aaaaaaaaa#c#aaaaaaaabcdd....", 
3984 "...#aaaaaaaaabcbaaaaaaaaacdd....", 
3985 "..#aaaaaaaaaaacaaaaaaaaaabcdd...", 
3986 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...", 
3987 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..", 
3988 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..", 
3989 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.", 
3990 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.", 
3991 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd", 
3992 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd", 
3993 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd", 
3994 "..#ccccccccccccccccccccccccddddd", 
3995 "....ddddddddddddddddddddddddddd.", 
3996 ".....ddddddddddddddddddddddddd.."}; 
3998 wxBitmap 
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
, 
3999                                           const wxArtClient
& WXUNUSED(client
), 
4000                                           const wxSize
& WXUNUSED(size
)) 
4002     if ( id 
== wxART_INFORMATION 
) 
4003         return wxBitmap(info_xpm
); 
4004     if ( id 
== wxART_ERROR 
) 
4005         return wxBitmap(error_xpm
); 
4006     if ( id 
== wxART_WARNING 
) 
4007         return wxBitmap(warning_xpm
); 
4008     if ( id 
== wxART_QUESTION 
) 
4009         return wxBitmap(question_xpm
); 
4010     return wxNullBitmap
; 
4014 // ---------------------------------------------------------------------------- 
4015 // text control geometry 
4016 // ---------------------------------------------------------------------------- 
4018 static inline int GetTextBorderWidth() 
4023 wxRect 
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl 
*text
, 
4024                                          const wxRect
& rect
) const 
4026     wxRect rectTotal 
= rect
; 
4028     wxCoord widthBorder 
= GetTextBorderWidth(); 
4029     rectTotal
.Inflate(widthBorder
); 
4031     // this is what Windows does 
4037 wxRect 
wxWin32Renderer::GetTextClientArea(const wxTextCtrl 
*text
, 
4039                                           wxCoord 
*extraSpaceBeyond
) const 
4041     wxRect rectText 
= rect
; 
4043     // undo GetTextTotalArea() 
4044     if ( rectText
.height 
> 0 ) 
4047     wxCoord widthBorder 
= GetTextBorderWidth(); 
4048     rectText
.Inflate(-widthBorder
); 
4050     if ( extraSpaceBeyond 
) 
4051         *extraSpaceBeyond 
= 0; 
4056 // ---------------------------------------------------------------------------- 
4058 // ---------------------------------------------------------------------------- 
4060 void wxWin32Renderer::AdjustSize(wxSize 
*size
, const wxWindow 
*window
) 
4063     if ( wxDynamicCast(window
, wxScrollBar
) ) 
4065         // we only set the width of vert scrollbars and height of the 
4067         if ( window
->GetWindowStyle() & wxSB_HORIZONTAL 
) 
4068             size
->y 
= m_sizeScrollbarArrow
.y
; 
4070             size
->x 
= m_sizeScrollbarArrow
.x
; 
4072         // skip border width adjustments, they don't make sense for us 
4075 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR 
4078     if ( wxDynamicCast(window
, wxButton
) ) 
4080         if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) ) 
4082             // TODO: don't harcode all this 
4083             size
->x 
+= 3*window
->GetCharWidth(); 
4085             wxCoord heightBtn 
= (11*(window
->GetCharHeight() + 8))/10; 
4086             if ( size
->y 
< heightBtn 
- 8 ) 
4087                 size
->y 
= heightBtn
; 
4092         // for compatibility with other ports, the buttons default size is never 
4093         // less than the standard one, but not when display not PDAs. 
4094         if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
) 
4096         if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) ) 
4098                         wxSize szDef 
= wxButton::GetDefaultSize(); 
4099                 if ( size
->x 
< szDef
.x 
) 
4104         // no border width adjustments for buttons 
4107 #endif // wxUSE_BUTTON 
4109     // take into account the border width 
4110     wxRect rectBorder 
= GetBorderDimensions(window
->GetBorder()); 
4111     size
->x 
+= rectBorder
.x 
+ rectBorder
.width
; 
4112     size
->y 
+= rectBorder
.y 
+ rectBorder
.height
; 
4115 // ============================================================================ 
4117 // ============================================================================ 
4119 // ---------------------------------------------------------------------------- 
4120 // wxWin32InputHandler 
4121 // ---------------------------------------------------------------------------- 
4123 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer 
*renderer
) 
4125     m_renderer 
= renderer
; 
4128 bool wxWin32InputHandler::HandleKey(wxInputConsumer 
*control
, 
4129                                     const wxKeyEvent
& event
, 
4135 bool wxWin32InputHandler::HandleMouse(wxInputConsumer 
*control
, 
4136                                       const wxMouseEvent
& event
) 
4138     // clicking on the control gives it focus 
4139     if ( event
.ButtonDown() ) 
4141         wxWindow 
*win 
= control
->GetInputWindow(); 
4143         if (( wxWindow::FindFocus() != control
->GetInputWindow() ) && 
4144             ( win
->AcceptsFocus() ) ) 
4155 // ---------------------------------------------------------------------------- 
4156 // wxWin32ScrollBarInputHandler 
4157 // ---------------------------------------------------------------------------- 
4159 wxWin32ScrollBarInputHandler:: 
4160 wxWin32ScrollBarInputHandler(wxWin32Renderer 
*renderer
, 
4161                              wxInputHandler 
*handler
) 
4162         : wxStdScrollBarInputHandler(renderer
, handler
) 
4164     m_scrollPaused 
= FALSE
; 
4168 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar 
*scrollbar
, 
4169                                                  const wxControlAction
& action
) 
4171     // stop if went beyond the position of the original click (this can only 
4172     // happen when we scroll by pages) 
4174     if ( action 
== wxACTION_SCROLL_PAGE_DOWN 
) 
4176         stop 
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
) 
4177                 != wxHT_SCROLLBAR_BAR_2
; 
4179     else if ( action 
== wxACTION_SCROLL_PAGE_UP 
) 
4181         stop 
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
) 
4182                 != wxHT_SCROLLBAR_BAR_1
; 
4187         StopScrolling(scrollbar
); 
4189         scrollbar
->Refresh(); 
4194     return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
); 
4197 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer 
*control
, 
4198                                                const wxMouseEvent
& event
) 
4200     // remember the current state 
4201     bool wasDraggingThumb 
= m_htLast 
== wxHT_SCROLLBAR_THUMB
; 
4203     // do process the message 
4204     bool rc 
= wxStdScrollBarInputHandler::HandleMouse(control
, event
); 
4206     // analyse the changes 
4207     if ( !wasDraggingThumb 
&& (m_htLast 
== wxHT_SCROLLBAR_THUMB
) ) 
4209         // we just started dragging the thumb, remember its initial position to 
4210         // be able to restore it if the drag is cancelled later 
4211         m_eventStartDrag 
= event
; 
4217 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer 
*control
, 
4218                                                    const wxMouseEvent
& event
) 
4220     // we don't highlight scrollbar elements, so there is no need to process 
4221     // mouse move events normally - only do it while mouse is captured (i.e. 
4222     // when we're dragging the thumb or pressing on something) 
4223     if ( !m_winCapture 
) 
4226     if ( event
.Entering() ) 
4228         // we're not interested in this at all 
4232     wxScrollBar 
*scrollbar 
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
); 
4234     if ( m_scrollPaused 
) 
4236         // check if the mouse returned to its original location 
4238         if ( event
.Leaving() ) 
4244         ht 
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition()); 
4245         if ( ht 
== m_htLast 
) 
4247             // yes it did, resume scrolling 
4248             m_scrollPaused 
= FALSE
; 
4249             if ( m_timerScroll 
) 
4251                 // we were scrolling by line/page, restart timer 
4252                 m_timerScroll
->Start(m_interval
); 
4254                 Press(scrollbar
, TRUE
); 
4256             else // we were dragging the thumb 
4258                 // restore its last location 
4259                 HandleThumbMove(scrollbar
, m_eventLastDrag
); 
4265     else // normal case, scrolling hasn't been paused 
4267         // if we're scrolling the scrollbar because the arrow or the shaft was 
4268         // pressed, check that the mouse stays on the same scrollbar element 
4271         // Always let thumb jump back if we leave the scrollbar 
4272         if ( event
.Moving() ) 
4274             ht 
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition()); 
4276         else // event.Leaving() 
4281         // Jump back only if we get far away from it 
4282         wxPoint pos 
= event
.GetPosition(); 
4283         if (scrollbar
->HasFlag( wxVERTICAL 
)) 
4285             if (pos
.x 
> -40 && pos
.x 
< scrollbar
->GetSize().x
+40) 
4290             if (pos
.y 
> -40 && pos
.y 
< scrollbar
->GetSize().y
+40) 
4293         ht 
= m_renderer
->HitTestScrollbar(scrollbar
, pos 
); 
4296         // if we're dragging the thumb and the mouse stays in the scrollbar, it 
4297         // is still ok - we only want to catch the case when the mouse leaves 
4298         // the scrollbar here 
4299         if ( m_htLast 
== wxHT_SCROLLBAR_THUMB 
&& ht 
!= wxHT_NOWHERE 
) 
4301             ht 
= wxHT_SCROLLBAR_THUMB
; 
4304         if ( ht 
!= m_htLast 
) 
4306             // what were we doing? 2 possibilities: either an arrow/shaft was 
4307             // pressed in which case we have a timer and so we just stop it or 
4308             // we were dragging the thumb 
4309             if ( m_timerScroll 
) 
4312                 m_interval 
= m_timerScroll
->GetInterval(); 
4313                 m_timerScroll
->Stop(); 
4314                 m_scrollPaused 
= TRUE
; 
4316                 // unpress the arrow 
4317                 Press(scrollbar
, FALSE
); 
4319             else // we were dragging the thumb 
4321                 // remember the current thumb position to be able to restore it 
4322                 // if the mouse returns to it later 
4323                 m_eventLastDrag 
= event
; 
4325                 // and restore the original position (before dragging) of the 
4327                 HandleThumbMove(scrollbar
, m_eventStartDrag
); 
4334     return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
); 
4337 // ---------------------------------------------------------------------------- 
4338 // wxWin32CheckboxInputHandler 
4339 // ---------------------------------------------------------------------------- 
4341 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer 
*control
, 
4342                                             const wxKeyEvent
& event
, 
4347         wxControlAction action
; 
4348         int keycode 
= event
.GetKeyCode(); 
4352                 action 
= wxACTION_CHECKBOX_TOGGLE
; 
4356             case WXK_NUMPAD_SUBTRACT
: 
4357                 action 
= wxACTION_CHECKBOX_CHECK
; 
4361             case WXK_NUMPAD_ADD
: 
4362             case WXK_NUMPAD_EQUAL
: 
4363                 action 
= wxACTION_CHECKBOX_CLEAR
; 
4369             control
->PerformAction(action
); 
4378 // ---------------------------------------------------------------------------- 
4379 // wxWin32TextCtrlInputHandler 
4380 // ---------------------------------------------------------------------------- 
4382 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer 
*control
, 
4383                                             const wxKeyEvent
& event
, 
4386     // handle only MSW-specific text bindings here, the others are handled in 
4390         int keycode 
= event
.GetKeyCode(); 
4392         wxControlAction action
; 
4393         if ( keycode 
== WXK_DELETE 
&& event
.ShiftDown() ) 
4395             action 
= wxACTION_TEXT_CUT
; 
4397         else if ( keycode 
== WXK_INSERT 
) 
4399             if ( event
.ControlDown() ) 
4400                 action 
= wxACTION_TEXT_COPY
; 
4401             else if ( event
.ShiftDown() ) 
4402                 action 
= wxACTION_TEXT_PASTE
; 
4405         if ( action 
!= wxACTION_NONE 
) 
4407             control
->PerformAction(action
); 
4413     return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
); 
4416 // ---------------------------------------------------------------------------- 
4417 // wxWin32StatusBarInputHandler 
4418 // ---------------------------------------------------------------------------- 
4420 wxWin32StatusBarInputHandler:: 
4421 wxWin32StatusBarInputHandler(wxInputHandler 
*handler
) 
4422     : wxStdInputHandler(handler
) 
4427 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow 
*statbar
, 
4428                                             const wxPoint
& pt
) const 
4430     if ( statbar
->HasFlag(wxST_SIZEGRIP
) && 
4431          statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) ) 
4434             parentTLW 
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
); 
4436         wxCHECK_MSG( parentTLW
, FALSE
, 
4437                      _T("the status bar should be a child of a TLW") ); 
4439         // a maximized window can't be resized anyhow 
4440         if ( !parentTLW
->IsMaximized() ) 
4442             // VZ: I think that the standard Windows behaviour is to only 
4443             //     show the resizing cursor when the mouse is on top of the 
4444             //     grip itself but apparently different Windows versions behave 
4445             //     differently (?) and it seems a better UI to allow resizing 
4446             //     the status bar even when the mouse is above the grip 
4447             wxSize sizeSbar 
= statbar
->GetSize(); 
4449             int diff 
= sizeSbar
.x 
- pt
.x
; 
4450             return diff 
>= 0 && diff 
< (wxCoord
)STATUSBAR_GRIP_SIZE
; 
4457 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer 
*consumer
, 
4458                                                const wxMouseEvent
& event
) 
4460     if ( event
.Button(1) ) 
4462         if ( event
.ButtonDown(1) ) 
4464             wxWindow 
*statbar 
= consumer
->GetInputWindow(); 
4466             if ( IsOnGrip(statbar
, event
.GetPosition()) ) 
4468                 wxTopLevelWindow 
*tlw 
= wxDynamicCast(statbar
->GetParent(), 
4472                     tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, 
4473                                        wxHT_TOPLEVEL_BORDER_SE
); 
4475                     statbar
->SetCursor(m_cursorOld
); 
4483     return wxStdInputHandler::HandleMouse(consumer
, event
); 
4486 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer 
*consumer
, 
4487                                                    const wxMouseEvent
& event
) 
4489     wxWindow 
*statbar 
= consumer
->GetInputWindow(); 
4491     bool isOnGrip 
= IsOnGrip(statbar
, event
.GetPosition()); 
4492     if ( isOnGrip 
!= m_isOnGrip 
) 
4494         m_isOnGrip 
= isOnGrip
; 
4497             m_cursorOld 
= statbar
->GetCursor(); 
4498             statbar
->SetCursor(wxCURSOR_SIZENWSE
); 
4502             statbar
->SetCursor(m_cursorOld
); 
4506     return wxStdInputHandler::HandleMouseMove(consumer
, event
); 
4509 // ---------------------------------------------------------------------------- 
4510 // wxWin32FrameInputHandler 
4511 // ---------------------------------------------------------------------------- 
4513 class wxWin32SystemMenuEvtHandler 
: public wxEvtHandler
 
4516     wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler 
*handler
); 
4518     void Attach(wxInputConsumer 
*consumer
); 
4522     DECLARE_EVENT_TABLE() 
4523     void OnSystemMenu(wxCommandEvent 
&event
); 
4524     void OnCloseFrame(wxCommandEvent 
&event
); 
4525     void OnClose(wxCloseEvent 
&event
); 
4527     wxWin32FrameInputHandler 
*m_inputHnd
; 
4528     wxTopLevelWindow         
*m_wnd
; 
4529     wxAcceleratorTable        m_oldAccelTable
; 
4532 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler( 
4533                                 wxWin32FrameInputHandler 
*handler
) 
4535     m_inputHnd 
= handler
; 
4539 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer 
*consumer
) 
4541     wxASSERT_MSG( m_wnd 
== NULL
, _T("can't attach the handler twice!") ); 
4543     m_wnd 
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
); 
4544     m_wnd
->PushEventHandler(this); 
4546     // VS: This code relies on using generic implementation of  
4547     //     wxAcceleratorTable in wxUniv! 
4548     wxAcceleratorTable table 
= *m_wnd
->GetAcceleratorTable(); 
4549     m_oldAccelTable 
= table
; 
4550     table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
)); 
4551     table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
)); 
4552     m_wnd
->SetAcceleratorTable(table
); 
4555 void wxWin32SystemMenuEvtHandler::Detach() 
4559         m_wnd
->SetAcceleratorTable(m_oldAccelTable
); 
4560         m_wnd
->RemoveEventHandler(this);  
4565 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
) 
4566     EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
) 
4567     EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
) 
4568     EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
) 
4571 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent 
&WXUNUSED(event
)) 
4573     int border 
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) && 
4574                   !m_wnd
->IsMaximized()) ? 
4575                       RESIZEABLE_FRAME_BORDER_THICKNESS 
: 
4576                       FRAME_BORDER_THICKNESS
; 
4577     wxPoint pt 
= m_wnd
->GetClientAreaOrigin(); 
4578     pt
.x 
= -pt
.x 
+ border
; 
4579     pt
.y 
= -pt
.y 
+ border 
+ FRAME_TITLEBAR_HEIGHT
; 
4581     wxAcceleratorTable table 
= *m_wnd
->GetAcceleratorTable(); 
4582     m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
); 
4583     m_inputHnd
->PopupSystemMenu(m_wnd
, pt
); 
4584     m_wnd
->SetAcceleratorTable(table
); 
4587 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent 
&WXUNUSED(event
)) 
4589     m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, 
4590                          wxTOPLEVEL_BUTTON_CLOSE
); 
4593 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent 
&event
) 
4600 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler 
*handler
) 
4601         : wxStdFrameInputHandler(handler
) 
4603     m_menuHandler 
= new wxWin32SystemMenuEvtHandler(this); 
4606 wxWin32FrameInputHandler::~wxWin32FrameInputHandler() 
4608     if ( m_menuHandler 
) 
4610         m_menuHandler
->Detach(); 
4611         delete m_menuHandler
; 
4615 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer 
*consumer
, 
4616                                            const wxMouseEvent
& event
) 
4618     if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() ) 
4620         wxTopLevelWindow 
*tlw 
= 
4621             wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
); 
4623         long hit 
= tlw
->HitTest(event
.GetPosition()); 
4625         if ( event
.LeftDClick() && hit 
== wxHT_TOPLEVEL_TITLEBAR 
) 
4627             tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, 
4628                                tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
 
4629                                                   : wxTOPLEVEL_BUTTON_MAXIMIZE
); 
4632         else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU 
) 
4634             if ( (event
.LeftDown() && hit 
== wxHT_TOPLEVEL_ICON
) || 
4635                  (event
.RightDown() &&  
4636                       (hit 
== wxHT_TOPLEVEL_TITLEBAR 
||  
4637                        hit 
== wxHT_TOPLEVEL_ICON
)) ) 
4639                 PopupSystemMenu(tlw
, event
.GetPosition()); 
4645     return wxStdFrameInputHandler::HandleMouse(consumer
, event
); 
4648 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow 
*window
,  
4649                                                const wxPoint
& pos
) const 
4651     wxMenu 
*menu 
= new wxMenu
; 
4653     if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX 
) 
4654         menu
->Append(wxID_RESTORE_FRAME 
, _("&Restore")); 
4655     menu
->Append(wxID_MOVE_FRAME 
, _("&Move")); 
4656     if ( window
->GetWindowStyle() & wxRESIZE_BORDER 
) 
4657         menu
->Append(wxID_RESIZE_FRAME 
, _("&Size")); 
4658     if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) ) 
4659         menu
->Append(wxID_ICONIZE_FRAME 
, _("Mi&nimize")); 
4660     if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX 
) 
4661         menu
->Append(wxID_MAXIMIZE_FRAME 
, _("Ma&ximize")); 
4662     menu
->AppendSeparator(); 
4663     menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4")); 
4665     if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX 
) 
4667         if ( window
->IsMaximized() ) 
4669             menu
->Enable(wxID_MAXIMIZE_FRAME
, FALSE
); 
4670             menu
->Enable(wxID_MOVE_FRAME
, FALSE
); 
4671             if ( window
->GetWindowStyle() & wxRESIZE_BORDER 
) 
4672                 menu
->Enable(wxID_RESIZE_FRAME
, FALSE
); 
4675             menu
->Enable(wxID_RESTORE_FRAME
, FALSE
); 
4678     window
->PopupMenu(menu
, pos
); 
4682 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer 
*consumer
,  
4685     if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU 
) 
4687         // always detach if active frame changed: 
4688         m_menuHandler
->Detach(); 
4692             m_menuHandler
->Attach(consumer
); 
4696     return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);