X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/77ffb5937e89927b621128789401db8921fe580f..730d336601a3ece761b56e7c05d1099352670a25:/src/msw/notebook.cpp diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index 89446d2d6d..dcf8118edc 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -6,7 +6,7 @@ // Created: 11.06.98 // RCS-ID: $Id$ // Copyright: (c) 1998 Vadim Zeitlin -// Licence: wxWidgets licence +// Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) @@ -25,6 +25,7 @@ // wxWidgets #ifndef WX_PRECOMP #include "wx/string.h" + #include "wx/dc.h" #endif // WX_PRECOMP #include "wx/log.h" @@ -33,39 +34,24 @@ #include "wx/control.h" #include "wx/notebook.h" #include "wx/app.h" +#include "wx/sysopt.h" #include "wx/msw/private.h" -// Windows standard headers -#ifndef __WIN95__ - #error "wxNotebook is only supported Windows 95 and above" -#endif //Win95 - -#include // for SetWindowFont +#include #ifdef __GNUWIN32_OLD__ #include "wx/msw/gnuwin32/extra.h" #endif -#if defined(__WIN95__) && !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__)) +#if !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__)) #include #endif #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 // ---------------------------------------------------------------------------- @@ -108,9 +94,7 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING) BEGIN_EVENT_TABLE(wxNotebook, wxControl) EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange) - EVT_SIZE(wxNotebook::OnSize) - EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey) END_EVENT_TABLE() @@ -126,7 +110,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) @@ -149,6 +133,8 @@ wxBEGIN_FLAGS( wxNotebookStyle ) wxFLAGS_MEMBER(wxNB_LEFT) wxFLAGS_MEMBER(wxNB_RIGHT) wxFLAGS_MEMBER(wxNB_BOTTOM) + wxFLAGS_MEMBER(wxNB_NOPAGETHEME) + wxFLAGS_MEMBER(wxNB_FLAT) wxEND_FLAGS( wxNotebookStyle ) @@ -173,7 +159,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 +172,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) @@ -194,6 +180,25 @@ IMPLEMENT_DYNAMIC_CLASS(wxNotebookPageInfo, wxObject ) #endif IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent) +// ---------------------------------------------------------------------------- +// local functions +// ---------------------------------------------------------------------------- + +#ifndef __WXWINCE__ +// apparently DrawThemeBackground() modifies the rect passed to it and if we +// don't call this function there are some drawing artifacts which are only +// visible with some non default themes; so modify the rect here so that it +// still paints the correct area +static void AdjustRectForThemeBg(RECT& rc) +{ + // magic numbers needed to compensate for DrawThemeBackground() + rc.left -= 2; + rc.top -= 2; + rc.right += 4; + rc.bottom += 5; +} +#endif + // ============================================================================ // implementation // ============================================================================ @@ -220,6 +225,10 @@ void wxNotebook::Init() { m_imageList = NULL; m_nSelection = -1; + +#if wxUSE_UXTHEME + m_hbrBackground = NULL; +#endif // wxUSE_UXTHEME } // default for dynamic class @@ -249,29 +258,90 @@ 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 ) +#ifdef __WXWINCE__ + // Not sure why, but without this style, there is no border + // around the notebook tabs. + if (style & wxNB_FLAT) + style |= wxBORDER_SUNKEN; +#endif + + // 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); + } } - + + LPCTSTR className = WC_TABCONTROL; + + // SysTabCtl32 class has natively CS_HREDRAW and CS_VREDRAW enabled and it + // causes horrible flicker when resizing notebook, so get rid of it by + // using a class without these styles (but otherwise identical to it) + if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) ) + { + static ClassRegistrar s_clsNotebook; + if ( !s_clsNotebook.IsInitialized() ) + { + // get a copy of standard class and modify it + WNDCLASS wc; + + if ( ::GetClassInfo(::GetModuleHandle(NULL), WC_TABCONTROL, &wc) ) + { + wc.lpszClassName = wxT("_wx_SysTabCtl32"); + wc.style &= ~(CS_HREDRAW | CS_VREDRAW); + + s_clsNotebook.Register(wc); + } + else + { + wxLogLastError(_T("GetClassInfoEx(SysTabCtl32)")); + } + } + + // use our custom class if available but fall back to the standard + // notebook if we failed to register it + if ( s_clsNotebook.IsRegistered() ) + { + // it's ok to use c_str() here as the static s_clsNotebook object + // has sufficiently long lifetime + className = s_clsNotebook.GetName().c_str(); + } + } + if ( !CreateControl(parent, id, pos, size, style | wxTAB_TRAVERSAL, wxDefaultValidator, name) ) return false; - if ( !MSWCreateControl(WC_TABCONTROL, wxEmptyString, pos, size) ) + if ( !MSWCreateControl(className, wxEmptyString, pos, size) ) return false; - SetBackgroundColour(wxColour(::GetSysColor(COLOR_BTNFACE))); +#if wxUSE_UXTHEME + if ( HasFlag(wxNB_NOPAGETHEME) || + wxSystemOptions::IsFalse(wxT("msw.notebook.themed-background")) ) + { + SetBackgroundColour(GetThemeBackgroundColour()); + } +#endif // wxUSE_UXTHEME + // Undocumented hack to get flat notebook style + // In fact, we should probably only do this in some + // curcumstances, i.e. if we know we will have a border + // at the bottom (the tab control doesn't draw it itself) +#if defined(__POCKETPC__) || defined(__SMARTPHONE__) + if (HasFlag(wxNB_FLAT)) + { + SendMessage(m_hwnd, CCM_SETVERSION, COMCTL32_VERSION, 0); + if (!m_hasBgCol) + SetBackgroundColour(*wxWHITE); + } +#endif return true; } @@ -291,7 +361,7 @@ WXDWORD wxNotebook::MSWGetStyle(long style, WXDWORD *exstyle) const else if ( style & wxNB_LEFT ) tabStyle |= TCS_VERTICAL; else if ( style & wxNB_RIGHT ) - tabStyle |= TCS_VERTICAL | TCS_RIGHT; + tabStyle |= TCS_VERTICAL | TCS_RIGHT; // ex style if ( exstyle ) @@ -304,6 +374,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 +401,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,9 +515,9 @@ 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); + wxSize tabSize; if (GetPageCount() > 0) { RECT rect; @@ -471,9 +549,18 @@ void wxNotebook::AdjustPageSize(wxNotebookPage *page) // get the page size from the notebook size GetSize((int *)&rc.right, (int *)&rc.bottom); - TabCtrl_AdjustRect(m_hwnd, false, &rc); - page->SetSize(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); + // This check is to work around a bug in TabCtrl_AdjustRect which will + // cause a crash on win2k, or on XP with themes disabled, if the + // wxNB_MULTILINE style is used and the rectangle is very small, (such as + // when the notebook is first created.) The value of 20 is just + // arbitrarily chosen, if there is a better way to determine this value + // then please do so. --RD + if (rc.right > 20 && rc.bottom > 20) + { + TabCtrl_AdjustRect(m_hwnd, false, &rc); + page->SetSize(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); + } } // ---------------------------------------------------------------------------- @@ -500,8 +587,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(); @@ -509,13 +596,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; @@ -544,6 +631,7 @@ bool wxNotebook::DeleteAllPages() m_nSelection = -1; + InvalidateBestSize(); return true; } @@ -561,27 +649,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 // ---------------------------- @@ -597,12 +664,22 @@ bool wxNotebook::InsertPage(size_t nPage, } // and the text - if ( !strText.IsEmpty() ) + if ( !strText.empty() ) { tcItem.mask |= TCIF_TEXT; 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! @@ -628,16 +705,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 // --------------------------- @@ -660,6 +727,8 @@ bool wxNotebook::InsertPage(size_t nPage, if ( selNew != -1 ) SetSelection(selNew); + InvalidateBestSize(); + return true; } @@ -694,45 +763,77 @@ int wxNotebook::HitTest(const wxPoint& pt, long *flags) const void wxNotebook::OnSize(wxSizeEvent& event) { - // fit the notebook page to the tab control's display area - RECT rc; - rc.left = rc.top = 0; - GetSize((int *)&rc.right, (int *)&rc.bottom); - - // there seems to be a bug in the implementation of TabCtrl_AdjustRect(): it - // returns completely false values for multiline tab controls after the tabs - // are added but before getting the first WM_SIZE (off by ~50 pixels, see - // - // http://sf.net/tracker/index.php?func=detail&aid=645323&group_id=9863&atid=109863 - // - // and the only work around I could find was this ugly hack... without it - // simply toggling the "multiline" checkbox in the notebook sample resulted - // in a noticeable page displacement - if ( HasFlag(wxNB_MULTILINE) ) - { - // avoid an infinite recursion: we get another notification too! - static bool s_isInOnSize = false; +#if wxUSE_UXTHEME + // background bitmap size has changed, update the brush using it too + UpdateBgBrush(); +#endif // wxUSE_UXTHEME - if ( !s_isInOnSize ) - { - s_isInOnSize = true; - SendMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED, - MAKELPARAM(rc.right, rc.bottom)); - s_isInOnSize = false; - } - } + if ( GetPageCount() == 0 ) + { + // Prevents droppings on resize, but does cause some flicker + // when there are no pages. + Refresh(false); + event.Skip(); + return; + } - TabCtrl_AdjustRect(m_hwnd, false, &rc); + // fit all the notebook pages to the tab control's display area - int width = rc.right - rc.left, - height = rc.bottom - rc.top; - size_t nCount = m_pages.Count(); - for ( size_t nPage = 0; nPage < nCount; nPage++ ) { - wxNotebookPage *pPage = m_pages[nPage]; - pPage->SetSize(rc.left, rc.top, width, height); - } + RECT rc; + rc.left = rc.top = 0; + GetSize((int *)&rc.right, (int *)&rc.bottom); - event.Skip(); + // save the total size, we'll use it below + int widthNbook = rc.right - rc.left, + heightNbook = rc.bottom - rc.top; + + // there seems to be a bug in the implementation of TabCtrl_AdjustRect(): it + // returns completely false values for multiline tab controls after the tabs + // are added but before getting the first WM_SIZE (off by ~50 pixels, see + // + // http://sf.net/tracker/index.php?func=detail&aid=645323&group_id=9863&atid=109863 + // + // and the only work around I could find was this ugly hack... without it + // simply toggling the "multiline" checkbox in the notebook sample resulted + // in a noticeable page displacement + if ( HasFlag(wxNB_MULTILINE) ) + { + // avoid an infinite recursion: we get another notification too! + static bool s_isInOnSize = false; + + if ( !s_isInOnSize ) + { + s_isInOnSize = true; + SendMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED, + MAKELPARAM(rc.right, rc.bottom)); + s_isInOnSize = false; + } + } + + TabCtrl_AdjustRect(m_hwnd, false, &rc); + + int width = rc.right - rc.left, + height = rc.bottom - rc.top; + size_t nCount = m_pages.Count(); + for ( size_t nPage = 0; nPage < nCount; nPage++ ) { + wxNotebookPage *pPage = m_pages[nPage]; + pPage->SetSize(rc.left, rc.top, width, height); + } + + + // unless we had already repainted everything, we now need to refresh + if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) ) + { + // invalidate areas not covered by pages + RefreshRect(wxRect(0, 0, widthNbook, rc.top), false); + RefreshRect(wxRect(0, rc.top, rc.left, height), false); + RefreshRect(wxRect(0, rc.bottom, widthNbook, heightNbook - rc.bottom), + false); + RefreshRect(wxRect(rc.right, rc.top, widthNbook - rc.bottom, height), + false); + } + + event.Skip(); } void wxNotebook::OnSelChange(wxNotebookEvent& event) @@ -866,77 +967,146 @@ void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event) } } -// ---------------------------------------------------------------------------- -// wxNotebook base class virtuals -// ---------------------------------------------------------------------------- +#if wxUSE_UXTHEME -#if wxUSE_CONSTRAINTS +WXHBRUSH wxNotebook::QueryBgBitmap() +{ + RECT rc; + ::GetClientRect(GetHwnd(), &rc); -// override these 2 functions to do nothing: everything is done in OnSize + // adjust position + TabCtrl_AdjustRect(GetHwnd(), false, &rc); -void wxNotebook::SetConstraintSizes(bool WXUNUSED(recurse)) -{ - // don't set the sizes of the pages - their correct size is not yet known - wxControl::SetConstraintSizes(false); + WindowHDC hDC(GetHwnd()); + MemoryHDC hDCMem(hDC); + CompatibleBitmap hBmp(hDC, rc.right, rc.bottom); + + SelectInHDC selectBmp(hDCMem, hBmp); + + wxUxThemeHandle theme(this, L"TAB"); + if ( theme ) + { + AdjustRectForThemeBg(rc); + + wxUxThemeEngine::Get()->DrawThemeBackground + ( + theme, + (WXHDC)hDCMem, + 9 /* TABP_PANE */, + 0, + &rc, + NULL + ); + } + + return (WXHBRUSH)::CreatePatternBrush(hBmp); } -bool wxNotebook::DoPhase(int WXUNUSED(nPhase)) +void wxNotebook::UpdateBgBrush() { - return true; + if ( m_hbrBackground ) + ::DeleteObject((HBRUSH)m_hbrBackground); + + if ( !m_hasBgCol && wxUxThemeEngine::GetIfActive() ) + { + m_hbrBackground = QueryBgBitmap(); + } + else // no themes + { + m_hbrBackground = NULL; + } } -#endif // wxUSE_CONSTRAINTS +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); -// ---------------------------------------------------------------------------- -// wxNotebook Windows message handlers -// ---------------------------------------------------------------------------- + ::MapWindowPoints(NULL, GetHwnd(), (POINT *)&rc, 1); -bool wxNotebook::MSWOnScroll(int orientation, WXWORD nSBCode, - WXWORD pos, WXHWND control) + 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 *WXUNUSED(win)) { - // don't generate EVT_SCROLLWIN events for the WM_SCROLLs coming from the - // up-down control - if ( control ) - return false; + if ( m_hasBgCol ) + return GetBackgroundColour(); + + // Experimental: don't do this since we're doing it in wxPanel +#if 0 // defined(__POCKETPC__) || defined(__SMARTPHONE__) + // For some reason, the pages will be grey by default. + // Normally they should be white on these platforms. + // (However the static control backgrounds are painted + // in the correct colour, just not the rest of it.) + // So let's give WinCE a hint. + else if (!win->m_hasBgCol) + return *wxWHITE; +#endif - return wxNotebookBase::MSWOnScroll(orientation, nSBCode, pos, control); + if ( !wxUxThemeEngine::GetIfActive() ) + return wxNullColour; + + return GetThemeBackgroundColour(); } -bool wxNotebook::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result) +bool +wxNotebook::MSWPrintChild(wxWindow *win, + WXWPARAM wParam, + WXLPARAM WXUNUSED(lParam)) { - wxNotebookEvent event(wxEVT_NULL, m_windowId); + // Don't paint the theme for the child if we have a solid background + if ( m_hasBgCol ) + return false; - NMHDR* hdr = (NMHDR *)lParam; - switch ( hdr->code ) { - case TCN_SELCHANGE: - event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED); - break; - case TCN_SELCHANGING: - event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING); - break; + RECT rc; + ::GetClientRect(GetHwnd(), &rc); - default: - return wxControl::MSWOnNotify(idCtrl, lParam, result); - } + // adjust position + TabCtrl_AdjustRect(GetHwnd(), false, &rc); - event.SetSelection(TabCtrl_GetCurSel(m_hwnd)); - event.SetOldSelection(m_nSelection); - event.SetEventObject(this); - event.SetInt(idCtrl); + wxUxThemeHandle theme(win, L"TAB"); + if ( theme ) + { + // map from this client to win client coords + ::MapWindowPoints(GetHwnd(), GetHwndOf(win), (POINT *)&rc, 2); + + AdjustRectForThemeBg(rc); + wxUxThemeEngine::Get()->DrawThemeBackground + ( + theme, + (WXHDC)wParam, + 9 /* TABP_PANE */, + 0, + &rc, + NULL + ); + } - bool processed = GetEventHandler()->ProcessEvent(event); - *result = !event.IsAllowed(); - return processed; + return true; } +#endif // wxUSE_UXTHEME + // Windows only: attempts to get colour for UX theme page background -wxColour wxNotebook::GetThemeBackgroundColour() +wxColour wxNotebook::GetThemeBackgroundColour() const { #if wxUSE_UXTHEME if (wxUxThemeEngine::Get()) { - wxUxThemeHandle hTheme(this, L"TAB"); + wxUxThemeHandle hTheme((wxNotebook*) this, L"TAB"); if (hTheme) { // This is total guesswork. @@ -968,8 +1138,7 @@ wxColour wxNotebook::GetThemeBackgroundColour() &themeColor); } - wxColour colour(GetRValue(themeColor), GetGValue(themeColor), GetBValue(themeColor)); - return colour; + return wxRGBToColour(themeColor); } } #endif // wxUSE_UXTHEME @@ -977,57 +1146,68 @@ wxColour wxNotebook::GetThemeBackgroundColour() 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 +// ---------------------------------------------------------------------------- +// wxNotebook base class virtuals +// ---------------------------------------------------------------------------- + +#if wxUSE_CONSTRAINTS + +// override these 2 functions to do nothing: everything is done in OnSize + +void wxNotebook::SetConstraintSizes(bool WXUNUSED(recurse)) { -#if wxUSE_UXTHEME + // don't set the sizes of the pages - their correct size is not yet known + wxControl::SetConstraintSizes(false); +} - window->ApplyParentThemeBackground(colour); - - for ( wxWindowList::compatibility_iterator node = window->GetChildren().GetFirst(); node; node = node->GetNext() ) - { - wxWindow *child = node->GetData(); - ApplyThemeBackground(child, colour); - } -#endif +bool wxNotebook::DoPhase(int WXUNUSED(nPhase)) +{ + return true; } -#if wxUSE_UXTHEME -WXLRESULT wxNotebook::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) +#endif // wxUSE_CONSTRAINTS + +// ---------------------------------------------------------------------------- +// wxNotebook Windows message handlers +// ---------------------------------------------------------------------------- + +bool wxNotebook::MSWOnScroll(int orientation, WXWORD nSBCode, + WXWORD pos, WXHWND control) { - static bool g_TestedForTheme = false; - static bool g_supportsThemes = false; - switch ( nMsg ) - { - case WM_ERASEBKGND: - { - if (!g_TestedForTheme) - { - int commCtrlVersion = wxTheApp->GetComCtl32Version() ; + // don't generate EVT_SCROLLWIN events for the WM_SCROLLs coming from the + // up-down control + if ( control ) + return false; - g_supportsThemes = (commCtrlVersion >= 600); - g_TestedForTheme = true; - } + return wxNotebookBase::MSWOnScroll(orientation, nSBCode, pos, control); +} - // 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; - } - } - } - } +bool wxNotebook::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result) +{ + wxNotebookEvent event(wxEVT_NULL, m_windowId); + + NMHDR* hdr = (NMHDR *)lParam; + switch ( hdr->code ) { + case TCN_SELCHANGE: + event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED); + break; - return wxControl::MSWWindowProc(nMsg, wParam, lParam); + case TCN_SELCHANGING: + event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING); + break; + + default: + return wxControl::MSWOnNotify(idCtrl, lParam, result); + } + + event.SetSelection(TabCtrl_GetCurSel(m_hwnd)); + event.SetOldSelection(m_nSelection); + event.SetEventObject(this); + event.SetInt(idCtrl); + + bool processed = GetEventHandler()->ProcessEvent(event); + *result = !event.IsAllowed(); + return processed; } -#endif // #if wxUSE_UXTHEME #endif // wxUSE_NOTEBOOK