]> git.saurik.com Git - wxWidgets.git/commitdiff
added support for drawing themed background: DoEraseBackground() and GetThemeBackgrou...
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 19 Nov 2004 18:36:45 +0000 (18:36 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 19 Nov 2004 18:36:45 +0000 (18:36 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30631 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/notebook.h
src/msw/notebook.cpp

index 15ad5f884fba4bb0ee08dc12f0c6cf65c584dd90..caa4a9f7100b43a943e41646653bd9a64c0fa83b 100644 (file)
@@ -72,6 +72,7 @@ public:
               const wxSize& size = wxDefaultSize,
               long style = 0,
               const wxString& name = wxNOTEBOOK_NAME);
+  virtual ~wxNotebook();
 
   // accessors
   // ---------
@@ -111,9 +112,6 @@ public:
     // set the padding between tabs (in pixels)
   void SetPadding(const wxSize& padding);
 
-    // Windows only: attempts to get colour for UX theme page background
-  wxColour GetThemeBackgroundColour();
-
   // operations
   // ----------
     // remove all pages
@@ -134,9 +132,6 @@ public:
     // style.
   void SetTabSize(const wxSize& sz);
 
-    // Windows only: attempts to apply the UX theme page background to this page
-  void ApplyThemeBackground(wxWindow* window, const wxColour& colour);
-
     // hit test
   virtual int HitTest(const wxPoint& pt, long *flags = NULL) const;
 
@@ -162,6 +157,19 @@ public:
   virtual bool DoPhase(int nPhase);
 #endif // wxUSE_CONSTRAINTS
 
+
+  // implementation only
+  // -------------------
+
+#if wxUSE_UXTHEME
+  // handler for child pages erase background event
+  void DoEraseBackground(wxEraseEvent& event);
+
+  // get the brush to be used for painting the background for the controls
+  // which need it in their MSWControlColor()
+  WXHBRUSH GetThemeBackgroundBrush() const { return m_hbrBackground; }
+#endif // wxUSE_UXTHEME
+
 protected:
   // common part of all ctors
   void Init();
@@ -175,15 +183,20 @@ protected:
   // set the size of the given page to fit in the notebook
   void AdjustPageSize(wxNotebookPage *page);
 
-    // override WndProc.
 #if wxUSE_UXTHEME
-    virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
-#endif
+  // creates the brush to be used for drawing the tab control background
+  void UpdateBgBrush();
+#endif // wxUSE_UXTHEME
 
   // the current selection (-1 if none)
   int m_nSelection;
 
-  wxNotebookPageInfoList m_pageInfos ;
+  wxNotebookPageInfoList m_pageInfos;
+
+#if wxUSE_UXTHEME
+  // background brush used to paint the tab control
+  WXHBRUSH m_hbrBackground;
+#endif // wxUSE_UXTHEME
 
 
   DECLARE_DYNAMIC_CLASS_NO_COPY(wxNotebook)
index e08843e33b63759fd9b2421df9301d460cf0b6a7..13c06febc05a6001d1d52f6249ae358add205b18 100644 (file)
 #include "wx/msw/winundef.h"
 
 #if wxUSE_UXTHEME
-#include "wx/msw/uxtheme.h"
-
-#include "wx/radiobut.h"
-#include "wx/radiobox.h"
-#include "wx/checkbox.h"
-#include "wx/bmpbuttn.h"
-#include "wx/statline.h"
-#include "wx/statbox.h"
-#include "wx/stattext.h"
-#include "wx/slider.h"
-#include "wx/scrolwin.h"
-#include "wx/panel.h"
+    #include "wx/msw/uxtheme.h"
 #endif
 
 // ----------------------------------------------------------------------------
@@ -220,6 +209,10 @@ void wxNotebook::Init()
 {
   m_imageList = NULL;
   m_nSelection = -1;
+
+#if wxUSE_UXTHEME
+  m_hbrBackground = NULL;
+#endif // wxUSE_UXTHEME
 }
 
 // default for dynamic class
@@ -270,8 +263,6 @@ bool wxNotebook::Create(wxWindow *parent,
     if ( !MSWCreateControl(WC_TABCONTROL, wxEmptyString, pos, size) )
         return false;
 
-    SetBackgroundColour(wxColour(::GetSysColor(COLOR_BTNFACE)));
-
     return true;
 }
 
@@ -304,6 +295,14 @@ WXDWORD wxNotebook::MSWGetStyle(long style, WXDWORD *exstyle) const
     return tabStyle;
 }
 
+wxNotebook::~wxNotebook()
+{
+#if wxUSE_UXTHEME
+    if ( m_hbrBackground )
+        ::DeleteObject((HBRUSH)m_hbrBackground);
+#endif // wxUSE_UXTHEME
+}
+
 // ----------------------------------------------------------------------------
 // wxNotebook accessors
 // ----------------------------------------------------------------------------
@@ -571,27 +570,6 @@ bool wxNotebook::InsertPage(size_t nPage,
     wxASSERT_MSG( pPage->GetParent() == this,
                     _T("notebook pages must have notebook as parent") );
 
-#if wxUSE_UXTHEME && wxUSE_UXTHEME_AUTO
-    static bool g_TestedForTheme = false;
-    static bool g_UseTheme = false;
-    if (!g_TestedForTheme)
-    {
-        int commCtrlVersion = wxTheApp->GetComCtl32Version() ;
-
-        g_UseTheme = (commCtrlVersion >= 600);
-        g_TestedForTheme = true;
-    }
-
-    // Automatically apply the theme background,
-    // changing the colour of the panel to match the
-    // tab page colour. This won't work well with all
-    // themes but it's a start.
-    if (g_UseTheme && wxUxThemeEngine::Get() && pPage->IsKindOf(CLASSINFO(wxPanel)))
-    {
-        ApplyThemeBackground(pPage, GetThemeBackgroundColour());
-    }
-#endif
-
     // add a new tab to the control
     // ----------------------------
 
@@ -743,6 +721,10 @@ void wxNotebook::OnSize(wxSizeEvent& event)
     pPage->SetSize(rc.left, rc.top, width, height);
   }
 
