X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/14a6b6e5f0200192944ed3d35ef4a3ce4549ac70..5f3565a2fb3d678b03cf8547f37e56b1efe786f5:/src/msw/notebook.cpp diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index 36e746e7c8..f4614c1267 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -25,6 +25,7 @@ // wxWidgets #ifndef WX_PRECOMP #include "wx/string.h" + #include "wx/dc.h" #endif // WX_PRECOMP #include "wx/log.h" @@ -54,18 +55,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 // ---------------------------------------------------------------------------- @@ -126,7 +116,7 @@ wxBEGIN_FLAGS( wxNotebookStyle ) wxFLAGS_MEMBER(wxBORDER_RAISED) wxFLAGS_MEMBER(wxBORDER_STATIC) wxFLAGS_MEMBER(wxBORDER_NONE) - + // old style border flags wxFLAGS_MEMBER(wxSIMPLE_BORDER) wxFLAGS_MEMBER(wxSUNKEN_BORDER) @@ -173,7 +163,7 @@ wxEND_PROPERTIES_TABLE() wxBEGIN_HANDLERS_TABLE(wxNotebook) wxEND_HANDLERS_TABLE() -wxCONSTRUCTOR_5( wxNotebook , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle) +wxCONSTRUCTOR_5( wxNotebook , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle) wxBEGIN_PROPERTIES_TABLE(wxNotebookPageInfo) @@ -186,7 +176,7 @@ wxEND_PROPERTIES_TABLE() wxBEGIN_HANDLERS_TABLE(wxNotebookPageInfo) wxEND_HANDLERS_TABLE() -wxCONSTRUCTOR_4( wxNotebookPageInfo , wxNotebookPage* , Page , wxString , Text , bool , Selected , int , ImageId ) +wxCONSTRUCTOR_4( wxNotebookPageInfo , wxNotebookPage* , Page , wxString , Text , bool , Selected , int , ImageId ) #else IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl) @@ -220,6 +210,10 @@ void wxNotebook::Init() { m_imageList = NULL; m_nSelection = -1; + +#if wxUSE_UXTHEME + m_hbrBackground = NULL; +#endif // wxUSE_UXTHEME } // default for dynamic class @@ -249,20 +243,20 @@ bool wxNotebook::Create(wxWindow *parent, long style, const wxString& name) { - // Does ComCtl32 support non-top tabs? - int verComCtl32 = wxApp::GetComCtl32Version(); - if ( verComCtl32 < 470 || verComCtl32 >= 600 ) + // comctl32.dll 6.0 doesn't support non-top tabs with visual styles (the + // control is simply not rendered correctly), so disable them in this case + const int verComCtl32 = wxApp::GetComCtl32Version(); + if ( verComCtl32 == 600 ) { - if (style & wxNB_BOTTOM) - style &= ~wxNB_BOTTOM; - - if (style & wxNB_LEFT) - style &= ~wxNB_LEFT; - - if (style & wxNB_RIGHT) - style &= ~wxNB_RIGHT; + // check if we use themes at all -- if we don't, we're still ok +#if wxUSE_UXTHEME + if ( wxUxThemeEngine::GetIfActive() ) +#endif + { + style &= ~(wxNB_BOTTOM | wxNB_LEFT | wxNB_RIGHT); + } } - + if ( !CreateControl(parent, id, pos, size, style | wxTAB_TRAVERSAL, wxDefaultValidator, name) ) return false; @@ -270,8 +264,6 @@ bool wxNotebook::Create(wxWindow *parent, if ( !MSWCreateControl(WC_TABCONTROL, wxEmptyString, pos, size) ) return false; - SetBackgroundColour(wxColour(::GetSysColor(COLOR_BTNFACE))); - return true; } @@ -304,6 +296,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 // ---------------------------------------------------------------------------- @@ -323,7 +323,7 @@ int wxNotebook::GetRowCount() const int wxNotebook::SetSelection(size_t nPage) { - wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") ); + wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") ); if ( int(nPage) != m_nSelection ) { @@ -437,7 +437,7 @@ void wxNotebook::SetTabSize(const wxSize& sz) wxSize wxNotebook::CalcSizeFromPage(const wxSize& sizePage) const { wxSize sizeTotal = sizePage; - + // We need to make getting tab size part of the wxWidgets API. wxSize tabSize(0, 0); if (GetPageCount() > 0) @@ -509,8 +509,8 @@ wxNotebookPage *wxNotebook::DoRemovePage(size_t nPage) if (selNew != -1) { // No selection change, just refresh the current selection. - // Because it could be that the slection index changed - // we need to update it. + // Because it could be that the slection index changed + // we need to update it. // Note: this does not mean the selection it self changed. m_nSelection = selNew; m_pages[m_nSelection]->Refresh(); @@ -518,13 +518,13 @@ wxNotebookPage *wxNotebook::DoRemovePage(size_t nPage) else if (int(nPage) == m_nSelection) { // The selection was deleted. - + // Determine new selection. if (m_nSelection == int(GetPageCount())) selNew = m_nSelection - 1; else selNew = m_nSelection; - + // m_nSelection must be always valid so reset it before calling // SetSelection() m_nSelection = -1; @@ -553,6 +553,7 @@ bool wxNotebook::DeleteAllPages() m_nSelection = -1; + InvalidateBestSize(); return true; } @@ -570,27 +571,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 // ---------------------------- @@ -612,6 +592,16 @@ bool wxNotebook::InsertPage(size_t nPage, tcItem.pszText = (wxChar *)strText.c_str(); // const_cast } + // hide the page: unless it is selected, it shouldn't be shown (and if it + // is selected it will be shown later) + HWND hwnd = GetWinHwnd(pPage); + SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_VISIBLE); + + // this updates internal flag too -- otherwise it would get out of sync + // with the real state + pPage->Show(false); + + // fit the notebook page to the tab control's display area: this should be // done before adding it to the notebook or TabCtrl_InsertItem() will // change the notebooks size itself! @@ -637,16 +627,6 @@ bool wxNotebook::InsertPage(size_t nPage, AdjustPageSize(pPage); } - // hide the page: unless it is selected, it shouldn't be shown (and if it - // is selected it will be shown later) - HWND hwnd = GetWinHwnd(pPage); - SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_VISIBLE); - - // this updates internal flag too -- otherwise it would get out of sync - // with the real state - pPage->Show(false); - - // now deal with the selection // --------------------------- @@ -669,6 +649,7 @@ bool wxNotebook::InsertPage(size_t nPage, if ( selNew != -1 ) SetSelection(selNew); + InvalidateBestSize(); return true; } @@ -741,6 +722,10 @@ void wxNotebook::OnSize(wxSizeEvent& event) pPage->SetSize(rc.left, rc.top, width, height); } +#if wxUSE_UXTHEME + UpdateBgBrush(); +#endif // wxUSE_UXTHEME + event.Skip(); } @@ -875,6 +860,90 @@ void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event) } } +#if wxUSE_UXTHEME + +WXHANDLE wxNotebook::QueryBgBitmap(wxWindow *win) +{ + 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); + + if ( win ) + { + RECT rc2; + ::GetWindowRect(GetHwndOf(win), &rc2); + + COLORREF c = ::GetPixel(hDCMem, rc2.left - rc.left, rc2.top - rc.top); + + return (WXHANDLE)c; + } + else // we are asked to create the brush + { + return (WXHANDLE)::CreatePatternBrush(hBmp); + } +} + +void wxNotebook::UpdateBgBrush() +{ + if ( m_hbrBackground ) + ::DeleteObject((HBRUSH)m_hbrBackground); + + if ( !m_hasBgCol && wxUxThemeEngine::GetIfActive() ) + { + m_hbrBackground = (WXHBRUSH)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 *win) +{ + if ( m_hasBgCol ) + return GetBackgroundColour(); + + if ( !wxUxThemeEngine::GetIfActive() ) + return wxNullColour; + + COLORREF c = (COLORREF)QueryBgBitmap(win); + + return c == CLR_INVALID ? wxNullColour : wxRGBToColour(c); +} + +#endif // wxUSE_UXTHEME + // ---------------------------------------------------------------------------- // wxNotebook base class virtuals // ---------------------------------------------------------------------------- @@ -939,104 +1008,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