virtual bool IsCanvasWindow() const { return true; }
 #endif
 
+#ifdef __WXMSW__
+    // This is a hack to support inheriting of background through child
+    // wxPanel: at least wxNotebook needs this under wxMSW as its background
+    // should apply to its children which are usually wxPanels which normally
+    // don't have a transparent background. Calling this function allows to
+    // change this for the panels which are used as notebook pages.
+    void MSWSetTransparentBackground(bool isTransparent = true)
+    {
+        m_isTransparent = isTransparent;
+    }
+
+    virtual bool HasTransparentBackground() { return m_isTransparent; }
+#endif // __WXMSW__
+
     WX_DECLARE_CONTROL_CONTAINER();
 
 protected:
     // choose the default border for this window
     virtual wxBorder GetDefaultBorder() const { return wxWindowBase::GetDefaultBorder(); }
 
+private:
+#ifdef __WXMSW__
+    bool m_isTransparent;
+#endif // __WXMSW__
+
     DECLARE_DYNAMIC_CLASS_NO_COPY(wxPanel)
     DECLARE_EVENT_TABLE()
 };
 
     // the hDC parameter is the DC background will be drawn on, it can be used
     // to call SetBrushOrgEx() on it if the returned brush is a bitmap one
     //
-    // child parameter is never NULL
+    // child parameter is never NULL, it can be this window itself or one of
+    // its (grand)children
     //
     // the base class version returns a solid brush if we have a non default
     // background colour or 0 otherwise
     virtual WXHBRUSH MSWGetBgBrushForChild(WXHDC hDC, wxWindowMSW *child);
 
     // return the background brush to use for painting the given window by
-    // quering the parent windows via their MSWGetBgBrushForChild() recursively
-    WXHBRUSH MSWGetBgBrush(WXHDC hDC) { return MSWGetBgBrush(hDC, this); }
-    WXHBRUSH MSWGetBgBrush(WXHDC hDC, wxWindowMSW *child);
+    // querying the parent windows via MSWGetBgBrushForChild() recursively
+    WXHBRUSH MSWGetBgBrush(WXHDC hDC);
 
     enum MSWThemeColour
     {
 
 #endif // wxUSE_TOOLTIPS
     Widgets_SetFgColour,
     Widgets_SetBgColour,
+    Widgets_SetPageBg,
     Widgets_SetFont,
     Widgets_Enable,
 
 #endif // wxUSE_TOOLTIPS
     void OnSetFgCol(wxCommandEvent& event);
     void OnSetBgCol(wxCommandEvent& event);
+    void OnSetPageBg(wxCommandEvent& event);
     void OnSetFont(wxCommandEvent& event);
     void OnEnable(wxCommandEvent& event);
     void OnSetBorder(wxCommandEvent& event);
 
     EVT_MENU(Widgets_SetFgColour, WidgetsFrame::OnSetFgCol)
     EVT_MENU(Widgets_SetBgColour, WidgetsFrame::OnSetBgCol)
+    EVT_MENU(Widgets_SetPageBg,   WidgetsFrame::OnSetPageBg)
     EVT_MENU(Widgets_SetFont,     WidgetsFrame::OnSetFont)
     EVT_MENU(Widgets_Enable,      WidgetsFrame::OnEnable)
 
 #endif // wxUSE_TOOLTIPS
     menuWidget->Append(Widgets_SetFgColour, wxT("Set &foreground...\tCtrl-F"));
     menuWidget->Append(Widgets_SetBgColour, wxT("Set &background...\tCtrl-B"));
+    menuWidget->Append(Widgets_SetPageBg,   wxT("Set &page background...\tShift-Ctrl-B"));
     menuWidget->Append(Widgets_SetFont,     wxT("Set f&ont...\tCtrl-O"));
     menuWidget->AppendCheckItem(Widgets_Enable,  wxT("&Enable/disable\tCtrl-E"));
 
 
 #endif // wxUSE_TOOLTIPS
 
-void WidgetsFrame::OnSetFgCol(wxCommandEvent& WXUNUSED(event))
+namespace
+{
+
+// Trivial wrapper for wxGetColourFromUser() which also does something even if
+// the colour dialog is not available in the current build (which may happen
+// for the ports in development and it is still useful to see how colours work)
+wxColour GetColourFromUser(wxWindow *parent, const wxColour& colDefault)
 {
 #if wxUSE_COLOURDLG
+    return wxGetColourFromUser(parent, colDefault);
+#else // !wxUSE_COLOURDLG
+    if ( colDefault == *wxBLACK )
+        return *wxWHITE;
+    else
+        return *wxBLACK;
+#endif // wxUSE_COLOURDLG/!wxUSE_COLOURDLG
+}
+
+} // anonymous namespace
+
+void WidgetsFrame::OnSetFgCol(wxCommandEvent& WXUNUSED(event))
+{
     // allow for debugging the default colour the first time this is called
     WidgetsPage *page = CurrentPage();
 
     if (!m_colFg.Ok())
         m_colFg = page->GetForegroundColour();
 
-    wxColour col = wxGetColourFromUser(this, m_colFg);
+    wxColour col = GetColourFromUser(this, m_colFg);
     if ( !col.Ok() )
         return;
 
         (*it)->SetForegroundColour(m_colFg);
         (*it)->Refresh();
     }
-#else
-    wxLogMessage(wxT("Colour selection dialog not available in current build."));
-#endif
 }
 
 void WidgetsFrame::OnSetBgCol(wxCommandEvent& WXUNUSED(event))
 {
-#if wxUSE_COLOURDLG
     WidgetsPage *page = CurrentPage();
 
     if ( !m_colBg.Ok() )
         m_colBg = page->GetBackgroundColour();
 
-    wxColour col = wxGetColourFromUser(this, m_colBg);
+    wxColour col = GetColourFromUser(this, m_colBg);
     if ( !col.Ok() )
         return;
 
         (*it)->SetBackgroundColour(m_colBg);
         (*it)->Refresh();
     }
