From caf95d2aef2a88279df7f249d3b9440e18941d7d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 19 Nov 2004 18:36:45 +0000 Subject: [PATCH] added support for drawing themed background: DoEraseBackground() and GetThemeBackgroundBrush() git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30631 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/notebook.h | 33 ++++-- src/msw/notebook.cpp | 212 ++++++++++++++------------------------ 2 files changed, 100 insertions(+), 145 deletions(-) diff --git a/include/wx/msw/notebook.h b/include/wx/msw/notebook.h index 15ad5f884f..caa4a9f710 100644 --- a/include/wx/msw/notebook.h +++ b/include/wx/msw/notebook.h @@ -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) diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index e08843e33b..13c06febc0 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -54,18 +54,7 @@ #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 -- 2.47.2