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