+// ----------------------------------------------------------------------------
+// flicker-less notebook redraw
+// ----------------------------------------------------------------------------
+
+#if USE_NOTEBOOK_ANTIFLICKER
+
+// wnd proc for the spin button
+LRESULT APIENTRY _EXPORT wxNotebookSpinBtnWndProc(HWND hwnd,
+                                                  UINT message,
+                                                  WPARAM wParam,
+                                                  LPARAM lParam)
+{
+    if ( message == WM_ERASEBKGND )
+        return 0;
+
+    return ::CallWindowProc(CASTWNDPROC gs_wndprocNotebookSpinBtn,
+                            hwnd, message, wParam, lParam);
+}
+
+LRESULT APIENTRY _EXPORT wxNotebookWndProc(HWND hwnd,
+                                           UINT message,
+                                           WPARAM wParam,
+                                           LPARAM lParam)
+{
+    return ::CallWindowProc(CASTWNDPROC gs_wndprocNotebook,
+                            hwnd, message, wParam, lParam);
+}
+
+void wxNotebook::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
+{
+    // do nothing here
+}
+
+void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+    wxPaintDC dc(this);
+    wxMemoryDC memdc;
+    RECT rc;
+    ::GetClientRect(GetHwnd(), &rc);
+    wxBitmap bmp(rc.right, rc.bottom);
+    memdc.SelectObject(bmp);
+
+    const wxLayoutDirection dir = dc.GetLayoutDirection();
+    memdc.SetLayoutDirection(dir);
+
+    const HDC hdc = GetHdcOf(memdc);
+
+    // The drawing logic of the native tab control is absolutely impenetrable
+    // but observation shows that in the current Windows versions (XP and 7),
+    // the tab control always erases its entire background in its window proc
+    // when the tabs are top-aligned but does not do it when the tabs are in
+    // any other position.
+    //
+    // This means that we can't rely on our background colour being used for
+    // the blank area in the tab row because this doesn't work in the default
+    // top-aligned case, hence the hack with ExtFloodFill() below. But it also
+    // means that we still do need to erase the DC to account for the other
+    // cases.
+    //
+    // Moreover, just in case some very old or very new (or even future,
+    // although it seems unlikely that this is ever going to change by now)
+    // version of Windows didn't do it like this, do both things in all cases
+    // instead of optimizing away the one of them which doesn't do anything for
+    // the effectively used tab orientation -- better safe than fast.
+
+    // Notice that we use our own background here, not the background used for
+    // the pages, because the tab row background must blend with the parent and
+    // so the background colour inherited from it (if any) must be used.
+    AutoHBRUSH hbr(wxColourToRGB(GetBackgroundColour()));
+
+    ::FillRect(hdc, &rc, hbr);
+
+    MSWDefWindowProc(WM_PAINT, (WPARAM)hdc, 0);
+
+    // At least for the top-aligned tabs, our background colour was overwritten
+    // and so we now replace the default background with our colour. This is
+    // horribly inefficient, of course, but seems to be the only way to do it.
+    if ( UseBgCol() )
+    {
+        SelectInHDC selectBrush(hdc, hbr);
+
+        // Find the point which must contain the default background colour:
+        // this is a hack, of course, but using this point "close" to the
+        // corner seems to work fine in practice.
+        int x = 0,
+            y = 0;
+
+        switch ( GetWindowStyle() & wxBK_ALIGN_MASK )
+        {
+            case wxBK_TOP:
+                x = rc.right - 2;
+                y = 2;
+                break;
+
+            case wxBK_BOTTOM:
+                x = rc.right - 2;
+                y = rc.bottom - 2;
+                break;
+
+            case wxBK_LEFT:
+                x = 2;
+                y = rc.bottom - 2;
+                break;
+
+            case wxBK_RIGHT:
+                x = 2;
+                y = rc.bottom - 2;
+                break;
+        }
+
+        ::ExtFloodFill(hdc, x, y, ::GetSysColor(COLOR_BTNFACE), FLOODFILLSURFACE);
+    }
+
+    // For some reason in RTL mode, source offset has to be -1, otherwise the
+    // right border (physical) remains unpainted.
+    const wxCoord ofs = dir == wxLayout_RightToLeft ? -1 : 0;
+    dc.Blit(ofs, 0, rc.right, rc.bottom, &memdc, ofs, 0);
+}
+
+#endif // USE_NOTEBOOK_ANTIFLICKER