+ else {
+ // we get this event in 3 cases
+ //
+ // a) one of our pages might have generated it because the user TABbed
+ // out from it in which case we should propagate the event upwards and
+ // our parent will take care of setting the focus to prev/next sibling
+ //
+ // or
+ //
+ // b) the parent panel wants to give the focus to us so that we
+ // forward it to our selected page. We can't deal with this in
+ // OnSetFocus() because we don't know which direction the focus came
+ // from in this case and so can't choose between setting the focus to
+ // first or last panel child
+ //
+ // or
+ //
+ // c) we ourselves (see MSWTranslateMessage) generated the event
+ //
+ wxWindow * const parent = GetParent();
+
+ const bool isFromParent = event.GetEventObject() == parent;
+ const bool isFromSelf = event.GetEventObject() == this;
+
+ if ( isFromParent || isFromSelf )
+ {
+ // no, it doesn't come from child, case (b) or (c): forward to a
+ // page but only if direction is backwards (TAB) or from ourselves,
+ if ( m_nSelection != -1 &&
+ (!event.GetDirection() || isFromSelf) )
+ {
+ // so that the page knows that the event comes from it's parent
+ // and is being propagated downwards
+ event.SetEventObject(this);
+
+ wxWindow *page = m_pages[m_nSelection];
+ if ( !page->GetEventHandler()->ProcessEvent(event) )
+ {
+ page->SetFocus();
+ }
+ //else: page manages focus inside it itself
+ }
+ else // otherwise set the focus to the notebook itself
+ {
+ SetFocus();
+ }
+ }
+ else
+ {
+ // it comes from our child, case (a), pass to the parent, but only
+ // if the direction is forwards. Otherwise set the focus to the
+ // notebook itself. The notebook is always the 'first' control of a
+ // page.
+ if ( !event.GetDirection() )
+ {
+ SetFocus();
+ }
+ else if ( parent )
+ {
+ event.SetCurrentFocus(this);
+ parent->GetEventHandler()->ProcessEvent(event);
+ }
+ }
+ }
+}
+
+#if wxUSE_UXTHEME
+
+WXHBRUSH wxNotebook::QueryBgBitmap()
+{
+ RECT rc;
+ ::GetClientRect(GetHwnd(), &rc);
+
+ // adjust position
+ TabCtrl_AdjustRect(GetHwnd(), false, &rc);
+
+ WindowHDC hDC(GetHwnd());
+ MemoryHDC hDCMem(hDC);
+ CompatibleBitmap hBmp(hDC, rc.right, rc.bottom);
+
+ SelectInHDC selectBmp(hDCMem, hBmp);
+
+ wxUxThemeHandle theme(this, L"TAB");
+ if ( theme )
+ {
+ AdjustRectForThemeBg(rc);
+
+ wxUxThemeEngine::Get()->DrawThemeBackground
+ (
+ theme,
+ (WXHDC)hDCMem,
+ 9 /* TABP_PANE */,
+ 0,
+ &rc,
+ NULL
+ );
+ }
+
+ return (WXHBRUSH)::CreatePatternBrush(hBmp);
+}
+
+void wxNotebook::UpdateBgBrush()
+{
+ if ( m_hbrBackground )
+ ::DeleteObject((HBRUSH)m_hbrBackground);
+
+ if ( !m_hasBgCol && wxUxThemeEngine::GetIfActive() )
+ {
+ m_hbrBackground = QueryBgBitmap();
+ }
+ else // no themes
+ {
+ m_hbrBackground = NULL;
+ }
+}
+
+WXHBRUSH wxNotebook::MSWGetBgBrushForChild(WXHDC hDC, wxWindow *win)
+{
+ if ( m_hbrBackground )
+ {
+ // before drawing with the background brush, we need to position it
+ // correctly
+ RECT rc;
+ ::GetWindowRect(GetHwndOf(win), &rc);
+
+ ::MapWindowPoints(NULL, GetHwnd(), (POINT *)&rc, 1);
+
+ if ( !::SetBrushOrgEx((HDC)hDC, -rc.left, -rc.top, NULL) )
+ {
+ wxLogLastError(_T("SetBrushOrgEx(notebook bg brush)"));
+ }
+
+ return m_hbrBackground;
+ }
+
+ return wxNotebookBase::MSWGetBgBrushForChild(hDC, win);
+}
+
+wxColour wxNotebook::MSWGetBgColourForChild(wxWindow *WXUNUSED(win))
+{
+ if ( m_hasBgCol )
+ return GetBackgroundColour();
+
+ // Experimental: don't do this since we're doing it in wxPanel
+#if 0 // defined(__POCKETPC__) || defined(__SMARTPHONE__)
+ // For some reason, the pages will be grey by default.
+ // Normally they should be white on these platforms.
+ // (However the static control backgrounds are painted
+ // in the correct colour, just not the rest of it.)
+ // So let's give WinCE a hint.
+ else if (!win->m_hasBgCol)
+ return *wxWHITE;
+#endif
+
+ if ( !wxUxThemeEngine::GetIfActive() )
+ return wxNullColour;
+
+ return GetThemeBackgroundColour();
+}
+
+bool
+wxNotebook::MSWPrintChild(wxWindow *win,
+ WXWPARAM wParam,
+ WXLPARAM WXUNUSED(lParam))
+{
+ // Don't paint the theme for the child if we have a solid background
+ if ( m_hasBgCol )
+ return false;
+
+
+ RECT rc;
+ ::GetClientRect(GetHwnd(), &rc);
+
+ // adjust position
+ TabCtrl_AdjustRect(GetHwnd(), false, &rc);
+
+ wxUxThemeHandle theme(win, L"TAB");
+ if ( theme )
+ {
+ // map from this client to win client coords
+ ::MapWindowPoints(GetHwnd(), GetHwndOf(win), (POINT *)&rc, 2);
+
+ AdjustRectForThemeBg(rc);
+ wxUxThemeEngine::Get()->DrawThemeBackground
+ (
+ theme,
+ (WXHDC)wParam,
+ 9 /* TABP_PANE */,
+ 0,
+ &rc,
+ NULL
+ );
+ }
+
+ return true;
+}
+
+#endif // wxUSE_UXTHEME
+
+// Windows only: attempts to get colour for UX theme page background
+wxColour wxNotebook::GetThemeBackgroundColour() const
+{
+#if wxUSE_UXTHEME
+ if (wxUxThemeEngine::Get())
+ {
+ wxUxThemeHandle hTheme((wxNotebook*) this, L"TAB");
+ if (hTheme)
+ {
+ // This is total guesswork.
+ // See PlatformSDK\Include\Tmschema.h for values
+ COLORREF themeColor;
+ wxUxThemeEngine::Get()->GetThemeColor(
+ hTheme,
+ 10 /* TABP_BODY */,
+ 1 /* NORMAL */,
+ 3821 /* FILLCOLORHINT */,
+ &themeColor);
+
+ /*
+ [DS] Workaround for WindowBlinds:
+ Some themes return a near black theme color using FILLCOLORHINT,
+ this makes notebook pages have an ugly black background and makes
+ text (usually black) unreadable. Retry again with FILLCOLOR.
+
+ This workaround potentially breaks appearance of some themes,
+ but in practice it already fixes some themes.
+ */
+ if (themeColor == 1)
+ {
+ wxUxThemeEngine::Get()->GetThemeColor(
+ hTheme,
+ 10 /* TABP_BODY */,
+ 1 /* NORMAL */,
+ 3802 /* FILLCOLOR */,
+ &themeColor);
+ }
+
+ return wxRGBToColour(themeColor);
+ }
+ }
+#endif // wxUSE_UXTHEME
+
+ return GetBackgroundColour();