]> git.saurik.com Git - wxWidgets.git/blob - src/msw/renderer.cpp
Added clipboard sample
[wxWidgets.git] / src / msw / renderer.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/renderer.cpp
3 // Purpose: implementation of wxRendererNative for Windows
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>
9 // License: wxWindows licence
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"
29 #include "wx/window.h"
30 #include "wx/dc.h"
31 #include "wx/settings.h"
32 #endif //WX_PRECOMP
33
34 #include "wx/scopeguard.h"
35 #include "wx/splitter.h"
36 #include "wx/renderer.h"
37 #include "wx/msw/private.h"
38 #include "wx/msw/dc.h"
39 #include "wx/msw/uxtheme.h"
40
41 #if wxUSE_GRAPHICS_CONTEXT
42 // TODO remove this dependency (gdiplus needs the macros)
43 #ifndef max
44 #define max(a,b) (((a) > (b)) ? (a) : (b))
45 #endif
46
47 #ifndef min
48 #define min(a,b) (((a) < (b)) ? (a) : (b))
49 #endif
50
51 #include "wx/dcgraph.h"
52 #include "gdiplus.h"
53 using namespace Gdiplus;
54 #endif // wxUSE_GRAPHICS_CONTEXT
55
56 // tmschema.h is in Win32 Platform SDK and might not be available with earlier
57 // compilers
58 #ifndef CP_DROPDOWNBUTTON
59 #define BP_PUSHBUTTON 1
60 #define BP_RADIOBUTTON 2
61 #define BP_CHECKBOX 3
62 #define RBS_UNCHECKEDNORMAL 1
63 #define RBS_CHECKEDNORMAL (RBS_UNCHECKEDNORMAL + 4)
64 #define RBS_MIXEDNORMAL (RBS_CHECKEDNORMAL + 4)
65 #define CBS_UNCHECKEDNORMAL 1
66 #define CBS_CHECKEDNORMAL (CBS_UNCHECKEDNORMAL + 4)
67 #define CBS_MIXEDNORMAL (CBS_CHECKEDNORMAL + 4)
68
69 #define PBS_NORMAL 1
70 #define PBS_HOT 2
71 #define PBS_PRESSED 3
72 #define PBS_DISABLED 4
73 #define PBS_DEFAULTED 5
74
75 #define CP_DROPDOWNBUTTON 1
76
77 #define CBXS_NORMAL 1
78 #define CBXS_HOT 2
79 #define CBXS_PRESSED 3
80 #define CBXS_DISABLED 4
81
82 #define TVP_GLYPH 2
83
84 #define GLPS_CLOSED 1
85 #define GLPS_OPENED 2
86
87 #define HP_HEADERITEM 1
88
89 #define HIS_NORMAL 1
90 #define HIS_HOT 2
91 #define HIS_PRESSED 3
92
93 #define TMT_HEIGHT 2417
94
95 #define HP_HEADERSORTARROW 4
96 #define HSAS_SORTEDUP 1
97 #define HSAS_SORTEDDOWN 2
98
99 #define EP_EDITTEXT 1
100 #define ETS_NORMAL 1
101 #define ETS_HOT 2
102 #define ETS_SELECTED 3
103 #define ETS_DISABLED 4
104 #define ETS_FOCUSED 5
105 #define ETS_READONLY 6
106 #define ETS_ASSIST 7
107 #define TMT_FILLCOLOR 3802
108 #define TMT_TEXTCOLOR 3803
109 #define TMT_BORDERCOLOR 3801
110 #define TMT_EDGEFILLCOLOR 3808
111 #endif
112
113
114 // ----------------------------------------------------------------------------
115 // If the DC is a wxGCDC then pull out the HDC from the GraphicsContext when
116 // it is needed, and handle the Release when done.
117
118 class GraphicsHDC
119 {
120 public:
121 GraphicsHDC(wxDC* dc)
122 {
123 #if wxUSE_GRAPHICS_CONTEXT
124 m_graphics = NULL;
125 wxGCDC* gcdc = wxDynamicCast(dc, wxGCDC);
126 if (gcdc) {
127 m_graphics = (Graphics*)gcdc->GetGraphicsContext()->GetNativeContext();
128 m_hdc = m_graphics->GetHDC();
129 }
130 else
131 #endif
132 m_hdc = GetHdcOf(*((wxMSWDCImpl*)dc->GetImpl()));
133 }
134
135 ~GraphicsHDC()
136 {
137 #if wxUSE_GRAPHICS_CONTEXT
138 if (m_graphics)
139 m_graphics->ReleaseHDC(m_hdc);
140 #endif
141 }
142
143 operator HDC() const { return m_hdc; }
144
145 private:
146 HDC m_hdc;
147 #if wxUSE_GRAPHICS_CONTEXT
148 Graphics* m_graphics;
149 #endif
150 };
151
152 #if defined(__WXWINCE__)
153 #ifndef DFCS_FLAT
154 #define DFCS_FLAT 0
155 #endif
156 #ifndef DFCS_MONO
157 #define DFCS_MONO 0
158 #endif
159 #endif
160
161 #ifndef DFCS_HOT
162 #define DFCS_HOT 0x1000
163 #endif
164
165 // ----------------------------------------------------------------------------
166 // wxRendererMSW: wxRendererNative implementation for "old" Win32 systems
167 // ----------------------------------------------------------------------------
168
169 class WXDLLEXPORT wxRendererMSW : public wxDelegateRendererNative
170 {
171 public:
172 wxRendererMSW() { }
173
174 static wxRendererNative& Get();
175
176 virtual void DrawComboBoxDropButton(wxWindow *win,
177 wxDC& dc,
178 const wxRect& rect,
179 int flags = 0);
180
181 virtual void DrawCheckBox(wxWindow *win,
182 wxDC& dc,
183 const wxRect& rect,
184 int flags = 0);
185
186 virtual void DrawPushButton(wxWindow *win,
187 wxDC& dc,
188 const wxRect& rect,
189 int flags = 0);
190
191 virtual void DrawFocusRect(wxWindow* win,
192 wxDC& dc,
193 const wxRect& rect,
194 int flags = 0);
195
196 virtual void DrawChoice(wxWindow* win,
197 wxDC& dc,
198 const wxRect& rect,
199 int flags=0);
200
201 virtual void DrawComboBox(wxWindow* win,
202 wxDC& dc,
203 const wxRect& rect,
204 int flags=0);
205
206 virtual void DrawTextCtrl(wxWindow* win,
207 wxDC& dc,
208 const wxRect& rect,
209 int flags=0);
210
211 virtual void DrawRadioButton(wxWindow* win,
212 wxDC& dc,
213 const wxRect& rect,
214 int flags=0);
215
216 virtual wxSize GetCheckBoxSize(wxWindow *win);
217
218 virtual int GetHeaderButtonHeight(wxWindow *win);
219
220 private:
221 DECLARE_NO_COPY_CLASS(wxRendererMSW)
222 };
223
224 // ----------------------------------------------------------------------------
225 // wxRendererXP: wxRendererNative implementation for Windows XP and later
226 // ----------------------------------------------------------------------------
227
228 #if wxUSE_UXTHEME
229
230 class WXDLLEXPORT wxRendererXP : public wxDelegateRendererNative
231 {
232 public:
233 wxRendererXP() : wxDelegateRendererNative(wxRendererMSW::Get()) { }
234
235 static wxRendererNative& Get();
236
237 virtual int DrawHeaderButton(wxWindow *win,
238 wxDC& dc,
239 const wxRect& rect,
240 int flags = 0,
241 wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE,
242 wxHeaderButtonParams* params = NULL);
243
244 virtual void DrawTreeItemButton(wxWindow *win,
245 wxDC& dc,
246 const wxRect& rect,
247 int flags = 0);
248 virtual void DrawSplitterBorder(wxWindow *win,
249 wxDC& dc,
250 const wxRect& rect,
251 int flags = 0);
252 virtual void DrawSplitterSash(wxWindow *win,
253 wxDC& dc,
254 const wxSize& size,
255 wxCoord position,
256 wxOrientation orient,
257 int flags = 0);
258 virtual void DrawComboBoxDropButton(wxWindow *win,
259 wxDC& dc,
260 const wxRect& rect,
261 int flags = 0);
262 virtual void DrawCheckBox(wxWindow *win,
263 wxDC& dc,
264 const wxRect& rect,
265 int flags = 0);
266
267 virtual void DrawPushButton(wxWindow *win,
268 wxDC& dc,
269 const wxRect& rect,
270 int flags = 0);
271
272 virtual void DrawItemSelectionRect(wxWindow *win,
273 wxDC& dc,
274 const wxRect& rect,
275 int flags = 0 );
276
277
278 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
279 private:
280 DECLARE_NO_COPY_CLASS(wxRendererXP)
281 };
282
283 #endif // wxUSE_UXTHEME
284
285 // ============================================================================
286 // wxRendererNative and wxRendererMSW implementation
287 // ============================================================================
288
289 /* static */
290 wxRendererNative& wxRendererNative::GetDefault()
291 {
292 #if wxUSE_UXTHEME
293 wxUxThemeEngine *themeEngine = wxUxThemeEngine::Get();
294 if ( themeEngine && themeEngine->IsAppThemed() )
295 return wxRendererXP::Get();
296 #endif // wxUSE_UXTHEME
297
298 return wxRendererMSW::Get();
299 }
300
301 /* static */
302 wxRendererNative& wxRendererMSW::Get()
303 {
304 static wxRendererMSW s_rendererMSW;
305
306 return s_rendererMSW;
307 }
308
309 void
310 wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win),
311 wxDC& dc,
312 const wxRect& rect,
313 int flags)
314 {
315 RECT r;
316 wxCopyRectToRECT(rect, r);
317
318 int style = DFCS_SCROLLCOMBOBOX;
319 if ( flags & wxCONTROL_DISABLED )
320 style |= DFCS_INACTIVE;
321 if ( flags & wxCONTROL_PRESSED )
322 style |= DFCS_PUSHED | DFCS_FLAT;
323
324 ::DrawFrameControl(GraphicsHDC(&dc), &r, DFC_SCROLL, style);
325 }
326
327 void
328 wxRendererMSW::DrawCheckBox(wxWindow * WXUNUSED(win),
329 wxDC& dc,
330 const wxRect& rect,
331 int flags)
332 {
333 RECT r;
334 wxCopyRectToRECT(rect, r);
335
336 int style = DFCS_BUTTONCHECK;
337 if ( flags & wxCONTROL_CHECKED )
338 style |= DFCS_CHECKED;
339 if ( flags & wxCONTROL_DISABLED )
340 style |= DFCS_INACTIVE;
341 if ( flags & wxCONTROL_FLAT )
342 style |= DFCS_MONO;
343 if ( flags & wxCONTROL_PRESSED )
344 style |= DFCS_PUSHED;
345 if ( flags & wxCONTROL_CURRENT )
346 style |= DFCS_HOT;
347
348 ::DrawFrameControl(GraphicsHDC(&dc), &r, DFC_BUTTON, style);
349 }
350
351 void
352 wxRendererMSW::DrawPushButton(wxWindow * WXUNUSED(win),
353 wxDC& dc,
354 const wxRect& rectOrig,
355 int flags)
356 {
357 wxRect rect(rectOrig);
358
359 int style = DFCS_BUTTONPUSH;
360 if ( flags & wxCONTROL_DISABLED )
361 style |= DFCS_INACTIVE;
362 if ( flags & wxCONTROL_PRESSED )
363 style |= DFCS_PUSHED | DFCS_FLAT;
364 if ( flags & wxCONTROL_ISDEFAULT )
365 {
366 // DrawFrameControl() doesn't seem to support default buttons so we
367 // have to draw the border ourselves
368 wxDCPenChanger pen(dc, *wxBLACK_PEN);
369 wxDCBrushChanger brush(dc, *wxTRANSPARENT_BRUSH);
370 dc.DrawRectangle(rect);
371 rect.Deflate(1);
372 }
373
374 RECT rc;
375 wxCopyRectToRECT(rect, rc);
376
377 ::DrawFrameControl(GraphicsHDC(&dc), &rc, DFC_BUTTON, style);
378 }
379
380 void wxRendererMSW::DrawFocusRect(wxWindow * WXUNUSED(win),
381 wxDC& dc,
382 const wxRect& rect,
383 int WXUNUSED(flags))
384 {
385 RECT rc;
386 wxCopyRectToRECT(rect, rc);
387
388 ::DrawFocusRect(GraphicsHDC(&dc), &rc);
389 }
390
391 wxSize wxRendererMSW::GetCheckBoxSize(wxWindow * WXUNUSED(win))
392 {
393 return wxSize(::GetSystemMetrics(SM_CXMENUCHECK),
394 ::GetSystemMetrics(SM_CYMENUCHECK));
395 }
396
397 int wxRendererMSW::GetHeaderButtonHeight(wxWindow * WXUNUSED(win))
398 {
399 // some "reasonable" value returned in case of error, it doesn't really
400 // correspond to anything but it's better than returning 0
401 static const int DEFAULT_HEIGHT = 20;
402
403
404 // create a temporary header window just to get its geometry
405 HWND hwndHeader = ::CreateWindow(WC_HEADER, NULL, 0,
406 0, 0, 0, 0, NULL, NULL, NULL, NULL);
407 if ( !hwndHeader )
408 return DEFAULT_HEIGHT;
409
410 wxON_BLOCK_EXIT1( ::DestroyWindow, hwndHeader );
411
412 // initialize the struct filled with the values by Header_Layout()
413 RECT parentRect = { 0, 0, 100, 100 };
414 WINDOWPOS wp = { 0, 0, 0, 0, 0, 0, 0 };
415 HDLAYOUT hdl = { &parentRect, &wp };
416
417 return Header_Layout(hwndHeader, &hdl) ? wp.cy : DEFAULT_HEIGHT;
418 }
419
420 // Uses the theme to draw the border and fill for something like a wxTextCtrl
421 void wxRendererMSW::DrawTextCtrl(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
422 {
423 wxColour fill;
424 wxColour bdr;
425 COLORREF cref;
426
427 #if wxUSE_UXTHEME
428 wxUxThemeHandle hTheme(win, L"EDIT");
429 if (hTheme)
430 {
431 wxUxThemeEngine::Get()->GetThemeColor(hTheme, EP_EDITTEXT,
432 ETS_NORMAL, TMT_FILLCOLOR, &cref);
433 fill = wxRGBToColour(cref);
434
435 int etsState;
436 if ( flags & wxCONTROL_DISABLED )
437 etsState = ETS_DISABLED;
438 else
439 etsState = ETS_NORMAL;
440
441 wxUxThemeEngine::Get()->GetThemeColor(hTheme, EP_EDITTEXT,
442 etsState, TMT_BORDERCOLOR, &cref);
443 bdr = wxRGBToColour(cref);
444 }
445 else
446 #endif
447 {
448 fill = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
449 bdr = *wxBLACK;
450 }
451
452 dc.SetPen( bdr );
453 dc.SetBrush( fill );
454 dc.DrawRectangle(rect);
455 }
456
457
458 // Draw the equivallent of a wxComboBox
459 void wxRendererMSW::DrawComboBox(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
460 {
461 // Draw the main part of the control same as TextCtrl
462 DrawTextCtrl(win, dc, rect, flags);
463
464 // Draw the button inside the border, on the right side
465 wxRect br(rect);
466 br.height -= 2;
467 br.x += br.width - br.height - 1;
468 br.width = br.height;
469 br.y += 1;
470
471 DrawComboBoxDropButton(win, dc, br, flags);
472 }
473
474
475 void wxRendererMSW::DrawChoice(wxWindow* win, wxDC& dc,
476 const wxRect& rect, int flags)
477 {
478 DrawComboBox(win, dc, rect, flags);
479 }
480
481
482 // Draw a themed radio button
483 void wxRendererMSW::DrawRadioButton(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
484 {
485 #if wxUSE_UXTHEME
486 wxUxThemeHandle hTheme(win, L"BUTTON");
487 if ( !hTheme )
488 #endif
489 {
490 // ??? m_rendererNative.DrawRadioButton(win, dc, rect, flags);
491 return;
492 }
493
494 #if wxUSE_UXTHEME
495 RECT r;
496 wxCopyRectToRECT(rect, r);
497
498 int state;
499 if ( flags & wxCONTROL_CHECKED )
500 state = RBS_CHECKEDNORMAL;
501 else if ( flags & wxCONTROL_UNDETERMINED )
502 state = RBS_MIXEDNORMAL;
503 else
504 state = RBS_UNCHECKEDNORMAL;
505
506 // RBS_XXX is followed by RBX_XXXGOT, then RBS_XXXPRESSED and DISABLED
507 if ( flags & wxCONTROL_CURRENT )
508 state += 1;
509 else if ( flags & wxCONTROL_PRESSED )
510 state += 2;
511 else if ( flags & wxCONTROL_DISABLED )
512 state += 3;
513
514 wxUxThemeEngine::Get()->DrawThemeBackground
515 (
516 hTheme,
517 GraphicsHDC(&dc),
518 BP_RADIOBUTTON,
519 state,
520 &r,
521 NULL
522 );
523 #endif
524 }
525
526 // ============================================================================
527 // wxRendererXP implementation
528 // ============================================================================
529
530 #if wxUSE_UXTHEME
531
532 /* static */
533 wxRendererNative& wxRendererXP::Get()
534 {
535 static wxRendererXP s_rendererXP;
536
537 return s_rendererXP;
538 }
539
540 // NOTE: There is no guarantee that the button drawn fills the entire rect (XP
541 // default theme, for example), so the caller should have cleared button's
542 // background before this call. This is quite likely a wxMSW-specific thing.
543 void
544 wxRendererXP::DrawComboBoxDropButton(wxWindow * win,
545 wxDC& dc,
546 const wxRect& rect,
547 int flags)
548 {
549 wxUxThemeHandle hTheme(win, L"COMBOBOX");
550 if ( !hTheme )
551 {
552 m_rendererNative.DrawComboBoxDropButton(win, dc, rect, flags);
553 return;
554 }
555
556 RECT r;
557 wxCopyRectToRECT(rect, r);
558
559 int state;
560 if ( flags & wxCONTROL_PRESSED )
561 state = CBXS_PRESSED;
562 else if ( flags & wxCONTROL_CURRENT )
563 state = CBXS_HOT;
564 else if ( flags & wxCONTROL_DISABLED )
565 state = CBXS_DISABLED;
566 else
567 state = CBXS_NORMAL;
568
569 wxUxThemeEngine::Get()->DrawThemeBackground
570 (
571 hTheme,
572 GetHdcOf(*((wxMSWDCImpl*)dc.GetImpl())),
573 CP_DROPDOWNBUTTON,
574 state,
575 &r,
576 NULL
577 );
578
579 }
580
581 int
582 wxRendererXP::DrawHeaderButton(wxWindow *win,
583 wxDC& dc,
584 const wxRect& rect,
585 int flags,
586 wxHeaderSortIconType sortArrow,
587 wxHeaderButtonParams* params)
588 {
589 wxUxThemeHandle hTheme(win, L"HEADER");
590 if ( !hTheme )
591 {
592 return m_rendererNative.DrawHeaderButton(win, dc, rect, flags, sortArrow, params);
593 }
594
595 RECT r;
596 wxCopyRectToRECT(rect, r);
597
598 int state;
599 if ( flags & wxCONTROL_PRESSED )
600 state = HIS_PRESSED;
601 else if ( flags & wxCONTROL_CURRENT )
602 state = HIS_HOT;
603 else
604 state = HIS_NORMAL;
605 wxUxThemeEngine::Get()->DrawThemeBackground
606 (
607 hTheme,
608 GetHdcOf(*((wxMSWDCImpl*)dc.GetImpl())),
609 HP_HEADERITEM,
610 state,
611 &r,
612 NULL
613 );
614
615 // NOTE: Using the theme to draw HP_HEADERSORTARROW doesn't do anything.
616 // Why? If this can be fixed then draw the sort arrows using the theme
617 // and then clear those flags before calling DrawHeaderButtonContents.
618
619 // Add any extras that are specified in flags and params
620 return DrawHeaderButtonContents(win, dc, rect, flags, sortArrow, params);
621 }
622
623
624 void
625 wxRendererXP::DrawTreeItemButton(wxWindow *win,
626 wxDC& dc,
627 const wxRect& rect,
628 int flags)
629 {
630 wxUxThemeHandle hTheme(win, L"TREEVIEW");
631 if ( !hTheme )
632 {
633 m_rendererNative.DrawTreeItemButton(win, dc, rect, flags);
634 return;
635 }
636
637 RECT r;
638 wxCopyRectToRECT(rect, r);
639
640 int state = flags & wxCONTROL_EXPANDED ? GLPS_OPENED : GLPS_CLOSED;
641 wxUxThemeEngine::Get()->DrawThemeBackground
642 (
643 hTheme,
644 GetHdcOf(*((wxMSWDCImpl*)dc.GetImpl())),
645 TVP_GLYPH,
646 state,
647 &r,
648 NULL
649 );
650 }
651
652
653
654 void
655 wxRendererXP::DrawCheckBox(wxWindow *win,
656 wxDC& dc,
657 const wxRect& rect,
658 int flags)
659 {
660 wxUxThemeHandle hTheme(win, L"BUTTON");
661 if ( !hTheme )
662 {
663 m_rendererNative.DrawCheckBox(win, dc, rect, flags);
664 return;
665 }
666
667 RECT r;
668 wxCopyRectToRECT(rect, r);
669
670 int state;
671 if ( flags & wxCONTROL_CHECKED )
672 state = CBS_CHECKEDNORMAL;
673 else if ( flags & wxCONTROL_UNDETERMINED )
674 state = CBS_MIXEDNORMAL;
675 else
676 state = CBS_UNCHECKEDNORMAL;
677
678 // CBS_XXX is followed by CBX_XXXHOT, then CBS_XXXPRESSED and DISABLED
679 enum
680 {
681 CBS_HOT_OFFSET = 1,
682 CBS_PRESSED_OFFSET = 2,
683 CBS_DISABLED_OFFSET = 3
684 };
685
686 if ( flags & wxCONTROL_DISABLED )
687 state += CBS_DISABLED_OFFSET;
688 else if ( flags & wxCONTROL_PRESSED )
689 state += CBS_PRESSED_OFFSET;
690 else if ( flags & wxCONTROL_CURRENT )
691 state += CBS_HOT_OFFSET;
692
693 wxUxThemeEngine::Get()->DrawThemeBackground
694 (
695 hTheme,
696 GetHdcOf(*((wxMSWDCImpl*)dc.GetImpl())),
697 BP_CHECKBOX,
698 state,
699 &r,
700 NULL
701 );
702 }
703
704 void
705 wxRendererXP::DrawPushButton(wxWindow * win,
706 wxDC& dc,
707 const wxRect& rect,
708 int flags)
709 {
710 wxUxThemeHandle hTheme(win, L"BUTTON");
711 if ( !hTheme )
712 {
713 m_rendererNative.DrawPushButton(win, dc, rect, flags);
714 return;
715 }
716
717 RECT r;
718 wxCopyRectToRECT(rect, r);
719
720 int state;
721 if ( flags & wxCONTROL_PRESSED )
722 state = PBS_PRESSED;
723 else if ( flags & wxCONTROL_CURRENT )
724 state = PBS_HOT;
725 else if ( flags & wxCONTROL_DISABLED )
726 state = PBS_DISABLED;
727 else if ( flags & wxCONTROL_ISDEFAULT )
728 state = PBS_DEFAULTED;
729 else
730 state = PBS_NORMAL;
731
732 wxUxThemeEngine::Get()->DrawThemeBackground
733 (
734 hTheme,
735 GetHdcOf(*((wxMSWDCImpl*)dc.GetImpl())),
736 BP_PUSHBUTTON,
737 state,
738 &r,
739 NULL
740 );
741 }
742
743 void
744 wxRendererXP::DrawItemSelectionRect(wxWindow *win,
745 wxDC& dc,
746 const wxRect& rect,
747 int flags)
748 {
749 wxBrush brush;
750 if ( flags & wxCONTROL_SELECTED )
751 {
752 if ( flags & wxCONTROL_FOCUSED )
753 {
754 brush = wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
755 }
756 else // !focused
757 {
758 brush = wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
759 }
760 }
761 else // !selected
762 {
763 brush = *wxTRANSPARENT_BRUSH;
764 }
765
766 dc.SetBrush(brush);
767 dc.SetPen(*wxTRANSPARENT_PEN);
768 dc.DrawRectangle( rect );
769
770 if ((flags & wxCONTROL_FOCUSED) && (flags & wxCONTROL_CURRENT))
771 DrawFocusRect( win, dc, rect, flags );
772 }
773
774
775
776 // ----------------------------------------------------------------------------
777 // splitter drawing
778 // ----------------------------------------------------------------------------
779
780 // the width of the sash: this is the same as used by Explorer...
781 static const wxCoord SASH_WIDTH = 4;
782
783 wxSplitterRenderParams
784 wxRendererXP::GetSplitterParams(const wxWindow * win)
785 {
786 if ( win->HasFlag(wxSP_NO_XP_THEME) )
787 return m_rendererNative.GetSplitterParams(win);
788 else
789 return wxSplitterRenderParams(SASH_WIDTH, 0, false);
790 }
791
792 void
793 wxRendererXP::DrawSplitterBorder(wxWindow * win,
794 wxDC& dc,
795 const wxRect& rect,
796 int flags)
797 {
798 if ( win->HasFlag(wxSP_NO_XP_THEME) )
799 {
800 m_rendererNative.DrawSplitterBorder(win, dc, rect, flags);
801 }
802 }
803
804 void
805 wxRendererXP::DrawSplitterSash(wxWindow *win,
806 wxDC& dc,
807 const wxSize& size,
808 wxCoord position,
809 wxOrientation orient,
810 int flags)
811 {
812 if ( !win->HasFlag(wxSP_NO_XP_THEME) )
813 {
814 dc.SetPen(*wxTRANSPARENT_PEN);
815 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
816 if ( orient == wxVERTICAL )
817 {
818 dc.DrawRectangle(position, 0, SASH_WIDTH, size.y);
819 }
820 else // wxHORIZONTAL
821 {
822 dc.DrawRectangle(0, position, size.x, SASH_WIDTH);
823 }
824
825 return;
826 }
827
828 m_rendererNative.DrawSplitterSash(win, dc, size, position, orient, flags);
829 }
830
831 #endif // wxUSE_UXTHEME