]> git.saurik.com Git - wxWidgets.git/blame - src/msw/renderer.cpp
Define ACO_AUTOAPPEND for MinGW/Cygwin.
[wxWidgets.git] / src / msw / renderer.cpp
CommitLineData
9c7f49f5 1///////////////////////////////////////////////////////////////////////////////
90b903c2 2// Name: src/msw/renderer.cpp
38c4cb6a 3// Purpose: implementation of wxRendererNative for Windows
9c7f49f5
VZ
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 20.07.2003
7// RCS-ID: $Id$
8// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
526954c5 9// Licence: wxWindows licence
9c7f49f5
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// for compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#ifndef WX_PRECOMP
28 #include "wx/string.h"
85b657c7
VS
29 #include "wx/window.h"
30 #include "wx/dc.h"
9eddec69 31 #include "wx/settings.h"
9c7f49f5
VZ
32#endif //WX_PRECOMP
33
51c42fc5 34#include "wx/scopeguard.h"
3c2544bb 35#include "wx/splitter.h"
9c7f49f5 36#include "wx/renderer.h"
03f01e63 37#include "wx/msw/private.h"
4614c8e5 38#include "wx/msw/uxtheme.h"
8b97949e 39
7cf3223a
VZ
40// tmschema.h is in Win32 Platform SDK and might not be available with earlier
41// compilers
42#ifndef CP_DROPDOWNBUTTON
2209baae 43 #define BP_PUSHBUTTON 1
e4131985 44 #define BP_RADIOBUTTON 2
9f93b45e 45 #define BP_CHECKBOX 3
e4131985
KO
46 #define RBS_UNCHECKEDNORMAL 1
47 #define RBS_CHECKEDNORMAL (RBS_UNCHECKEDNORMAL + 4)
48 #define RBS_MIXEDNORMAL (RBS_CHECKEDNORMAL + 4)
9f93b45e
VZ
49 #define CBS_UNCHECKEDNORMAL 1
50 #define CBS_CHECKEDNORMAL (CBS_UNCHECKEDNORMAL + 4)
51 #define CBS_MIXEDNORMAL (CBS_CHECKEDNORMAL + 4)
52
2209baae
RR
53 #define PBS_NORMAL 1
54 #define PBS_HOT 2
55 #define PBS_PRESSED 3
56 #define PBS_DISABLED 4
57 #define PBS_DEFAULTED 5
58
7cf3223a
VZ
59 #define CP_DROPDOWNBUTTON 1
60
61 #define CBXS_NORMAL 1
62 #define CBXS_HOT 2
63 #define CBXS_PRESSED 3
64 #define CBXS_DISABLED 4
a9d9e2f2 65
9f93b45e
VZ
66 #define TVP_GLYPH 2
67
68 #define GLPS_CLOSED 1
a9d9e2f2
JS
69 #define GLPS_OPENED 2
70
71 #define HP_HEADERITEM 1
72
73 #define HIS_NORMAL 1
74 #define HIS_HOT 2
75 #define HIS_PRESSED 3
4b94ddc4
RD
76
77 #define TMT_HEIGHT 2417
78
79 #define HP_HEADERSORTARROW 4
80 #define HSAS_SORTEDUP 1
81 #define HSAS_SORTEDDOWN 2
e4131985
KO
82
83 #define EP_EDITTEXT 1
84 #define ETS_NORMAL 1
85 #define ETS_HOT 2
86 #define ETS_SELECTED 3
87 #define ETS_DISABLED 4
88 #define ETS_FOCUSED 5
89 #define ETS_READONLY 6
90 #define ETS_ASSIST 7
91 #define TMT_FILLCOLOR 3802
92 #define TMT_TEXTCOLOR 3803
93 #define TMT_BORDERCOLOR 3801
94 #define TMT_EDGEFILLCOLOR 3808
b50d93d1
VZ
95
96 #define WP_MINBUTTON 15
97 #define WP_MAXBUTTON 17
98 #define WP_CLOSEBUTTON 18
99 #define WP_RESTOREBUTTON 21
100 #define WP_HELPBUTTON 23
7cf3223a
VZ
101#endif
102
d6f2a891
VZ
103#if defined(__WXWINCE__)
104 #ifndef DFCS_FLAT
105 #define DFCS_FLAT 0
106 #endif
107 #ifndef DFCS_MONO
108 #define DFCS_MONO 0
109 #endif
9f93b45e
VZ
110#endif
111
59ee63e9
VZ
112#ifndef DFCS_HOT
113 #define DFCS_HOT 0x1000
114#endif
115
de4bf0b3
FM
116// ----------------------------------------------------------------------------
117// methods common to wxRendererMSW and wxRendererXP
118// ----------------------------------------------------------------------------
119
120class wxRendererMSWBase : public wxDelegateRendererNative
121{
122public:
123 wxRendererMSWBase() { }
124 wxRendererMSWBase(wxRendererNative& rendererNative)
125 : wxDelegateRendererNative(rendererNative) { }
126
127 void DrawFocusRect(wxWindow * win,
128 wxDC& dc,
129 const wxRect& rect,
130 int flags = 0);
131
132 void DrawItemSelectionRect(wxWindow *win,
133 wxDC& dc,
134 const wxRect& rect,
135 int flags = 0);
136};
137
9c7f49f5 138// ----------------------------------------------------------------------------
8b97949e 139// wxRendererMSW: wxRendererNative implementation for "old" Win32 systems
9c7f49f5
VZ
140// ----------------------------------------------------------------------------
141
5aac6f3f 142class wxRendererMSW : public wxRendererMSWBase
9c7f49f5 143{
2eb10e2a
VZ
144public:
145 wxRendererMSW() { }
146
8b97949e
VZ
147 static wxRendererNative& Get();
148
7402677a
VZ
149 virtual void DrawComboBoxDropButton(wxWindow *win,
150 wxDC& dc,
151 const wxRect& rect,
152 int flags = 0);
153
59ee63e9
VZ
154 virtual void DrawCheckBox(wxWindow *win,
155 wxDC& dc,
156 const wxRect& rect,
081b3342
VZ
157 int flags = 0)
158 {
159 DoDrawButton(DFCS_BUTTONCHECK, win, dc, rect, flags);
160 }
59ee63e9 161
2209baae
RR
162 virtual void DrawPushButton(wxWindow *win,
163 wxDC& dc,
164 const wxRect& rect,
165 int flags = 0);
166
7280c828
VZ
167 virtual void DrawChoice(wxWindow* win,
168 wxDC& dc,
169 const wxRect& rect,
081b3342 170 int flags = 0);
e4131985 171
7280c828 172 virtual void DrawComboBox(wxWindow* win,
081b3342
VZ
173 wxDC& dc,
174 const wxRect& rect,
175 int flags = 0);
e4131985 176
7280c828 177 virtual void DrawTextCtrl(wxWindow* win,
081b3342
VZ
178 wxDC& dc,
179 const wxRect& rect,
180 int flags = 0);
e4131985 181
6e6b532c 182 virtual void DrawRadioBitmap(wxWindow* win,
081b3342
VZ
183 wxDC& dc,
184 const wxRect& rect,
185 int flags = 0)
186 {
187 DoDrawButton(DFCS_BUTTONRADIO, win, dc, rect, flags);
188 }
e4131985 189
b50d93d1
VZ
190 virtual void DrawTitleBarBitmap(wxWindow *win,
191 wxDC& dc,
192 const wxRect& rect,
193 wxTitleBarButton button,
194 int flags = 0);
195
191e43fd 196 virtual wxSize GetCheckBoxSize(wxWindow *win);
e8759560 197
51c42fc5
VZ
198 virtual int GetHeaderButtonHeight(wxWindow *win);
199
9aebcb5e
VS
200 virtual int GetHeaderButtonMargin(wxWindow *win);
201
2eb10e2a 202private:
b50d93d1
VZ
203 // wrapper of DrawFrameControl()
204 void DoDrawFrameControl(UINT type,
205 UINT kind,
206 wxWindow *win,
207 wxDC& dc,
208 const wxRect& rect,
209 int flags);
210
081b3342
VZ
211 // common part of Draw{PushButton,CheckBox,RadioBitmap}(): wraps
212 // DrawFrameControl(DFC_BUTTON)
213 void DoDrawButton(UINT kind,
214 wxWindow *win,
215 wxDC& dc,
216 const wxRect& rect,
b50d93d1
VZ
217 int flags)
218 {
219 DoDrawFrameControl(DFC_BUTTON, kind, win, dc, rect, flags);
220 }
081b3342 221
c0c133e1 222 wxDECLARE_NO_COPY_CLASS(wxRendererMSW);
9c7f49f5
VZ
223};
224
8b97949e
VZ
225// ----------------------------------------------------------------------------
226// wxRendererXP: wxRendererNative implementation for Windows XP and later
227// ----------------------------------------------------------------------------
228
7cf3223a
VZ
229#if wxUSE_UXTHEME
230
5aac6f3f 231class wxRendererXP : public wxRendererMSWBase
8b97949e
VZ
232{
233public:
de4bf0b3 234 wxRendererXP() : wxRendererMSWBase(wxRendererMSW::Get()) { }
8b97949e
VZ
235
236 static wxRendererNative& Get();
237
c97c9952 238 virtual int DrawHeaderButton(wxWindow *win,
4b94ddc4
RD
239 wxDC& dc,
240 const wxRect& rect,
241 int flags = 0,
80752b57 242 wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE,
4b94ddc4 243 wxHeaderButtonParams* params = NULL);
f4322df6 244
9f93b45e
VZ
245 virtual void DrawTreeItemButton(wxWindow *win,
246 wxDC& dc,
247 const wxRect& rect,
248 int flags = 0);
8b97949e
VZ
249 virtual void DrawSplitterBorder(wxWindow *win,
250 wxDC& dc,
c4e6c15e
VZ
251 const wxRect& rect,
252 int flags = 0);
8b97949e
VZ
253 virtual void DrawSplitterSash(wxWindow *win,
254 wxDC& dc,
255 const wxSize& size,
256 wxCoord position,
c4e6c15e
VZ
257 wxOrientation orient,
258 int flags = 0);
7cf3223a
VZ
259 virtual void DrawComboBoxDropButton(wxWindow *win,
260 wxDC& dc,
261 const wxRect& rect,
262 int flags = 0);
90b903c2
WS
263 virtual void DrawCheckBox(wxWindow *win,
264 wxDC& dc,
265 const wxRect& rect,
6c9aaf7d
VZ
266 int flags = 0)
267 {
268 if ( !DoDrawXPButton(BP_CHECKBOX, win, dc, rect, flags) )
269 m_rendererNative.DrawCheckBox(win, dc, rect, flags);
270 }
9f93b45e 271
2209baae
RR
272 virtual void DrawPushButton(wxWindow *win,
273 wxDC& dc,
274 const wxRect& rect,
6c9aaf7d
VZ
275 int flags = 0)
276 {
277 if ( !DoDrawXPButton(BP_PUSHBUTTON, win, dc, rect, flags) )
278 m_rendererNative.DrawPushButton(win, dc, rect, flags);
279 }
2209baae 280
081b3342
VZ
281 virtual void DrawRadioBitmap(wxWindow *win,
282 wxDC& dc,
283 const wxRect& rect,
6c9aaf7d
VZ
284 int flags = 0)
285 {
286 if ( !DoDrawXPButton(BP_RADIOBUTTON, win, dc, rect, flags) )
287 m_rendererNative.DrawRadioBitmap(win, dc, rect, flags);
288 }
081b3342 289
b50d93d1
VZ
290 virtual void DrawTitleBarBitmap(wxWindow *win,
291 wxDC& dc,
292 const wxRect& rect,
293 wxTitleBarButton button,
294 int flags = 0);
295
9f93b45e 296 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
081b3342 297
8b97949e 298private:
b50d93d1
VZ
299 // wrapper around DrawThemeBackground() translating flags to NORMAL/HOT/
300 // PUSHED/DISABLED states (and so suitable for drawing anything
301 // button-like)
302 void DoDrawButtonLike(HTHEME htheme,
303 int part,
304 wxDC& dc,
305 const wxRect& rect,
306 int flags);
307
6c9aaf7d
VZ
308 // common part of DrawCheckBox(), DrawPushButton() and DrawRadioBitmap()
309 bool DoDrawXPButton(int kind,
310 wxWindow *win,
311 wxDC& dc,
312 const wxRect& rect,
313 int flags);
314
c0c133e1 315 wxDECLARE_NO_COPY_CLASS(wxRendererXP);
8b97949e
VZ
316};
317
7cf3223a
VZ
318#endif // wxUSE_UXTHEME
319
de4bf0b3
FM
320
321// ============================================================================
322// wxRendererMSWBase implementation
323// ============================================================================
324
325void wxRendererMSWBase::DrawFocusRect(wxWindow * WXUNUSED(win),
326 wxDC& dc,
327 const wxRect& rect,
328 int WXUNUSED(flags))
329{
330 RECT rc;
331 wxCopyRectToRECT(rect, rc);
332
942d5e2d 333 ::DrawFocusRect(GetHdcOf(dc.GetTempHDC()), &rc);
de4bf0b3
FM
334}
335
336void wxRendererMSWBase::DrawItemSelectionRect(wxWindow *win,
337 wxDC& dc,
338 const wxRect& rect,
339 int flags)
340{
341 wxBrush brush;
342 if ( flags & wxCONTROL_SELECTED )
343 {
344 if ( flags & wxCONTROL_FOCUSED )
345 {
346 brush = wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
347 }
348 else // !focused
349 {
350 brush = wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
351 }
352 }
353 else // !selected
354 {
355 brush = *wxTRANSPARENT_BRUSH;
356 }
357
358 dc.SetBrush(brush);
359 dc.SetPen(*wxTRANSPARENT_PEN);
360 dc.DrawRectangle( rect );
361
362 if ((flags & wxCONTROL_FOCUSED) && (flags & wxCONTROL_CURRENT))
363 DrawFocusRect( win, dc, rect, flags );
364}
365
366
9c7f49f5 367// ============================================================================
8b97949e 368// wxRendererNative and wxRendererMSW implementation
9c7f49f5
VZ
369// ============================================================================
370
371/* static */
f0244295 372wxRendererNative& wxRendererNative::GetDefault()
8b97949e 373{
7cf3223a 374#if wxUSE_UXTHEME
8b97949e 375 wxUxThemeEngine *themeEngine = wxUxThemeEngine::Get();
7cf3223a
VZ
376 if ( themeEngine && themeEngine->IsAppThemed() )
377 return wxRendererXP::Get();
378#endif // wxUSE_UXTHEME
379
380 return wxRendererMSW::Get();
8b97949e
VZ
381}
382
383/* static */
384wxRendererNative& wxRendererMSW::Get()
9c7f49f5
VZ
385{
386 static wxRendererMSW s_rendererMSW;
387
388 return s_rendererMSW;
389}
390
7402677a
VZ
391void
392wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win),
393 wxDC& dc,
394 const wxRect& rect,
395 int flags)
396{
397 RECT r;
46bd1978 398 wxCopyRectToRECT(rect, r);
7402677a
VZ
399
400 int style = DFCS_SCROLLCOMBOBOX;
401 if ( flags & wxCONTROL_DISABLED )
402 style |= DFCS_INACTIVE;
403 if ( flags & wxCONTROL_PRESSED )
7cf3223a 404 style |= DFCS_PUSHED | DFCS_FLAT;
7402677a 405
942d5e2d 406 ::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, DFC_SCROLL, style);
7402677a
VZ
407}
408
59ee63e9 409void
b50d93d1
VZ
410wxRendererMSW::DoDrawFrameControl(UINT type,
411 UINT kind,
412 wxWindow * WXUNUSED(win),
413 wxDC& dc,
414 const wxRect& rect,
415 int flags)
59ee63e9
VZ
416{
417 RECT r;
418 wxCopyRectToRECT(rect, r);
419
081b3342 420 int style = kind;
59ee63e9
VZ
421 if ( flags & wxCONTROL_CHECKED )
422 style |= DFCS_CHECKED;
423 if ( flags & wxCONTROL_DISABLED )
424 style |= DFCS_INACTIVE;
8a461249
VZ
425 if ( flags & wxCONTROL_FLAT )
426 style |= DFCS_MONO;
59ee63e9
VZ
427 if ( flags & wxCONTROL_PRESSED )
428 style |= DFCS_PUSHED;
429 if ( flags & wxCONTROL_CURRENT )
430 style |= DFCS_HOT;
431
b50d93d1 432 ::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, type, style);
59ee63e9
VZ
433}
434
2209baae 435void
081b3342 436wxRendererMSW::DrawPushButton(wxWindow *win,
2209baae 437 wxDC& dc,
f2ea4255 438 const wxRect& rectOrig,
2209baae
RR
439 int flags)
440{
f2ea4255 441 wxRect rect(rectOrig);
f2ea4255
VZ
442 if ( flags & wxCONTROL_ISDEFAULT )
443 {
444 // DrawFrameControl() doesn't seem to support default buttons so we
445 // have to draw the border ourselves
446 wxDCPenChanger pen(dc, *wxBLACK_PEN);
447 wxDCBrushChanger brush(dc, *wxTRANSPARENT_BRUSH);
448 dc.DrawRectangle(rect);
844b9f5f 449 rect.Deflate(1);
f2ea4255
VZ
450 }
451
081b3342 452 DoDrawButton(DFCS_BUTTONPUSH, win, dc, rect, flags);
2209baae
RR
453}
454
b50d93d1
VZ
455void
456wxRendererMSW::DrawTitleBarBitmap(wxWindow *win,
457 wxDC& dc,
458 const wxRect& rect,
459 wxTitleBarButton button,
460 int flags)
461{
462 UINT kind;
463 switch ( button )
464 {
465 case wxTITLEBAR_BUTTON_CLOSE:
466 kind = DFCS_CAPTIONCLOSE;
467 break;
468
469 case wxTITLEBAR_BUTTON_MAXIMIZE:
470 kind = DFCS_CAPTIONMAX;
471 break;
472
473 case wxTITLEBAR_BUTTON_ICONIZE:
474 kind = DFCS_CAPTIONMIN;
475 break;
476
477 case wxTITLEBAR_BUTTON_RESTORE:
478 kind = DFCS_CAPTIONRESTORE;
479 break;
480
481 case wxTITLEBAR_BUTTON_HELP:
482 kind = DFCS_CAPTIONHELP;
483 break;
484
485 default:
486 wxFAIL_MSG( "unsupported title bar button" );
487 return;
488 }
489
490 DoDrawFrameControl(DFC_CAPTION, kind, win, dc, rect, flags);
491}
492
191e43fd 493wxSize wxRendererMSW::GetCheckBoxSize(wxWindow * WXUNUSED(win))
e8759560
VZ
494{
495 return wxSize(::GetSystemMetrics(SM_CXMENUCHECK),
496 ::GetSystemMetrics(SM_CYMENUCHECK));
497}
498
51c42fc5
VZ
499int wxRendererMSW::GetHeaderButtonHeight(wxWindow * WXUNUSED(win))
500{
501 // some "reasonable" value returned in case of error, it doesn't really
502 // correspond to anything but it's better than returning 0
503 static const int DEFAULT_HEIGHT = 20;
504
505
506 // create a temporary header window just to get its geometry
a268f4b7 507 HWND hwndHeader = ::CreateWindow(WC_HEADER, NULL, 0,
51c42fc5
VZ
508 0, 0, 0, 0, NULL, NULL, NULL, NULL);
509 if ( !hwndHeader )
510 return DEFAULT_HEIGHT;
511
512 wxON_BLOCK_EXIT1( ::DestroyWindow, hwndHeader );
513
514 // initialize the struct filled with the values by Header_Layout()
515 RECT parentRect = { 0, 0, 100, 100 };
11fa6e63 516 WINDOWPOS wp = { 0, 0, 0, 0, 0, 0, 0 };
51c42fc5
VZ
517 HDLAYOUT hdl = { &parentRect, &wp };
518
519 return Header_Layout(hwndHeader, &hdl) ? wp.cy : DEFAULT_HEIGHT;
520}
521
9aebcb5e
VS
522int wxRendererMSW::GetHeaderButtonMargin(wxWindow *WXUNUSED(win))
523{
524 return 10;
525}
526
e4131985
KO
527// Uses the theme to draw the border and fill for something like a wxTextCtrl
528void wxRendererMSW::DrawTextCtrl(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
529{
530 wxColour fill;
531 wxColour bdr;
532 COLORREF cref;
7280c828 533
e4131985
KO
534#if wxUSE_UXTHEME
535 wxUxThemeHandle hTheme(win, L"EDIT");
536 if (hTheme)
537 {
538 wxUxThemeEngine::Get()->GetThemeColor(hTheme, EP_EDITTEXT,
539 ETS_NORMAL, TMT_FILLCOLOR, &cref);
540 fill = wxRGBToColour(cref);
541
542 int etsState;
543 if ( flags & wxCONTROL_DISABLED )
544 etsState = ETS_DISABLED;
545 else
546 etsState = ETS_NORMAL;
7280c828 547
e4131985
KO
548 wxUxThemeEngine::Get()->GetThemeColor(hTheme, EP_EDITTEXT,
549 etsState, TMT_BORDERCOLOR, &cref);
7280c828 550 bdr = wxRGBToColour(cref);
e4131985
KO
551 }
552 else
553#endif
554 {
555 fill = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
556 bdr = *wxBLACK;
557 }
7280c828 558
e4131985
KO
559 dc.SetPen( bdr );
560 dc.SetBrush( fill );
561 dc.DrawRectangle(rect);
562}
563
564
081b3342 565// Draw the equivalent of a wxComboBox
e4131985
KO
566void wxRendererMSW::DrawComboBox(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
567{
568 // Draw the main part of the control same as TextCtrl
7280c828
VZ
569 DrawTextCtrl(win, dc, rect, flags);
570
e4131985
KO
571 // Draw the button inside the border, on the right side
572 wxRect br(rect);
573 br.height -= 2;
574 br.x += br.width - br.height - 1;
575 br.width = br.height;
576 br.y += 1;
577
578 DrawComboBoxDropButton(win, dc, br, flags);
579}
580
581
582void wxRendererMSW::DrawChoice(wxWindow* win, wxDC& dc,
583 const wxRect& rect, int flags)
584{
585 DrawComboBox(win, dc, rect, flags);
586}
587
8b97949e
VZ
588// ============================================================================
589// wxRendererXP implementation
590// ============================================================================
591
7cf3223a
VZ
592#if wxUSE_UXTHEME
593
8b97949e
VZ
594/* static */
595wxRendererNative& wxRendererXP::Get()
596{
597 static wxRendererXP s_rendererXP;
598
599 return s_rendererXP;
600}
601
7cf3223a
VZ
602// NOTE: There is no guarantee that the button drawn fills the entire rect (XP
603// default theme, for example), so the caller should have cleared button's
604// background before this call. This is quite likely a wxMSW-specific thing.
605void
606wxRendererXP::DrawComboBoxDropButton(wxWindow * win,
607 wxDC& dc,
608 const wxRect& rect,
609 int flags)
610{
611 wxUxThemeHandle hTheme(win, L"COMBOBOX");
9f93b45e 612 if ( !hTheme )
7cf3223a 613 {
9f93b45e
VZ
614 m_rendererNative.DrawComboBoxDropButton(win, dc, rect, flags);
615 return;
616 }
617
618 RECT r;
619 wxCopyRectToRECT(rect, r);
7cf3223a 620
9f93b45e
VZ
621 int state;
622 if ( flags & wxCONTROL_PRESSED )
623 state = CBXS_PRESSED;
624 else if ( flags & wxCONTROL_CURRENT )
625 state = CBXS_HOT;
626 else if ( flags & wxCONTROL_DISABLED )
627 state = CBXS_DISABLED;
628 else
629 state = CBXS_NORMAL;
630
631 wxUxThemeEngine::Get()->DrawThemeBackground
632 (
633 hTheme,
942d5e2d 634 GetHdcOf(dc.GetTempHDC()),
9f93b45e
VZ
635 CP_DROPDOWNBUTTON,
636 state,
637 &r,
638 NULL
639 );
640
641}
642
c97c9952 643int
9f93b45e
VZ
644wxRendererXP::DrawHeaderButton(wxWindow *win,
645 wxDC& dc,
646 const wxRect& rect,
4b94ddc4 647 int flags,
80752b57 648 wxHeaderSortIconType sortArrow,
4b94ddc4 649 wxHeaderButtonParams* params)
9f93b45e
VZ
650{
651 wxUxThemeHandle hTheme(win, L"HEADER");
652 if ( !hTheme )
653 {
c97c9952 654 return m_rendererNative.DrawHeaderButton(win, dc, rect, flags, sortArrow, params);
7cf3223a 655 }
9f93b45e
VZ
656
657 RECT r;
658 wxCopyRectToRECT(rect, r);
659
660 int state;
661 if ( flags & wxCONTROL_PRESSED )
662 state = HIS_PRESSED;
663 else if ( flags & wxCONTROL_CURRENT )
664 state = HIS_HOT;
665 else
666 state = HIS_NORMAL;
667 wxUxThemeEngine::Get()->DrawThemeBackground
668 (
669 hTheme,
942d5e2d 670 GetHdcOf(dc.GetTempHDC()),
9f93b45e
VZ
671 HP_HEADERITEM,
672 state,
673 &r,
674 NULL
675 );
4b94ddc4
RD
676
677 // NOTE: Using the theme to draw HP_HEADERSORTARROW doesn't do anything.
678 // Why? If this can be fixed then draw the sort arrows using the theme
679 // and then clear those flags before calling DrawHeaderButtonContents.
f4322df6 680
4b94ddc4 681 // Add any extras that are specified in flags and params
c97c9952 682 return DrawHeaderButtonContents(win, dc, rect, flags, sortArrow, params);
9f93b45e
VZ
683}
684
4b94ddc4 685
9f93b45e
VZ
686void
687wxRendererXP::DrawTreeItemButton(wxWindow *win,
688 wxDC& dc,
689 const wxRect& rect,
690 int flags)
691{
692 wxUxThemeHandle hTheme(win, L"TREEVIEW");
693 if ( !hTheme )
694 {
695 m_rendererNative.DrawTreeItemButton(win, dc, rect, flags);
696 return;
697 }
698
699 RECT r;
700 wxCopyRectToRECT(rect, r);
701
702 int state = flags & wxCONTROL_EXPANDED ? GLPS_OPENED : GLPS_CLOSED;
703 wxUxThemeEngine::Get()->DrawThemeBackground
704 (
705 hTheme,
942d5e2d 706 GetHdcOf(dc.GetTempHDC()),
9f93b45e
VZ
707 TVP_GLYPH,
708 state,
709 &r,
710 NULL
711 );
712}
713
6c9aaf7d
VZ
714bool
715wxRendererXP::DoDrawXPButton(int kind,
716 wxWindow *win,
717 wxDC& dc,
718 const wxRect& rect,
719 int flags)
9f93b45e
VZ
720{
721 wxUxThemeHandle hTheme(win, L"BUTTON");
722 if ( !hTheme )
6c9aaf7d 723 return false;
9f93b45e 724
b50d93d1 725 DoDrawButtonLike(hTheme, kind, dc, rect, flags);
59ee63e9 726
b50d93d1
VZ
727 return true;
728}
9f93b45e 729
b50d93d1
VZ
730void
731wxRendererXP::DoDrawButtonLike(HTHEME htheme,
732 int part,
733 wxDC& dc,
734 const wxRect& rect,
735 int flags)
736{
737 RECT r;
738 wxCopyRectToRECT(rect, r);
7cf3223a 739
b50d93d1
VZ
740 // the base state is always 1, whether it is PBS_NORMAL,
741 // {CBS,RBS}_UNCHECKEDNORMAL or CBS_NORMAL
742 int state = 1;
081b3342 743
6c9aaf7d
VZ
744 // XBS_XXX is followed by XBX_XXXHOT, then XBS_XXXPRESSED and DISABLED
745 enum
746 {
747 NORMAL_OFFSET,
748 HOT_OFFSET,
749 PRESSED_OFFSET,
750 DISABLED_OFFSET,
751 STATES_COUNT
752 };
081b3342 753
6c9aaf7d
VZ
754 // in both RBS_ and CBS_ enums CHECKED elements are offset by 4 from base
755 // (UNCHECKED) ones and MIXED are offset by 4 again as there are all states
756 // from the above enum in between them
081b3342 757 if ( flags & wxCONTROL_CHECKED )
6c9aaf7d 758 state += STATES_COUNT;
081b3342 759 else if ( flags & wxCONTROL_UNDETERMINED )
6c9aaf7d 760 state += 2*STATES_COUNT;
081b3342 761
6c9aaf7d
VZ
762 if ( flags & wxCONTROL_DISABLED )
763 state += DISABLED_OFFSET;
081b3342 764 else if ( flags & wxCONTROL_PRESSED )
6c9aaf7d 765 state += PRESSED_OFFSET;
2209baae 766 else if ( flags & wxCONTROL_CURRENT )
6c9aaf7d
VZ
767 state += HOT_OFFSET;
768 // wxCONTROL_ISDEFAULT flag is only valid for push buttons
b50d93d1 769 else if ( part == BP_PUSHBUTTON && (flags & wxCONTROL_ISDEFAULT) )
2209baae 770 state = PBS_DEFAULTED;
2209baae
RR
771
772 wxUxThemeEngine::Get()->DrawThemeBackground
773 (
b50d93d1 774 htheme,
942d5e2d 775 GetHdcOf(dc.GetTempHDC()),
b50d93d1 776 part,
2209baae
RR
777 state,
778 &r,
779 NULL
780 );
b50d93d1 781}
2209baae 782
b50d93d1
VZ
783void
784wxRendererXP::DrawTitleBarBitmap(wxWindow *win,
785 wxDC& dc,
786 const wxRect& rect,
787 wxTitleBarButton button,
788 int flags)
789{
790 wxUxThemeHandle hTheme(win, L"WINDOW");
791 if ( !hTheme )
792 {
793 m_rendererNative.DrawTitleBarBitmap(win, dc, rect, button, flags);
794 return;
795 }
796
797 int part;
798 switch ( button )
799 {
800 case wxTITLEBAR_BUTTON_CLOSE:
801 part = WP_CLOSEBUTTON;
802 break;
803
804 case wxTITLEBAR_BUTTON_MAXIMIZE:
805 part = WP_MAXBUTTON;
806 break;
807
808 case wxTITLEBAR_BUTTON_ICONIZE:
809 part = WP_MINBUTTON;
810 break;
811
812 case wxTITLEBAR_BUTTON_RESTORE:
813 part = WP_RESTOREBUTTON;
814 break;
815
816 case wxTITLEBAR_BUTTON_HELP:
817 part = WP_HELPBUTTON;
818 break;
819
820 default:
821 wxFAIL_MSG( "unsupported title bar button" );
822 return;
823 }
824
825 DoDrawButtonLike(hTheme, part, dc, rect, flags);
6c9aaf7d 826}
a9fdf824 827
8b97949e
VZ
828// ----------------------------------------------------------------------------
829// splitter drawing
830// ----------------------------------------------------------------------------
831
832// the width of the sash: this is the same as used by Explorer...
833static const wxCoord SASH_WIDTH = 4;
834
c4e6c15e 835wxSplitterRenderParams
3c2544bb 836wxRendererXP::GetSplitterParams(const wxWindow * win)
8b97949e 837{
9f93b45e 838 if ( win->HasFlag(wxSP_NO_XP_THEME) )
3c2544bb
JS
839 return m_rendererNative.GetSplitterParams(win);
840 else
841 return wxSplitterRenderParams(SASH_WIDTH, 0, false);
8b97949e
VZ
842}
843
844void
3c2544bb
JS
845wxRendererXP::DrawSplitterBorder(wxWindow * win,
846 wxDC& dc,
847 const wxRect& rect,
848 int flags)
8b97949e 849{
9f93b45e 850 if ( win->HasFlag(wxSP_NO_XP_THEME) )
3c2544bb
JS
851 {
852 m_rendererNative.DrawSplitterBorder(win, dc, rect, flags);
853 }
8b97949e
VZ
854}
855
856void
857wxRendererXP::DrawSplitterSash(wxWindow *win,
858 wxDC& dc,
859 const wxSize& size,
860 wxCoord position,
c4e6c15e 861 wxOrientation orient,
3c2544bb 862 int flags)
8b97949e 863{
6421119d 864 if ( !win->HasFlag(wxSP_NO_XP_THEME) )
8b97949e 865 {
fe404d1a
JS
866 dc.SetPen(*wxTRANSPARENT_PEN);
867 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
868 if ( orient == wxVERTICAL )
8b97949e 869 {
fe404d1a 870 dc.DrawRectangle(position, 0, SASH_WIDTH, size.y);
8b97949e 871 }
fe404d1a
JS
872 else // wxHORIZONTAL
873 {
874 dc.DrawRectangle(0, position, size.x, SASH_WIDTH);
875 }
876
877 return;
8b97949e 878 }
6421119d
VZ
879
880 m_rendererNative.DrawSplitterSash(win, dc, size, position, orient, flags);
8b97949e
VZ
881}
882
7cf3223a 883#endif // wxUSE_UXTHEME