1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/renderer.cpp 
   3 // Purpose:     implementation of wxRendererNative for Windows 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org> 
   9 // License:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // for compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  28     #include "wx/string.h" 
  29     #include "wx/window.h" 
  31     #include "wx/settings.h" 
  34 #include "wx/splitter.h" 
  35 #include "wx/renderer.h" 
  36 #include "wx/msw/uxtheme.h" 
  37 #include "wx/msw/private.h" 
  39 // tmschema.h is in Win32 Platform SDK and might not be available with earlier 
  41 #ifndef CP_DROPDOWNBUTTON 
  42     #define BP_PUSHBUTTON      1 
  44     #define CBS_UNCHECKEDNORMAL 1 
  45     #define CBS_CHECKEDNORMAL   (CBS_UNCHECKEDNORMAL + 4) 
  46     #define CBS_MIXEDNORMAL     (CBS_CHECKEDNORMAL + 4) 
  51     #define PBS_DISABLED        4 
  52     #define PBS_DEFAULTED       5 
  54     #define CP_DROPDOWNBUTTON  1 
  58     #define CBXS_PRESSED       3 
  59     #define CBXS_DISABLED      4 
  66     #define HP_HEADERITEM       1 
  72     #define TMT_HEIGHT          2417 
  74     #define HP_HEADERSORTARROW  4 
  75     #define HSAS_SORTEDUP       1 
  76     #define HSAS_SORTEDDOWN     2 
  79 #if defined(__WXWINCE__) && !defined(DFCS_FLAT) 
  83 // ---------------------------------------------------------------------------- 
  84 // wxRendererMSW: wxRendererNative implementation for "old" Win32 systems 
  85 // ---------------------------------------------------------------------------- 
  87 class WXDLLEXPORT wxRendererMSW 
: public wxDelegateRendererNative
 
  92     static wxRendererNative