-#else
-    wxLogMessage(wxT("Colour selection dialog not available in current build."));
-#endif
+}
+
+void WidgetsFrame::OnSetPageBg(wxCommandEvent& WXUNUSED(event))
+{
+    wxColour col = GetColourFromUser(this, GetBackgroundColour());
+    if ( !col.Ok() )
+        return;
+
+    CurrentPage()->SetBackgroundColour(col);
+    CurrentPage()->Refresh();
 }
 
 void WidgetsFrame::OnSetFont(wxCommandEvent& WXUNUSED(event))
 
 void wxPanel::Init()
 {
     WX_INIT_CONTROL_CONTAINER();
+
+#ifdef __WXMSW__
+    m_isTransparent = false;
+#endif // __WXMSW__
 }
 
 bool wxPanel::Create(wxWindow *parent, wxWindowID id,
 
     if ( !colBg.Ok() )
     {
         if ( wxWindow *win = wxFindWinFromHandle(hWnd) )
-            hbr = MSWGetBgBrush(pDC, win);
+            hbr = win->MSWGetBgBrush(pDC);
 
         // if the control doesn't have any bg colour, foreground colour will be
         // ignored as the return value would be 0 -- so forcefully give it a
 
     // succeeded: save the pointer to the page
     m_pages.Insert(pPage, nPage);
 
+    // also ensure that the notebook background is used for its pages by making
+    // them transparent: this ensures that MSWGetBgBrush() queries the notebook
+    // for the background brush to be used for erasing them
+    if ( wxPanel *panel = wxDynamicCast(pPage, wxPanel) )
+    {
+        panel->MSWSetTransparentBackground();
+    }
+
     // we may need to adjust the size again if the notebook size changed:
     // normally this only happens for the first page we add (the tabs which
     // hadn't been there before are now shown) but for a multiline notebook it
 
 WXHBRUSH wxNotebook::MSWGetBgBrushForChild(WXHDC hDC, wxWindow *child)
 {
-    // Only apply to notebook pages and transparent children, see
-    // wxWindow::MSWGetBgBrushForChild() for explanation
-    bool shouldApply;
-    if ( child->GetParent() == this )
-    {
-        // notebook page -- apply background
-        shouldApply = true;
-    }
-    else
-    {
-        // controls in a notebook page with transparent background should
-        // be handled too
-        shouldApply = child->HasTransparentBackground() &&
-                      child->GetParent()->GetParent() == this;
-    }
-
-    if ( m_hbrBackground && shouldApply )
+    if ( m_hbrBackground )
     {
         // before drawing with the background brush, we need to position it
         // correctly
 
     //     we did it
     //  3. this is backwards compatible behaviour and some people rely on it,
     //     see http://groups.google.com/groups?selm=4252E932.3080801%40able.es
-    wxWindow *parent = GetParent();
     wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
-    HBRUSH hbr = (HBRUSH)parent->MSWGetBgBrush(impl->GetHDC(), this);
+    HBRUSH hbr = MSWGetBgBrush(impl->GetHDC());
 
     // if there is no special brush for painting this control, just use the
     // solid background colour
     wxBrush brush;
     if ( !hbr )
     {
-        brush = wxBrush(parent->GetBackgroundColour());
+        brush = wxBrush(GetParent()->GetBackgroundColour());
         hbr = GetHbrushOf(brush);
     }
 
 
 }
 
 WXHBRUSH
-wxWindowMSW::MSWGetBgBrushForChild(WXHDC WXUNUSED(hDC), wxWindowMSW *child)
+wxWindowMSW::MSWGetBgBrushForChild(WXHDC WXUNUSED(hDC),
+                                   wxWindowMSW * WXUNUSED(child))
 {
     if ( m_hasBgCol )
     {
-        // our background colour applies to:
-        //  1. this window itself, always
-        //  2. all children unless the colour is "not inheritable"
-        //  3. even if it is not inheritable, our immediate transparent
-        //     children should still inherit it -- but not any transparent
-        //     children because it would look wrong if a child of non
-        //     transparent child would show our bg colour when the child itself
-        //     does not
-        if ( child == this ||
-                m_inheritBgCol ||
-                    (child->HasTransparentBackground() &&
-                        child->GetParent() == this) )
-        {
-            // draw children with the same colour as the parent
-            wxBrush *
-                brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour());
+        wxBrush *
+            brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour());
 
-            return (WXHBRUSH)GetHbrushOf(*brush);
-        }
+        return (WXHBRUSH)GetHbrushOf(*brush);
     }
 
     return 0;
 }
 
-WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC, wxWindowMSW *child)
+WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC)
 {
     for ( wxWindowMSW *win = this; win; win = win->GetParent() )
     {
-        WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, child);
+        WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, this);
         if ( hBrush )
             return hBrush;
 
+        // don't use the parent background if we're not transparent
+        if ( !win->HasTransparentBackground() )
+            break;
+
         // background is not inherited beyond top level windows
         if ( win->IsTopLevel() )
             break;