]> git.saurik.com Git - wxWidgets.git/blob - src/msw/notebook.cpp
signed/unsigned comparison warning fixed
[wxWidgets.git] / src / msw / notebook.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: msw/notebook.cpp
3 // Purpose: implementation of wxNotebook
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 11.06.98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "notebook.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #if wxUSE_NOTEBOOK
24
25 // wxWindows
26 #ifndef WX_PRECOMP
27 #include "wx/string.h"
28 #endif // WX_PRECOMP
29
30 #include "wx/log.h"
31 #include "wx/imaglist.h"
32 #include "wx/event.h"
33 #include "wx/control.h"
34 #include "wx/notebook.h"
35
36 #include "wx/msw/private.h"
37
38 // Windows standard headers
39 #ifndef __WIN95__
40 #error "wxNotebook is only supported Windows 95 and above"
41 #endif //Win95
42
43 #include <windowsx.h> // for SetWindowFont
44
45 #ifdef __GNUWIN32_OLD__
46 #include "wx/msw/gnuwin32/extra.h"
47 #endif
48
49 #if defined(__WIN95__) && !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__))
50 #include <commctrl.h>
51 #endif
52
53 #include "wx/msw/winundef.h"
54
55 #if wxUSE_UXTHEME
56 #include "wx/msw/uxtheme.h"
57
58 #include "wx/radiobut.h"
59 #include "wx/radiobox.h"
60 #include "wx/checkbox.h"
61 #include "wx/bmpbuttn.h"
62 #include "wx/statline.h"
63 #include "wx/statbox.h"
64 #include "wx/stattext.h"
65 #include "wx/slider.h"
66 #include "wx/scrolwin.h"
67 #include "wx/panel.h"
68 #endif
69
70 // ----------------------------------------------------------------------------
71 // macros
72 // ----------------------------------------------------------------------------
73
74 // check that the page index is valid
75 #define IS_VALID_PAGE(nPage) (((nPage) >= 0) && ((nPage) < GetPageCount()))
76
77 // hide the ugly cast
78 #define m_hwnd (HWND)GetHWND()
79
80 // ----------------------------------------------------------------------------
81 // constants
82 // ----------------------------------------------------------------------------
83
84 // This is a work-around for missing defines in gcc-2.95 headers
85 #ifndef TCS_RIGHT
86 #define TCS_RIGHT 0x0002
87 #endif
88
89 #ifndef TCS_VERTICAL
90 #define TCS_VERTICAL 0x0080
91 #endif
92
93 #ifndef TCS_BOTTOM
94 #define TCS_BOTTOM TCS_RIGHT
95 #endif
96
97 // ----------------------------------------------------------------------------
98 // event table
99 // ----------------------------------------------------------------------------
100
101 DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
102 DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
103
104 BEGIN_EVENT_TABLE(wxNotebook, wxControl)
105 EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
106
107 EVT_SIZE(wxNotebook::OnSize)
108
109 EVT_SET_FOCUS(wxNotebook::OnSetFocus)
110
111 EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
112 END_EVENT_TABLE()
113
114 IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl)
115 IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
116
117 // ============================================================================
118 // implementation
119 // ============================================================================
120
121 // ----------------------------------------------------------------------------
122 // wxNotebook construction
123 // ----------------------------------------------------------------------------
124
125 // common part of all ctors
126 void wxNotebook::Init()
127 {
128 m_imageList = NULL;
129 m_nSelection = -1;
130 }
131
132 // default for dynamic class
133 wxNotebook::wxNotebook()
134 {
135 Init();
136 }
137
138 // the same arguments as for wxControl
139 wxNotebook::wxNotebook(wxWindow *parent,
140 wxWindowID id,
141 const wxPoint& pos,
142 const wxSize& size,
143 long style,
144 const wxString& name)
145 {
146 Init();
147
148 Create(parent, id, pos, size, style, name);
149 }
150
151 // Create() function
152 bool wxNotebook::Create(wxWindow *parent,
153 wxWindowID id,
154 const wxPoint& pos,
155 const wxSize& size,
156 long style,
157 const wxString& name)
158 {
159 // base init
160 if ( !CreateControl(parent, id, pos, size, style | wxTAB_TRAVERSAL,
161 wxDefaultValidator, name) )
162 return FALSE;
163
164 if ( !MSWCreateControl(WC_TABCONTROL, _T(""), pos, size) )
165 return FALSE;
166
167 SetBackgroundColour(wxColour(::GetSysColor(COLOR_BTNFACE)));
168
169 return TRUE;
170 }
171
172 WXDWORD wxNotebook::MSWGetStyle(long style, WXDWORD *exstyle) const
173 {
174 WXDWORD tabStyle = wxControl::MSWGetStyle(style, exstyle);
175
176 tabStyle |= WS_TABSTOP | TCS_TABS;
177
178 if ( style & wxNB_MULTILINE )
179 tabStyle |= TCS_MULTILINE;
180 if ( style & wxNB_FIXEDWIDTH )
181 tabStyle |= TCS_FIXEDWIDTH;
182
183 if ( style & wxNB_BOTTOM )
184 tabStyle |= TCS_RIGHT;
185 else if ( style & wxNB_LEFT )
186 tabStyle |= TCS_VERTICAL;
187 else if ( style & wxNB_RIGHT )
188 tabStyle |= TCS_VERTICAL | TCS_RIGHT;
189
190 // ex style
191 if ( exstyle )
192 {
193 // note that we never want to have the default WS_EX_CLIENTEDGE style
194 // as it looks too ugly for the notebooks
195 *exstyle = 0;
196 }
197
198 return tabStyle;
199 }
200
201 // ----------------------------------------------------------------------------
202 // wxNotebook accessors
203 // ----------------------------------------------------------------------------
204
205 int wxNotebook::GetPageCount() const
206 {
207 // consistency check
208 wxASSERT( (int)m_pages.Count() == TabCtrl_GetItemCount(m_hwnd) );
209
210 return m_pages.Count();
211 }
212
213 int wxNotebook::GetRowCount() const
214 {
215 return TabCtrl_GetRowCount(m_hwnd);
216 }
217
218 int wxNotebook::SetSelection(int nPage)
219 {
220 wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") );
221
222 if ( nPage != m_nSelection )
223 {
224 wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, m_windowId);
225 event.SetSelection(nPage);
226 event.SetOldSelection(m_nSelection);
227 event.SetEventObject(this);
228 if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
229 {
230 // program allows the page change
231 event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
232 (void)GetEventHandler()->ProcessEvent(event);
233
234 TabCtrl_SetCurSel(m_hwnd, nPage);
235 }
236 }
237
238 return m_nSelection;
239 }
240
241 bool wxNotebook::SetPageText(int nPage, const wxString& strText)
242 {
243 wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") );
244
245 TC_ITEM tcItem;
246 tcItem.mask = TCIF_TEXT;
247 tcItem.pszText = (wxChar *)strText.c_str();
248
249 return TabCtrl_SetItem(m_hwnd, nPage, &tcItem) != 0;
250 }
251
252 wxString wxNotebook::GetPageText(int nPage) const
253 {
254 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxT(""), wxT("notebook page out of range") );
255
256 wxChar buf[256];
257 TC_ITEM tcItem;
258 tcItem.mask = TCIF_TEXT;
259 tcItem.pszText = buf;
260 tcItem.cchTextMax = WXSIZEOF(buf);
261
262 wxString str;
263 if ( TabCtrl_GetItem(m_hwnd, nPage, &tcItem) )
264 str = tcItem.pszText;
265
266 return str;
267 }
268
269 int wxNotebook::GetPageImage(int nPage) const
270 {
271 wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") );
272
273 TC_ITEM tcItem;
274 tcItem.mask = TCIF_IMAGE;
275
276 return TabCtrl_GetItem(m_hwnd, nPage, &tcItem) ? tcItem.iImage : -1;
277 }
278
279 bool wxNotebook::SetPageImage(int nPage, int nImage)
280 {
281 wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") );
282
283 TC_ITEM tcItem;
284 tcItem.mask = TCIF_IMAGE;
285 tcItem.iImage = nImage;
286
287 return TabCtrl_SetItem(m_hwnd, nPage, &tcItem) != 0;
288 }
289
290 void wxNotebook::SetImageList(wxImageList* imageList)
291 {
292 wxNotebookBase::SetImageList(imageList);
293
294 if ( imageList )
295 {
296 TabCtrl_SetImageList(m_hwnd, (HIMAGELIST)imageList->GetHIMAGELIST());
297 }
298 }
299
300 // ----------------------------------------------------------------------------
301 // wxNotebook size settings
302 // ----------------------------------------------------------------------------
303
304 void wxNotebook::SetPageSize(const wxSize& size)
305 {
306 // transform the page size into the notebook size
307 RECT rc;
308 rc.left =
309 rc.top = 0;
310 rc.right = size.x;
311 rc.bottom = size.y;
312
313 TabCtrl_AdjustRect(GetHwnd(), TRUE, &rc);
314
315 // and now set it
316 SetSize(rc.right - rc.left, rc.bottom - rc.top);
317 }
318
319 void wxNotebook::SetPadding(const wxSize& padding)
320 {
321 TabCtrl_SetPadding(GetHwnd(), padding.x, padding.y);
322 }
323
324 // Windows-only at present. Also, you must use the wxNB_FIXEDWIDTH
325 // style.
326 void wxNotebook::SetTabSize(const wxSize& sz)
327 {
328 ::SendMessage(GetHwnd(), TCM_SETITEMSIZE, 0, MAKELPARAM(sz.x, sz.y));
329 }
330
331 wxSize wxNotebook::CalcSizeFromPage(const wxSize& sizePage) const
332 {
333 wxSize sizeTotal = sizePage;
334
335 // We need to make getting tab size part of the wxWindows API.
336 wxSize tabSize(0, 0);
337 if (GetPageCount() > 0)
338 {
339 RECT rect;
340 TabCtrl_GetItemRect((HWND) GetHWND(), 0, & rect);
341 tabSize.x = rect.right - rect.left;
342 tabSize.y = rect.bottom - rect.top;
343 }
344 if ( HasFlag(wxNB_LEFT) || HasFlag(wxNB_RIGHT) )
345 {
346 sizeTotal.x += tabSize.x + 7;
347 sizeTotal.y += 7;
348 }
349 else
350 {
351 sizeTotal.x += 7;
352 sizeTotal.y += tabSize.y + 7;
353 }
354
355 return sizeTotal;
356 }
357
358 void wxNotebook::AdjustPageSize(wxNotebookPage *page)
359 {
360 wxCHECK_RET( page, _T("NULL page in wxNotebook::AdjustPageSize") );
361
362 RECT rc;
363 rc.left =
364 rc.top = 0;
365
366 // get the page size from the notebook size
367 GetSize((int *)&rc.right, (int *)&rc.bottom);
368 TabCtrl_AdjustRect(m_hwnd, FALSE, &rc);
369
370 page->SetSize(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
371 }
372
373 // ----------------------------------------------------------------------------
374 // wxNotebook operations
375 // ----------------------------------------------------------------------------
376
377 // remove one page from the notebook, without deleting
378 wxNotebookPage *wxNotebook::DoRemovePage(int nPage)
379 {
380 wxNotebookPage *pageRemoved = wxNotebookBase::DoRemovePage(nPage);
381 if ( !pageRemoved )
382 return NULL;
383
384 TabCtrl_DeleteItem(m_hwnd, nPage);
385
386 if ( m_pages.IsEmpty() )
387 {
388 // no selection any more, the notebook becamse empty
389 m_nSelection = -1;
390 }
391 else // notebook still not empty
392 {
393 // change the selected page if it was deleted or became invalid
394 int selNew;
395 if ( m_nSelection == GetPageCount() )
396 {
397 // last page deleted, make the new last page the new selection
398 selNew = m_nSelection - 1;
399 }
400 else if ( nPage <= m_nSelection )
401 {
402 // we must show another page, even if it has the same index
403 selNew = m_nSelection;
404 }
405 else // nothing changes for the currently selected page
406 {
407 selNew = -1;
408
409 // we still must refresh the current page: this needs to be done
410 // for some unknown reason if the tab control shows the up-down
411 // control (i.e. when there are too many pages) -- otherwise after
412 // deleting a page nothing at all is shown
413 m_pages[m_nSelection]->Refresh();
414 }
415
416 if ( selNew != -1 )
417 {
418 // m_nSelection must be always valid so reset it before calling
419 // SetSelection()
420 m_nSelection = -1;
421 SetSelection(selNew);
422 }
423 }
424
425 return pageRemoved;
426 }
427
428 // remove all pages
429 bool wxNotebook::DeleteAllPages()
430 {
431 int nPageCount = GetPageCount();
432 int nPage;
433 for ( nPage = 0; nPage < nPageCount; nPage++ )
434 delete m_pages[nPage];
435
436 m_pages.Clear();
437
438 TabCtrl_DeleteAllItems(m_hwnd);
439
440 m_nSelection = -1;
441
442 return TRUE;
443 }
444
445 // same as AddPage() but does it at given position
446 bool wxNotebook::InsertPage(int nPage,
447 wxNotebookPage *pPage,
448 const wxString& strText,
449 bool bSelect,
450 int imageId)
451 {
452 wxCHECK_MSG( pPage != NULL, FALSE, _T("NULL page in wxNotebook::InsertPage") );
453 wxCHECK_MSG( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), FALSE,
454 _T("invalid index in wxNotebook::InsertPage") );
455
456 wxASSERT_MSG( pPage->GetParent() == this,
457 _T("notebook pages must have notebook as parent") );
458
459 #if wxUSE_UXTHEME && wxUSE_UXTHEME_AUTO
460 // Automatically apply the theme background,
461 // changing the colour of the panel to match the
462 // tab page colour. This won't work well with all
463 // themes but it's a start.
464 if (wxUxThemeEngine::Get() && pPage->IsKindOf(CLASSINFO(wxPanel)))
465 {
466 ApplyThemeBackground(pPage, GetThemeBackgroundColour());
467 }
468 #endif
469
470 // add a new tab to the control
471 // ----------------------------
472
473 // init all fields to 0
474 TC_ITEM tcItem;
475 wxZeroMemory(tcItem);
476
477 // set the image, if any
478 if ( imageId != -1 )
479 {
480 tcItem.mask |= TCIF_IMAGE;
481 tcItem.iImage = imageId;
482 }
483
484 // and the text
485 if ( !strText.IsEmpty() )
486 {
487 tcItem.mask |= TCIF_TEXT;
488 tcItem.pszText = (wxChar *)strText.c_str(); // const_cast
489 }
490
491 // fit the notebook page to the tab control's display area: this should be
492 // done before adding it to the notebook or TabCtrl_InsertItem() will
493 // change the notebooks size itself!
494 AdjustPageSize(pPage);
495
496 // finally do insert it
497 if ( TabCtrl_InsertItem(m_hwnd, nPage, &tcItem) == -1 )
498 {
499 wxLogError(wxT("Can't create the notebook page '%s'."), strText.c_str());
500
501 return FALSE;
502 }
503
504 // succeeded: save the pointer to the page
505 m_pages.Insert(pPage, nPage);
506
507 // for the first page (only) we need to adjust the size again because the
508 // notebook size changed: the tabs which hadn't been there before are now
509 // shown
510 if ( m_pages.GetCount() == 1 )
511 {
512 AdjustPageSize(pPage);
513 }
514
515 // hide the page: unless it is selected, it shouldn't be shown (and if it
516 // is selected it will be shown later)
517 HWND hwnd = GetWinHwnd(pPage);
518 SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_VISIBLE);
519
520 // this updates internal flag too -- otherwise it would get out of sync
521 // with the real state
522 pPage->Show(FALSE);
523
524
525 // now deal with the selection
526 // ---------------------------
527
528 // if the inserted page is before the selected one, we must update the
529 // index of the selected page
530 if ( nPage <= m_nSelection )
531 {
532 // one extra page added
533 m_nSelection++;
534 }
535
536 // some page should be selected: either this one or the first one if there
537 // is still no selection
538 int selNew = -1;
539 if ( bSelect )
540 selNew = nPage;
541 else if ( m_nSelection == -1 )
542 selNew = 0;
543
544 if ( selNew != -1 )
545 SetSelection(selNew);
546
547 return TRUE;
548 }
549
550 // Hit test
551 int wxNotebook::HitTest(const wxPoint& pt, long& flags)
552 {
553 TC_HITTESTINFO hitTestInfo;
554 hitTestInfo.pt.x = pt.x;
555 hitTestInfo.pt.y = pt.y;
556 int item = TabCtrl_HitTest( (HWND) GetHWND(), & hitTestInfo ) ;
557 flags = 0;
558
559 if ((hitTestInfo.flags & TCHT_NOWHERE) == TCHT_NOWHERE)
560 flags |= wxNB_HITTEST_NOWHERE;
561 if ((hitTestInfo.flags & TCHT_ONITEMICON) == TCHT_ONITEMICON)
562 flags |= wxNB_HITTEST_ONICON;
563 if ((hitTestInfo.flags & TCHT_ONITEMLABEL) == TCHT_ONITEMLABEL)
564 flags |= wxNB_HITTEST_ONLABEL;
565
566 return item;
567 }
568
569 // ----------------------------------------------------------------------------
570 // wxNotebook callbacks
571 // ----------------------------------------------------------------------------
572
573 void wxNotebook::OnSize(wxSizeEvent& event)
574 {
575 // fit the notebook page to the tab control's display area
576 RECT rc;
577 rc.left = rc.top = 0;
578 GetSize((int *)&rc.right, (int *)&rc.bottom);
579
580 TabCtrl_AdjustRect(m_hwnd, FALSE, &rc);
581
582 int width = rc.right - rc.left,
583 height = rc.bottom - rc.top;
584 size_t nCount = m_pages.Count();
585 for ( size_t nPage = 0; nPage < nCount; nPage++ ) {
586 wxNotebookPage *pPage = m_pages[nPage];
587 pPage->SetSize(rc.left, rc.top, width, height);
588 }
589
590 event.Skip();
591 }
592
593 void wxNotebook::OnSelChange(wxNotebookEvent& event)
594 {
595 // is it our tab control?
596 if ( event.GetEventObject() == this )
597 {
598 int sel = event.GetOldSelection();
599 if ( sel != -1 )
600 m_pages[sel]->Show(FALSE);
601
602 sel = event.GetSelection();
603 if ( sel != -1 )
604 {
605 wxNotebookPage *pPage = m_pages[sel];
606 pPage->Show(TRUE);
607 pPage->SetFocus();
608 }
609
610 m_nSelection = sel;
611 }
612
613 // we want to give others a chance to process this message as well
614 event.Skip();
615 }
616
617 void wxNotebook::OnSetFocus(wxFocusEvent& event)
618 {
619 // this function is only called when the focus is explicitly set (i.e. from
620 // the program) to the notebook - in this case we don't need the
621 // complicated OnNavigationKey() logic because the programmer knows better
622 // what [s]he wants
623
624 // set focus to the currently selected page if any
625 if ( m_nSelection != -1 )
626 m_pages[m_nSelection]->SetFocus();
627
628 event.Skip();
629 }
630
631 void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
632 {
633 if ( event.IsWindowChange() ) {
634 // change pages
635 AdvanceSelection(event.GetDirection());
636 }
637 else {
638 // we get this event in 2 cases
639 //
640 // a) one of our pages might have generated it because the user TABbed
641 // out from it in which case we should propagate the event upwards and
642 // our parent will take care of setting the focus to prev/next sibling
643 //
644 // or
645 //
646 // b) the parent panel wants to give the focus to us so that we
647 // forward it to our selected page. We can't deal with this in
648 // OnSetFocus() because we don't know which direction the focus came
649 // from in this case and so can't choose between setting the focus to
650 // first or last panel child
651
652 wxWindow *parent = GetParent();
653 if ( event.GetEventObject() == parent )
654 {
655 // no, it doesn't come from child, case (b): forward to a page
656 if ( m_nSelection != -1 )
657 {
658 // so that the page knows that the event comes from it's parent
659 // and is being propagated downwards
660 event.SetEventObject(this);
661
662 wxWindow *page = m_pages[m_nSelection];
663 if ( !page->GetEventHandler()->ProcessEvent(event) )
664 {
665 page->SetFocus();
666 }
667 //else: page manages focus inside it itself
668 }
669 else
670 {
671 // we have no pages - still have to give focus to _something_
672 SetFocus();
673 }
674 }
675 else
676 {
677 // it comes from our child, case (a), pass to the parent
678 if ( parent ) {
679 event.SetCurrentFocus(this);
680 parent->GetEventHandler()->ProcessEvent(event);
681 }
682 }
683 }
684 }
685
686 // ----------------------------------------------------------------------------
687 // wxNotebook base class virtuals
688 // ----------------------------------------------------------------------------
689
690 #if wxUSE_CONSTRAINTS
691
692 // override these 2 functions to do nothing: everything is done in OnSize
693
694 void wxNotebook::SetConstraintSizes(bool WXUNUSED(recurse))
695 {
696 // don't set the sizes of the pages - their correct size is not yet known
697 wxControl::SetConstraintSizes(FALSE);
698 }
699
700 bool wxNotebook::DoPhase(int WXUNUSED(nPhase))
701 {
702 return TRUE;
703 }
704
705 #endif // wxUSE_CONSTRAINTS
706
707 // ----------------------------------------------------------------------------
708 // wxNotebook Windows message handlers
709 // ----------------------------------------------------------------------------
710
711 bool wxNotebook::MSWOnScroll(int orientation, WXWORD nSBCode,
712 WXWORD pos, WXHWND control)
713 {
714 // don't generate EVT_SCROLLWIN events for the WM_SCROLLs coming from the
715 // up-down control
716 if ( control )
717 return FALSE;
718
719 return wxNotebookBase::MSWOnScroll(orientation, nSBCode, pos, control);
720 }
721
722 bool wxNotebook::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result)
723 {
724 wxNotebookEvent event(wxEVT_NULL, m_windowId);
725
726 NMHDR* hdr = (NMHDR *)lParam;
727 switch ( hdr->code ) {
728 case TCN_SELCHANGE:
729 event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
730 break;
731
732 case TCN_SELCHANGING:
733 event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING);
734 break;
735
736 default:
737 return wxControl::MSWOnNotify(idCtrl, lParam, result);
738 }
739
740 event.SetSelection(TabCtrl_GetCurSel(m_hwnd));
741 event.SetOldSelection(m_nSelection);
742 event.SetEventObject(this);
743 event.SetInt(idCtrl);
744
745 bool processed = GetEventHandler()->ProcessEvent(event);
746 *result = !event.IsAllowed();
747 return processed;
748 }
749
750 // Windows only: attempts to get colour for UX theme page background
751 wxColour wxNotebook::GetThemeBackgroundColour()
752 {
753 #if wxUSE_UXTHEME
754 if (wxUxThemeEngine::Get())
755 {
756 WXHTHEME hTheme = wxUxThemeEngine::Get()->m_pfnOpenThemeData(GetHWND(), L"TAB");
757 if (hTheme)
758 {
759 // This is total guesswork.
760 // See PlatformSDK\Include\Tmschema.h for values
761 COLORREF themeColor;
762 wxUxThemeEngine::Get()->
763 m_pfnGetThemeColor(hTheme,
764 10 /* TABP_BODY */,
765 1 /* NORMAL */,
766 3821, /* FILLCOLORHINT */
767 & themeColor);
768
769 wxUxThemeEngine::Get()->m_pfnCloseThemeData(hTheme);
770
771 wxColour colour(GetRValue(themeColor), GetGValue(themeColor), GetBValue(themeColor));
772 return colour;
773 }
774 }
775 #endif
776 return GetBackgroundColour();
777 }
778
779 // Windows only: attempts to apply the UX theme page background to this page
780 void wxNotebook::ApplyThemeBackground(wxWindow* window, const wxColour& colour)
781 {
782 #if wxUSE_UXTHEME
783 // Don't set the background for buttons since this will
784 // switch it into ownerdraw mode
785 if (window->IsKindOf(CLASSINFO(wxButton)) && !window->IsKindOf(CLASSINFO(wxBitmapButton)))
786 // This is essential, otherwise you'll see dark grey
787 // corners in the buttons.
788 ((wxButton*)window)->wxControl::SetBackgroundColour(colour);
789 else if (window->IsKindOf(CLASSINFO(wxStaticText)) ||
790 window->IsKindOf(CLASSINFO(wxStaticBox)) ||
791 window->IsKindOf(CLASSINFO(wxStaticLine)) ||
792 window->IsKindOf(CLASSINFO(wxRadioButton)) ||
793 window->IsKindOf(CLASSINFO(wxRadioBox)) ||
794 window->IsKindOf(CLASSINFO(wxCheckBox)) ||
795 window->IsKindOf(CLASSINFO(wxBitmapButton)) ||
796 window->IsKindOf(CLASSINFO(wxSlider)) ||
797 window->IsKindOf(CLASSINFO(wxPanel)) ||
798 (window->IsKindOf(CLASSINFO(wxNotebook)) && (window != this)) ||
799 window->IsKindOf(CLASSINFO(wxScrolledWindow))
800 )
801 {
802 window->SetBackgroundColour(colour);
803 }
804
805 for ( wxWindowList::Node *node = window->GetChildren().GetFirst(); node; node = node->GetNext() )
806 {
807 wxWindow *child = node->GetData();
808 ApplyThemeBackground(child, colour);
809 }
810 #endif
811 }
812
813 #endif // wxUSE_NOTEBOOK