& Get(); 
  94     virtual void DrawComboBoxDropButton(wxWindow 
*win
, 
  99     virtual void DrawPushButton(wxWindow 
*win
, 
 105     DECLARE_NO_COPY_CLASS(wxRendererMSW
) 
 108 // ---------------------------------------------------------------------------- 
 109 // wxRendererXP: wxRendererNative implementation for Windows XP and later 
 110 // ---------------------------------------------------------------------------- 
 114 class WXDLLEXPORT wxRendererXP 
: public wxDelegateRendererNative
 
 117     wxRendererXP() : wxDelegateRendererNative(wxRendererMSW::Get()) { } 
 119     static wxRendererNative
& Get(); 
 121     virtual void DrawHeaderButton(wxWindow 
*win
, 
 125                                   wxHeaderSortIconType sortArrow 
= wxHDR_SORT_ICON_NONE
, 
 126                                   wxHeaderButtonParams
* params 
= NULL
); 
 127     virtual int GetHeaderButtonHeight(wxWindow 
*win
); 
 129     virtual void DrawTreeItemButton(wxWindow 
*win
, 
 133     virtual void DrawSplitterBorder(wxWindow 
*win
, 
 137     virtual void DrawSplitterSash(wxWindow 
*win
, 
 141                                   wxOrientation orient
, 
 143     virtual void DrawComboBoxDropButton(wxWindow 
*win
, 
 147     virtual void DrawCheckBox(wxWindow 
*win
, 
 152     virtual void DrawPushButton(wxWindow 
*win
, 
 157     virtual wxSplitterRenderParams 
GetSplitterParams(const wxWindow 
*win
); 
 159     DECLARE_NO_COPY_CLASS(wxRendererXP
) 
 162 #endif // wxUSE_UXTHEME 
 164 // ============================================================================ 
 165 // wxRendererNative and wxRendererMSW implementation 
 166 // ============================================================================ 
 169 wxRendererNative
& wxRendererNative::GetDefault() 
 172     wxUxThemeEngine 
*themeEngine 
= wxUxThemeEngine::Get(); 
 173     if ( themeEngine 
&& themeEngine
->IsAppThemed() ) 
 174         return wxRendererXP::Get(); 
 175 #endif // wxUSE_UXTHEME 
 177     return wxRendererMSW::Get(); 
 181 wxRendererNative
& wxRendererMSW::Get() 
 183     static wxRendererMSW s_rendererMSW
; 
 185     return s_rendererMSW
; 
 189 wxRendererMSW::DrawComboBoxDropButton(wxWindow 
* WXUNUSED(win
), 
 195     r
.left 
= rect
.GetLeft(); 
 196     r
.top 
= rect
.GetTop(); 
 197     r
.bottom 
= rect
.y 
+ rect
.height
; 
 198     r
.right 
= rect
.x 
+ rect
.width
; 
 200     int style 
= DFCS_SCROLLCOMBOBOX
; 
 201     if ( flags 
& wxCONTROL_DISABLED 
) 
 202         style 
|= DFCS_INACTIVE
; 
 203     if ( flags 
& wxCONTROL_PRESSED 
) 
 204         style 
|= DFCS_PUSHED 
| DFCS_FLAT
; 
 206     ::DrawFrameControl(GetHdcOf(dc
), &r
, DFC_SCROLL
, style
); 
 210 wxRendererMSW::DrawPushButton(wxWindow 
* WXUNUSED(win
), 
 212                               const wxRect
& rectOrig
, 
 215     wxRect 
rect(rectOrig
); 
 217     int style 
= DFCS_BUTTONPUSH
; 
 218     if ( flags 
& wxCONTROL_DISABLED 
) 
 219         style 
|= DFCS_INACTIVE
; 
 220     if ( flags 
& wxCONTROL_PRESSED 
) 
 221         style 
|= DFCS_PUSHED 
| DFCS_FLAT
; 
 222     if ( flags 
& wxCONTROL_ISDEFAULT 
) 
 224         // DrawFrameControl() doesn't seem to support default buttons so we 
 225         // have to draw the border ourselves 
 226         wxDCPenChanger 
pen(dc
, *wxBLACK_PEN
); 
 227         wxDCBrushChanger 
brush(dc
, *wxTRANSPARENT_BRUSH
); 
 228         dc
.DrawRectangle(rect
); 
 233     wxCopyRectToRECT(rect
, rc
); 
 235     ::DrawFrameControl(GetHdcOf(dc
), &rc
, DFC_BUTTON
, style
); 
 238 // ============================================================================ 
 239 // wxRendererXP implementation 
 240 // ============================================================================ 
 245 wxRendererNative
& wxRendererXP::Get() 
 247     static wxRendererXP s_rendererXP
; 
 252 // NOTE: There is no guarantee that the button drawn fills the entire rect (XP 
 253 // default theme, for example), so the caller should have cleared button's 
 254 // background before this call. This is quite likely a wxMSW-specific thing. 
 256 wxRendererXP::DrawComboBoxDropButton(wxWindow 
* win
, 
 261     wxUxThemeHandle 
hTheme(win
, L
"COMBOBOX"); 
 264         m_rendererNative
.DrawComboBoxDropButton(win
, dc
, rect
, flags
); 
 269     wxCopyRectToRECT(rect
, r
); 
 272     if ( flags 
& wxCONTROL_PRESSED 
) 
 273         state 
= CBXS_PRESSED
; 
 274     else if ( flags 
& wxCONTROL_CURRENT 
) 
 276     else if ( flags 
& wxCONTROL_DISABLED 
) 
 277         state 
= CBXS_DISABLED
; 
 281     wxUxThemeEngine::Get()->DrawThemeBackground
 
 294 wxRendererXP::DrawHeaderButton(wxWindow 
*win
, 
 298                                wxHeaderSortIconType sortArrow
, 
 299                                wxHeaderButtonParams
* params
) 
 301     wxUxThemeHandle 
hTheme(win
, L
"HEADER"); 
 304         m_rendererNative
.DrawHeaderButton(win
, dc
, rect
, flags
, sortArrow
, params
); 
 309     wxCopyRectToRECT(rect
, r
); 
 312     if ( flags 
& wxCONTROL_PRESSED 
) 
 314     else if ( flags 
& wxCONTROL_CURRENT 
) 
 318     wxUxThemeEngine::Get()->DrawThemeBackground
 
 328     // NOTE: Using the theme to draw HP_HEADERSORTARROW doesn't do anything. 
 329     // Why?  If this can be fixed then draw the sort arrows using the theme 
 330     // and then clear those flags before calling DrawHeaderButtonContents. 
 332     // Add any extras that are specified in flags and params 
 333     DrawHeaderButtonContents(win
, dc
, rect
, flags
, sortArrow
, params
); 
 338 wxRendererXP::GetHeaderButtonHeight(wxWindow 
*win
) 
 340     wxUxThemeHandle 
hTheme(win
, L
"HEADER"); 
 343         return m_rendererNative
.GetHeaderButtonHeight(win
); 
 349     hr 
= wxUxThemeEngine::Get()->GetThemeMetric( hTheme
, 
 363 wxRendererXP::DrawTreeItemButton(wxWindow 
*win
, 
 368     wxUxThemeHandle 
hTheme(win
, L
"TREEVIEW"); 
 371         m_rendererNative
.DrawTreeItemButton(win
, dc
, rect
, flags
); 
 376     wxCopyRectToRECT(rect
, r
); 
 378     int state 
= flags 
& wxCONTROL_EXPANDED 
? GLPS_OPENED 
: GLPS_CLOSED
; 
 379     wxUxThemeEngine::Get()->DrawThemeBackground
 
 391 wxRendererXP::DrawCheckBox(wxWindow 
*win
, 
 396     wxUxThemeHandle 
hTheme(win
, L
"BUTTON"); 
 399         m_rendererNative
.DrawCheckBox(win
, dc
, rect
, flags
); 
 404     wxCopyRectToRECT(rect
, r
); 
 407     if ( flags 
& wxCONTROL_CHECKED 
) 
 408         state 
= CBS_CHECKEDNORMAL
; 
 409     else if ( flags 
& wxCONTROL_UNDETERMINED 
) 
 410         state 
= CBS_MIXEDNORMAL
; 
 412         state 
= CBS_UNCHECKEDNORMAL
; 
 414     // CBS_XXX is followed by CBX_XXXGOT, then CBS_XXXPRESSED and DISABLED 
 415     if ( flags 
& wxCONTROL_CURRENT 
) 
 417     else if ( flags 
& wxCONTROL_PRESSED 
) 
 419     else if ( flags 
& wxCONTROL_DISABLED 
) 
 422     wxUxThemeEngine::Get()->DrawThemeBackground
 
 434 wxRendererXP::DrawPushButton(wxWindow 
* win
, 
 439     wxUxThemeHandle 
hTheme(win
, L
"BUTTON"); 
 442         m_rendererNative
.DrawPushButton(win
, dc
, rect
, flags
); 
 447     wxCopyRectToRECT(rect
, r
); 
 450     if ( flags 
& wxCONTROL_PRESSED 
) 
 452     else if ( flags 
& wxCONTROL_CURRENT 
) 
 454     else if ( flags 
& wxCONTROL_DISABLED 
) 
 455         state 
= PBS_DISABLED
; 
 456     else if ( flags 
& wxCONTROL_ISDEFAULT 
) 
 457         state 
= PBS_DEFAULTED
; 
 461     wxUxThemeEngine::Get()->DrawThemeBackground
 
 473 // ---------------------------------------------------------------------------- 
 475 // ---------------------------------------------------------------------------- 
 477 // the width of the sash: this is the same as used by Explorer... 
 478 static const wxCoord SASH_WIDTH 
= 4; 
 480 wxSplitterRenderParams
 
 481 wxRendererXP::GetSplitterParams(const wxWindow 
* win
) 
 483     if ( win
->HasFlag(wxSP_NO_XP_THEME
) ) 
 484         return m_rendererNative
.GetSplitterParams(win
); 
 486         return wxSplitterRenderParams(SASH_WIDTH
, 0, false); 
 490 wxRendererXP::DrawSplitterBorder(wxWindow 
* win
, 
 495     if ( win
->HasFlag(wxSP_NO_XP_THEME
) ) 
 497         m_rendererNative
.DrawSplitterBorder(win
, dc
, rect
, flags
); 
 502 wxRendererXP::DrawSplitterSash(wxWindow 
*win
, 
 506                                wxOrientation orient
, 
 509     if ( !win
->HasFlag(wxSP_NO_XP_THEME
) ) 
 511         dc
.SetPen(*wxTRANSPARENT_PEN
); 
 512         dc
.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE
))); 
 513         if ( orient 
== wxVERTICAL 
) 
 515             dc
.DrawRectangle(position
, 0, SASH_WIDTH
, size
.y
); 
 519             dc
.DrawRectangle(0, position
, size
.x
, SASH_WIDTH
); 
 525     m_rendererNative
.DrawSplitterSash(win
, dc
, size
, position
, orient
, flags
); 
 528 #endif // wxUSE_UXTHEME