+#if wxUSE_UXTHEME
+  UpdateBgBrush();
+#endif // wxUSE_UXTHEME
+
   event.Skip();
 }
 
@@ -877,6 +859,66 @@ void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
     }
 }
 
+#if wxUSE_UXTHEME
+
+void wxNotebook::UpdateBgBrush()
+{
+    if ( m_hbrBackground )
+        ::DeleteObject((HBRUSH)m_hbrBackground);
+
+    if ( wxUxThemeEngine::GetIfActive() )
+    {
+        RECT rc;
+        GetWindowRect(GetHwnd(), &rc);
+
+        WindowHDC hDC(GetHwnd());
+        MemoryHDC hDCMem(hDC);
+        CompatibleBitmap hBmp(hDC, rc.right - rc.left, rc.bottom - rc.top);
+
+        SelectInHDC selectBmp(hDCMem, hBmp);
+
+        SendMessage(GetHwnd(), WM_PRINTCLIENT, (WPARAM)(HDC)hDCMem, 
+                    PRF_ERASEBKGND | PRF_CLIENT | PRF_NONCLIENT);
+
+        m_hbrBackground = (WXHBRUSH)::CreatePatternBrush(hBmp);
+    }
+    else // no themes
+    {
+        m_hbrBackground = NULL;
+    }
+}
+
+void wxNotebook::DoEraseBackground(wxEraseEvent& event)
+{
+    // we can either draw the background ourselves or let DrawThemeBackground()
+    // do it, but as we already have the correct brush, let's do it ourselves
+    // (note that we use the same code in wxControl::MSWControlColor(), so if
+    // it breaks, it should at least break in consistent way)
+    if ( m_hbrBackground )
+    {
+        // before drawing with the background brush, we need to position it
+        // correctly
+        wxWindow *win = (wxWindow *)event.GetEventObject();
+
+        RECT rc;
+        ::GetWindowRect(GetHwndOf(win), &rc);
+
+        ::MapWindowPoints(NULL, GetHwnd(), (POINT *)&rc, 1);
+
+        HDC hdc = GetHdcOf(*event.GetDC());
+        if ( !::SetBrushOrgEx(hdc, -rc.left, -rc.top, NULL) )
+        {
+            wxLogLastError(_T("SetBrushOrgEx(notebook bg brush)"));
+        }
+
+        RECT rectClient;
+        ::GetClientRect(GetHwndOf(win), &rectClient);
+        ::FillRect(hdc, &rectClient, (HBRUSH)m_hbrBackground);
+    }
+}
+
+#endif // wxUSE_UXTHEME
+
 // ----------------------------------------------------------------------------
 // wxNotebook base class virtuals
 // ----------------------------------------------------------------------------
@@ -941,104 +983,4 @@ bool wxNotebook::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result)
   return processed;
 }
 
-// Windows only: attempts to get colour for UX theme page background
-wxColour wxNotebook::GetThemeBackgroundColour()
-{
-#if wxUSE_UXTHEME
-    if (wxUxThemeEngine::Get())
-    {
-        wxUxThemeHandle hTheme(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);
-            }
-
-            wxColour colour(GetRValue(themeColor), GetGValue(themeColor), GetBValue(themeColor));
-            return colour;
-        }
-    }
-#endif // wxUSE_UXTHEME
-
-    return GetBackgroundColour();
-}
-
-// Windows only: attempts to apply the UX theme page background to this page
-#if wxUSE_UXTHEME
-void wxNotebook::ApplyThemeBackground(wxWindow* window, const wxColour& colour)
-#else
-void wxNotebook::ApplyThemeBackground(wxWindow*, const wxColour&)
-#endif
-{
-#if wxUSE_UXTHEME
-
-    window->ApplyParentThemeBackground(colour);
-
-    for ( wxWindowList::compatibility_iterator node = window->GetChildren().GetFirst(); node; node = node->GetNext() )
-    {
-        wxWindow *child = node->GetData();
-        ApplyThemeBackground(child, colour);
-    }
-#endif
-}
-
-#if wxUSE_UXTHEME
-WXLRESULT wxNotebook::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
-{
-    static bool g_TestedForTheme = false;
-    static bool g_supportsThemes = false;
-    switch ( nMsg )
-    {
-        case WM_ERASEBKGND:
-        {
-            if (!g_TestedForTheme)
-            {
-                int commCtrlVersion = wxTheApp->GetComCtl32Version() ;
-
-                g_supportsThemes = (commCtrlVersion >= 600);
-                g_TestedForTheme = true;
-            }
-
-            // If currently an XP theme is active, it seems we can get away
-            // with not drawing a background, which reduces flicker.
-            if (g_supportsThemes)
-            {
-                wxUxThemeEngine *p = wxUxThemeEngine::Get();
-                if (p && p->IsThemeActive() )
-                {
-                    return true;
-                }
-            }
-        }
-    }
-
-    return wxControl::MSWWindowProc(nMsg, wParam, lParam);
-}
-#endif // #if wxUSE_UXTHEME
-
 #endif // wxUSE_NOTEBOOK