]> git.saurik.com Git - wxWidgets.git/blame - src/msw/renderer.cpp
Correct making the newly inserted menu item owner drawn in some cases.
[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
9c7f49f5 7// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
526954c5 8// Licence: wxWindows licence
9c7f49f5
VZ
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"
85b657c7
VS
28 #include "wx/window.h"
29 #include "wx/dc.h"
9eddec69 30 #include "wx/settings.h"
9c7f49f5
VZ
31#endif //WX_PRECOMP
32
066bd251 33#include "wx/dcgraph.h"
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);
252255e8
VZ
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;
de4bf0b3
FM
156};
157
9c7f49f5 158// ----------------------------------------------------------------------------
8b97949e 159// wxRendererMSW: wxRendererNative implementation for "old" Win32 systems
9c7f49f5
VZ
160// ----------------------------------------------------------------------------
161
5aac6f3f 162class wxRendererMSW : public wxRendererMSWBase
9c7f49f5 163{
2eb10e2a
VZ
164public:
165 wxRendererMSW() { }
166
8b97949e
VZ
167 static wxRendererNative& Get();
168
7402677a
VZ
169 virtual void DrawComboBoxDropButton(wxWindow *win,
170 wxDC& dc,
171 const wxRect& rect,
172 int flags = 0);
173
59ee63e9
VZ
174 virtual void DrawCheckBox(wxWindow *win,
175 wxDC& dc,
176 const wxRect& rect,
081b3342
VZ
177 int flags = 0)
178 {
179 DoDrawButton(DFCS_BUTTONCHECK, win, dc, rect, flags);
180 }
59ee63e9 181
2209baae
RR
182 virtual void DrawPushButton(wxWindow *win,
183 wxDC& dc,
184 const wxRect& rect,
185 int flags = 0);
186
7280c828 187 virtual void DrawTextCtrl(wxWindow* win,
081b3342
VZ
188 wxDC& dc,
189 const wxRect& rect,
190 int flags = 0);
e4131985 191
6e6b532c 192 virtual void DrawRadioBitmap(wxWindow* win,
081b3342
VZ
193 wxDC& dc,
194 const wxRect& rect,
195 int flags = 0)
196 {
197 DoDrawButton(DFCS_BUTTONRADIO, win, dc, rect, flags);
198 }
e4131985 199
b50d93d1
VZ
200 virtual void DrawTitleBarBitmap(wxWindow *win,
201 wxDC& dc,
202 const wxRect& rect,
203 wxTitleBarButton button,
204 int flags = 0);
205
191e43fd 206 virtual wxSize GetCheckBoxSize(wxWindow *win);
e8759560 207
51c42fc5
VZ
208 virtual int GetHeaderButtonHeight(wxWindow *win);
209
9aebcb5e
VS
210 virtual int GetHeaderButtonMargin(wxWindow *win);
211
2eb10e2a 212private:
b50d93d1
VZ
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
081b3342
VZ
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,
b50d93d1
VZ
227 int flags)
228 {
229 DoDrawFrameControl(DFC_BUTTON, kind, win, dc, rect, flags);
230 }
081b3342 231
c0c133e1 232 wxDECLARE_NO_COPY_CLASS(wxRendererMSW);
9c7f49f5
VZ
233};
234
8b97949e
VZ
235// ----------------------------------------------------------------------------
236// wxRendererXP: wxRendererNative implementation for Windows XP and later
237// ----------------------------------------------------------------------------
238
7cf3223a
VZ
239#if wxUSE_UXTHEME
240
5aac6f3f 241class wxRendererXP : public wxRendererMSWBase
8b97949e
VZ
242{
243public:
de4bf0b3 244 wxRendererXP() : wxRendererMSWBase(wxRendererMSW::Get()) { }
8b97949e
VZ
245
246 static wxRendererNative& Get();
247
c97c9952 248 virtual int DrawHeaderButton(wxWindow *win,
4b94ddc4
RD
249 wxDC& dc,
250 const wxRect& rect,
251 int flags = 0,
80752b57 252 wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE,
4b94ddc4 253 wxHeaderButtonParams* params = NULL);
f4322df6 254
9f93b45e
VZ
255 virtual void DrawTreeItemButton(wxWindow *win,
256 wxDC& dc,
257 const wxRect& rect,
258 int flags = 0);
8b97949e
VZ
259 virtual void DrawSplitterBorder(wxWindow *win,
260 wxDC& dc,
c4e6c15e
VZ
261 const wxRect& rect,
262 int flags = 0);
8b97949e
VZ
263 virtual void DrawSplitterSash(wxWindow *win,
264 wxDC& dc,
265 const wxSize& size,
266 wxCoord position,
c4e6c15e
VZ
267 wxOrientation orient,
268 int flags = 0);
7cf3223a
VZ
269 virtual void DrawComboBoxDropButton(wxWindow *win,
270 wxDC& dc,
271 const wxRect& rect,
272 int flags = 0);
90b903c2
WS
273 virtual void DrawCheckBox(wxWindow *win,
274 wxDC& dc,
275 const wxRect& rect,
6c9aaf7d
VZ
276 int flags = 0)
277 {
278 if ( !DoDrawXPButton(BP_CHECKBOX, win, dc, rect, flags) )
279 m_rendererNative.DrawCheckBox(win, dc, rect, flags);
280 }
9f93b45e 281
2209baae
RR
282 virtual void DrawPushButton(wxWindow *win,
283 wxDC& dc,
284 const wxRect& rect,
6c9aaf7d
VZ
285 int flags = 0)
286 {
287 if ( !DoDrawXPButton(BP_PUSHBUTTON, win, dc, rect, flags) )
288 m_rendererNative.DrawPushButton(win, dc, rect, flags);
289 }
2209baae 290
252255e8
VZ
291 virtual void DrawTextCtrl(wxWindow* win,
292 wxDC& dc,
293 const wxRect& rect,
294 int flags = 0);
295
081b3342
VZ
296 virtual void DrawRadioBitmap(wxWindow *win,
297 wxDC& dc,
298 const wxRect& rect,
6c9aaf7d
VZ
299 int flags = 0)
300 {
301 if ( !DoDrawXPButton(BP_RADIOBUTTON, win, dc, rect, flags) )
302 m_rendererNative.DrawRadioBitmap(win, dc, rect, flags);
303 }
081b3342 304
b50d93d1
VZ
305 virtual void DrawTitleBarBitmap(wxWindow *win,
306 wxDC& dc,
307 const wxRect& rect,
308 wxTitleBarButton button,
309 int flags = 0);
310
9f93b45e 311 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
081b3342 312
8b97949e 313private:
b50d93d1
VZ
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
6c9aaf7d
VZ
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
c0c133e1 330 wxDECLARE_NO_COPY_CLASS(wxRendererXP);
8b97949e
VZ
331};
332
7cf3223a
VZ
333#endif // wxUSE_UXTHEME
334
de4bf0b3
FM
335
336// ============================================================================
337// wxRendererMSWBase implementation
338// ============================================================================
339
340void 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
942d5e2d 348 ::DrawFocusRect(GetHdcOf(dc.GetTempHDC()), &rc);
de4bf0b3
FM
349}
350
351void 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
252255e8
VZ
381void wxRendererMSWBase::DrawChoice(wxWindow* win,
382 wxDC& dc,
383 const wxRect& rect,
384 int flags)
385{
386 DrawComboBox(win, dc, rect, flags);
387}
388
389void 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}
de4bf0b3 406
9c7f49f5 407// ============================================================================
8b97949e 408// wxRendererNative and wxRendererMSW implementation
9c7f49f5
VZ
409// ============================================================================
410
411/* static */
f0244295 412wxRendererNative& wxRendererNative::GetDefault()
8b97949e 413{
7cf3223a 414#if wxUSE_UXTHEME
8b97949e 415 wxUxThemeEngine *themeEngine = wxUxThemeEngine::Get();
7cf3223a
VZ
416 if ( themeEngine && themeEngine->IsAppThemed() )
417 return wxRendererXP::Get();
418#endif // wxUSE_UXTHEME
419
420 return wxRendererMSW::Get();
8b97949e
VZ
421}
422
423/* static */
424wxRendererNative& wxRendererMSW::Get()
9c7f49f5
VZ
425{
426 static wxRendererMSW s_rendererMSW;
427
428 return s_rendererMSW;
429}
430
7402677a
VZ
431void
432wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win),
433 wxDC& dc,
434 const wxRect& rect,
435 int flags)
436{
53d4bdbc
VZ
437 wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") );
438
439 wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect);
066bd251 440
7402677a 441 RECT r;
066bd251 442 wxCopyRectToRECT(adjustedRect, r);
7402677a
VZ
443
444 int style = DFCS_SCROLLCOMBOBOX;
445 if ( flags & wxCONTROL_DISABLED )
446 style |= DFCS_INACTIVE;
447 if ( flags & wxCONTROL_PRESSED )
7cf3223a 448 style |= DFCS_PUSHED | DFCS_FLAT;
7402677a 449
942d5e2d 450 ::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, DFC_SCROLL, style);
7402677a
VZ
451}
452
59ee63e9 453void
b50d93d1
VZ
454wxRendererMSW::DoDrawFrameControl(UINT type,
455 UINT kind,
456 wxWindow * WXUNUSED(win),
457 wxDC& dc,
458 const wxRect& rect,
459 int flags)
59ee63e9 460{
53d4bdbc
VZ
461 wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") );
462
463 wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect);
066bd251 464
59ee63e9 465 RECT r;
066bd251 466 wxCopyRectToRECT(adjustedRect, r);
59ee63e9 467
081b3342 468 int style = kind;
59ee63e9
VZ
469 if ( flags & wxCONTROL_CHECKED )
470 style |= DFCS_CHECKED;
471 if ( flags & wxCONTROL_DISABLED )
472 style |= DFCS_INACTIVE;
8a461249
VZ
473 if ( flags & wxCONTROL_FLAT )
474 style |= DFCS_MONO;
59ee63e9
VZ
475 if ( flags & wxCONTROL_PRESSED )
476 style |= DFCS_PUSHED;
477 if ( flags & wxCONTROL_CURRENT )
478 style |= DFCS_HOT;
07968bbd
DS
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;
59ee63e9 484
b50d93d1 485 ::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, type, style);
59ee63e9
VZ
486}
487
2209baae 488void
081b3342 489wxRendererMSW::DrawPushButton(wxWindow *win,
2209baae 490 wxDC& dc,
f2ea4255 491 const wxRect& rectOrig,
2209baae
RR
492 int flags)
493{
f2ea4255 494 wxRect rect(rectOrig);
f2ea4255
VZ
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);
844b9f5f 502 rect.Deflate(1);
f2ea4255
VZ
503 }
504
081b3342 505 DoDrawButton(DFCS_BUTTONPUSH, win, dc, rect, flags);
2209baae
RR
506}
507
b50d93d1
VZ
508void
509wxRendererMSW::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
191e43fd 546wxSize wxRendererMSW::GetCheckBoxSize(wxWindow * WXUNUSED(win))
e8759560
VZ
547{
548 return wxSize(::GetSystemMetrics(SM_CXMENUCHECK),
549 ::GetSystemMetrics(SM_CYMENUCHECK));
550}
551
51c42fc5
VZ
552int 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
a268f4b7 560 HWND hwndHeader = ::CreateWindow(WC_HEADER, NULL, 0,
51c42fc5
VZ
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 };
11fa6e63 569 WINDOWPOS wp = { 0, 0, 0, 0, 0, 0, 0 };
51c42fc5
VZ
570 HDLAYOUT hdl = { &parentRect, &wp };
571
572 return Header_Layout(hwndHeader, &hdl) ? wp.cy : DEFAULT_HEIGHT;
573}
574
9aebcb5e
VS
575int wxRendererMSW::GetHeaderButtonMargin(wxWindow *WXUNUSED(win))
576{
577 return 10;
578}
579
e4131985 580// Uses the theme to draw the border and fill for something like a wxTextCtrl
252255e8
VZ
581void wxRendererMSW::DrawTextCtrl(wxWindow* WXUNUSED(win),
582 wxDC& dc,
583 const wxRect& rect,
584 int WXUNUSED(flags))
e4131985
KO
585{
586 wxColour fill;
587 wxColour bdr;
e4131985
KO
588 {
589 fill = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
590 bdr = *wxBLACK;
591 }
7280c828 592
252255e8
VZ
593 dc.SetPen(bdr);
594 dc.SetBrush(fill);
e4131985
KO
595 dc.DrawRectangle(rect);
596}
597
598
8b97949e
VZ
599// ============================================================================
600// wxRendererXP implementation
601// ============================================================================
602
7cf3223a
VZ
603#if wxUSE_UXTHEME
604
8b97949e
VZ
605/* static */
606wxRendererNative& wxRendererXP::Get()
607{
608 static wxRendererXP s_rendererXP;
609
610 return s_rendererXP;
611}
612
7cf3223a
VZ
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.
616void
617wxRendererXP::DrawComboBoxDropButton(wxWindow * win,
618 wxDC& dc,
619 const wxRect& rect,
620 int flags)
621{
622 wxUxThemeHandle hTheme(win, L"COMBOBOX");
9f93b45e 623 if ( !hTheme )
7cf3223a 624 {
9f93b45e
VZ
625 m_rendererNative.DrawComboBoxDropButton(win, dc, rect, flags);
626 return;
627 }
628
53d4bdbc
VZ
629 wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") );
630
631 wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect);
066bd251 632
9f93b45e 633 RECT r;
066bd251 634 wxCopyRectToRECT(adjustedRect, r);
7cf3223a 635
9f93b45e
VZ
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,
942d5e2d 649 GetHdcOf(dc.GetTempHDC()),
9f93b45e
VZ
650 CP_DROPDOWNBUTTON,
651 state,
652 &r,
653 NULL
654 );
655
656}
657
c97c9952 658int
9f93b45e
VZ
659wxRendererXP::DrawHeaderButton(wxWindow *win,
660 wxDC& dc,
661 const wxRect& rect,
4b94ddc4 662 int flags,
80752b57 663 wxHeaderSortIconType sortArrow,
4b94ddc4 664 wxHeaderButtonParams* params)
9f93b45e
VZ
665{
666 wxUxThemeHandle hTheme(win, L"HEADER");
667 if ( !hTheme )
668 {
c97c9952 669 return m_rendererNative.DrawHeaderButton(win, dc, rect, flags, sortArrow, params);
7cf3223a 670 }
9f93b45e 671
53d4bdbc
VZ
672 wxCHECK_MSG( dc.GetImpl(), -1, wxT("Invalid wxDC") );
673
674 wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect);
066bd251 675
9f93b45e 676 RECT r;
066bd251 677 wxCopyRectToRECT(adjustedRect, r);
9f93b45e
VZ
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,
942d5e2d 689 GetHdcOf(dc.GetTempHDC()),
9f93b45e
VZ
690 HP_HEADERITEM,
691 state,
692 &r,
693 NULL
694 );
4b94ddc4
RD
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.
f4322df6 699
4b94ddc4 700 // Add any extras that are specified in flags and params
c97c9952 701 return DrawHeaderButtonContents(win, dc, rect, flags, sortArrow, params);
9f93b45e
VZ
702}
703
4b94ddc4 704
9f93b45e
VZ
705void
706wxRendererXP::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
53d4bdbc
VZ
718 wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") );
719
720 wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect);
066bd251 721
9f93b45e 722 RECT r;
066bd251 723 wxCopyRectToRECT(adjustedRect, r);
9f93b45e
VZ
724
725 int state = flags & wxCONTROL_EXPANDED ? GLPS_OPENED : GLPS_CLOSED;
726 wxUxThemeEngine::Get()->DrawThemeBackground
727 (
728 hTheme,
942d5e2d 729 GetHdcOf(dc.GetTempHDC()),
9f93b45e
VZ
730 TVP_GLYPH,
731 state,
732 &r,
733 NULL
734 );
735}
736
6c9aaf7d
VZ
737bool
738wxRendererXP::DoDrawXPButton(int kind,
739 wxWindow *win,
740 wxDC& dc,
741 const wxRect& rect,
742 int flags)
9f93b45e
VZ
743{
744 wxUxThemeHandle hTheme(win, L"BUTTON");
745 if ( !hTheme )
6c9aaf7d 746 return false;
9f93b45e 747
b50d93d1 748 DoDrawButtonLike(hTheme, kind, dc, rect, flags);
59ee63e9 749
b50d93d1
VZ
750 return true;
751}
9f93b45e 752
b50d93d1
VZ
753void
754wxRendererXP::DoDrawButtonLike(HTHEME htheme,
755 int part,
756 wxDC& dc,
757 const wxRect& rect,
758 int flags)
759{
53d4bdbc
VZ
760 wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") );
761
762 wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect);
066bd251 763
b50d93d1 764 RECT r;
066bd251 765 wxCopyRectToRECT(adjustedRect, r);
7cf3223a 766
b50d93d1
VZ
767 // the base state is always 1, whether it is PBS_NORMAL,
768 // {CBS,RBS}_UNCHECKEDNORMAL or CBS_NORMAL
769 int state = 1;
081b3342 770
6c9aaf7d
VZ
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 };
081b3342 780
6c9aaf7d
VZ
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
081b3342 784 if ( flags & wxCONTROL_CHECKED )
6c9aaf7d 785 state += STATES_COUNT;
081b3342 786 else if ( flags & wxCONTROL_UNDETERMINED )
6c9aaf7d 787 state += 2*STATES_COUNT;
081b3342 788
6c9aaf7d
VZ
789 if ( flags & wxCONTROL_DISABLED )
790 state += DISABLED_OFFSET;
081b3342 791 else if ( flags & wxCONTROL_PRESSED )
6c9aaf7d 792 state += PRESSED_OFFSET;
2209baae 793 else if ( flags & wxCONTROL_CURRENT )
6c9aaf7d
VZ
794 state += HOT_OFFSET;
795 // wxCONTROL_ISDEFAULT flag is only valid for push buttons
b50d93d1 796 else if ( part == BP_PUSHBUTTON && (flags & wxCONTROL_ISDEFAULT) )
2209baae 797 state = PBS_DEFAULTED;
2209baae
RR
798
799 wxUxThemeEngine::Get()->DrawThemeBackground
800 (
b50d93d1 801 htheme,
942d5e2d 802 GetHdcOf(dc.GetTempHDC()),
b50d93d1 803 part,
2209baae
RR
804 state,
805 &r,
806 NULL
807 );
b50d93d1 808}
2209baae 809
b50d93d1
VZ
810void
811wxRendererXP::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);
6c9aaf7d 853}
a9fdf824 854
252255e8
VZ
855// Uses the theme to draw the border and fill for something like a wxTextCtrl
856void 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
8b97949e
VZ
891// ----------------------------------------------------------------------------
892// splitter drawing
893// ----------------------------------------------------------------------------
894
895// the width of the sash: this is the same as used by Explorer...
896static const wxCoord SASH_WIDTH = 4;
897
c4e6c15e 898wxSplitterRenderParams
3c2544bb 899wxRendererXP::GetSplitterParams(const wxWindow * win)
8b97949e 900{
9f93b45e 901 if ( win->HasFlag(wxSP_NO_XP_THEME) )
3c2544bb
JS
902 return m_rendererNative.GetSplitterParams(win);
903 else
904 return wxSplitterRenderParams(SASH_WIDTH, 0, false);
8b97949e
VZ
905}
906
907void
3c2544bb
JS
908wxRendererXP::DrawSplitterBorder(wxWindow * win,
909 wxDC& dc,
910 const wxRect& rect,
911 int flags)
8b97949e 912{
9f93b45e 913 if ( win->HasFlag(wxSP_NO_XP_THEME) )
3c2544bb
JS
914 {
915 m_rendererNative.DrawSplitterBorder(win, dc, rect, flags);
916 }
8b97949e
VZ
917}
918
919void
920wxRendererXP::DrawSplitterSash(wxWindow *win,
921 wxDC& dc,
922 const wxSize& size,
923 wxCoord position,
c4e6c15e 924 wxOrientation orient,
3c2544bb 925 int flags)
8b97949e 926{
6421119d 927 if ( !win->HasFlag(wxSP_NO_XP_THEME) )
8b97949e 928 {
fe404d1a
JS
929 dc.SetPen(*wxTRANSPARENT_PEN);
930 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
931 if ( orient == wxVERTICAL )
8b97949e 932 {
fe404d1a 933 dc.DrawRectangle(position, 0, SASH_WIDTH, size.y);
8b97949e 934 }
fe404d1a
JS
935 else // wxHORIZONTAL
936 {
937 dc.DrawRectangle(0, position, size.x, SASH_WIDTH);
938 }
939
940 return;
8b97949e 941 }
6421119d
VZ
942
943 m_rendererNative.DrawSplitterSash(win, dc, size, position, orient, flags);
8b97949e
VZ
944}
945
7cf3223a 946#endif // wxUSE_UXTHEME