fixed remains of notebook flickering (improved patch 1181975)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@34269 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -57,12 +57,14 @@
|
|||||||
// check that the page index is valid
|
// check that the page index is valid
|
||||||
#define IS_VALID_PAGE(nPage) ((nPage) < GetPageCount())
|
#define IS_VALID_PAGE(nPage) ((nPage) < GetPageCount())
|
||||||
|
|
||||||
|
// you can set USE_NOTEBOOK_ANTIFLICKER to 0 for desktop Windows versions too
|
||||||
|
// to disable code whih results in flicker-less notebook redrawing at the
|
||||||
|
// expense of some extra GDI resource consumption
|
||||||
#ifdef __WXWINCE__
|
#ifdef __WXWINCE__
|
||||||
#define USE_NOTEBOOK_ANTIFLICKER 0
|
// notebooks are never resized under CE anyhow
|
||||||
|
#define USE_NOTEBOOK_ANTIFLICKER 0
|
||||||
#else
|
#else
|
||||||
// Set this to 1 to compile anti-flicker code, which creates a potentially
|
#define USE_NOTEBOOK_ANTIFLICKER 1
|
||||||
// large bitmap for every paint event
|
|
||||||
#define USE_NOTEBOOK_ANTIFLICKER 0
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -82,6 +84,17 @@
|
|||||||
#define TCS_BOTTOM TCS_RIGHT
|
#define TCS_BOTTOM TCS_RIGHT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// global variables
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if USE_NOTEBOOK_ANTIFLICKER
|
||||||
|
|
||||||
|
// the pointer to standard spin button wnd proc
|
||||||
|
static WXFARPROC gs_wndprocNotebookSpinBtn = (WXFARPROC)NULL;
|
||||||
|
|
||||||
|
#endif // USE_NOTEBOOK_ANTIFLICKER
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// event table
|
// event table
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -94,13 +107,14 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
|
|||||||
DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
|
DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(wxNotebook, wxControl)
|
BEGIN_EVENT_TABLE(wxNotebook, wxControl)
|
||||||
#if USE_NOTEBOOK_ANTIFLICKER
|
|
||||||
EVT_ERASE_BACKGROUND(wxNotebook::OnEraseBackground)
|
|
||||||
EVT_PAINT(wxNotebook::OnPaint)
|
|
||||||
#endif
|
|
||||||
EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
|
EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
|
||||||
EVT_SIZE(wxNotebook::OnSize)
|
EVT_SIZE(wxNotebook::OnSize)
|
||||||
EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
|
EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
|
||||||
|
|
||||||
|
#if USE_NOTEBOOK_ANTIFLICKER
|
||||||
|
EVT_ERASE_BACKGROUND(wxNotebook::OnEraseBackground)
|
||||||
|
EVT_PAINT(wxNotebook::OnPaint)
|
||||||
|
#endif // USE_NOTEBOOK_ANTIFLICKER
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
#if wxUSE_EXTENDED_RTTI
|
#if wxUSE_EXTENDED_RTTI
|
||||||
@@ -185,25 +199,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxNotebookPageInfo, wxObject )
|
|||||||
#endif
|
#endif
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
|
IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// private functions
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#if USE_NOTEBOOK_ANTIFLICKER
|
|
||||||
// wnd proc for the spin button
|
|
||||||
LRESULT APIENTRY _EXPORT wxNotebookSpinBtnWndProc(HWND hWnd,
|
|
||||||
UINT message,
|
|
||||||
WPARAM wParam,
|
|
||||||
LPARAM lParam);
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// global vars
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// the pointer to standard spin button wnd proc
|
|
||||||
static WXFARPROC s_wndprocNotebookSpinBtn = (WXFARPROC)NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -771,6 +766,53 @@ int wxNotebook::HitTest(const wxPoint& pt, long *flags) const
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// if there is no special brush just use the solid background colour
|
||||||
|
HBRUSH hbr = (HBRUSH)m_hbrBackground;
|
||||||
|
if ( !hbr )
|
||||||
|
hbr = GetHbrushOf(wxBrush(GetBackgroundColour()));
|
||||||
|
|
||||||
|
::FillRect(GetHdcOf(memdc), &rc, hbr);
|
||||||
|
|
||||||
|
MSWDefWindowProc(WM_PAINT, (WPARAM)memdc.GetHDC(), 0);
|
||||||
|
|
||||||
|
dc.Blit(0, 0, rc.right, rc.bottom, &memdc, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_NOTEBOOK_ANTIFLICKER
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxNotebook callbacks
|
// wxNotebook callbacks
|
||||||
@@ -809,7 +851,7 @@ void wxNotebook::OnSize(wxSizeEvent& event)
|
|||||||
rect = wxRect(0, 0, 4, sz.y);
|
rect = wxRect(0, 0, 4, sz.y);
|
||||||
RefreshRect(rect);
|
RefreshRect(rect);
|
||||||
}
|
}
|
||||||
#endif
|
#endif // !__WXWINCE__
|
||||||
|
|
||||||
// fit all the notebook pages to the tab control's display area
|
// fit all the notebook pages to the tab control's display area
|
||||||
|
|
||||||
@@ -872,6 +914,32 @@ void wxNotebook::OnSize(wxSizeEvent& event)
|
|||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_NOTEBOOK_ANTIFLICKER
|
||||||
|
// subclass the spin control used by the notebook to scroll pages to
|
||||||
|
// prevent it from flickering on resize
|
||||||
|
if ( !gs_wndprocNotebookSpinBtn )
|
||||||
|
{
|
||||||
|
// iterate over all child windows to find spin button
|
||||||
|
for ( HWND child = ::GetWindow(GetHwnd(), GW_CHILD);
|
||||||
|
child;
|
||||||
|
child = ::GetWindow(child, GW_HWNDNEXT) )
|
||||||
|
{
|
||||||
|
wxWindow *childWindow = wxFindWinFromHandle((WXHWND)child);
|
||||||
|
|
||||||
|
// see if it exists, if no wxWindow found then assume it's the spin
|
||||||
|
// btn
|
||||||
|
if ( !childWindow )
|
||||||
|
{
|
||||||
|
// subclass the spin button to override WM_ERASEBKGND
|
||||||
|
gs_wndprocNotebookSpinBtn = (WXFARPROC)wxGetWindowProc(child);
|
||||||
|
|
||||||
|
wxSetWindowProc(child, wxNotebookSpinBtnWndProc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // USE_NOTEBOOK_ANTIFLICKER
|
||||||
|
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1251,78 +1319,4 @@ bool wxNotebook::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result)
|
|||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __WXWINCE__
|
|
||||||
void wxNotebook::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
|
|
||||||
{
|
|
||||||
// do nothing here
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event))
|
|
||||||
{
|
|
||||||
// Better painting behaviour, at the expense of system resources
|
|
||||||
#if USE_NOTEBOOK_ANTIFLICKER
|
|
||||||
wxPaintDC dc(this);
|
|
||||||
wxMemoryDC memdc;
|
|
||||||
RECT rc;
|
|
||||||
::GetClientRect(GetHwnd(), &rc);
|
|
||||||
wxBitmap bmp(rc.right, rc.bottom);
|
|
||||||
memdc.SelectObject(bmp);
|
|
||||||
|
|
||||||
// iterate over all child windows to find spin button
|
|
||||||
for ( HWND child = ::GetWindow(GetHwnd(), GW_CHILD);
|
|
||||||
child;
|
|
||||||
child = ::GetWindow(child, GW_HWNDNEXT) )
|
|
||||||
{
|
|
||||||
wxWindow *childWindow = wxFindWinFromHandle((WXHWND)child);
|
|
||||||
|
|
||||||
// see if it exists, if no wxWindow found then assume it's the spin btn
|
|
||||||
if ( !childWindow )
|
|
||||||
{
|
|
||||||
// subclass the spin button to override WM_ERASEBKGND
|
|
||||||
if ( !s_wndprocNotebookSpinBtn )
|
|
||||||
s_wndprocNotebookSpinBtn = (WXFARPROC)wxGetWindowProc(child);
|
|
||||||
|
|
||||||
wxSetWindowProc(child, wxNotebookSpinBtnWndProc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HBRUSH hbr = (HBRUSH)m_hbrBackground;
|
|
||||||
|
|
||||||
// if there is no special brush just use the solid background colour
|
|
||||||
wxBrush brush;
|
|
||||||
if ( !hbr )
|
|
||||||
{
|
|
||||||
brush = wxBrush(GetBackgroundColour());
|
|
||||||
hbr = GetHbrushOf(brush);
|
|
||||||
}
|
|
||||||
|
|
||||||
::FillRect(GetHdcOf(memdc), &rc, hbr);
|
|
||||||
|
|
||||||
MSWDefWindowProc(WM_PAINT, (WPARAM)memdc.GetHDC(), 0);
|
|
||||||
|
|
||||||
dc.Blit(0, 0, rc.right, rc.bottom, &memdc, 0, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// __WXWINCE__
|
|
||||||
|
|
||||||
#if USE_NOTEBOOK_ANTIFLICKER
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// window proc for spin button
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LRESULT APIENTRY _EXPORT wxNotebookSpinBtnWndProc(HWND hwnd,
|
|
||||||
UINT message,
|
|
||||||
WPARAM wParam,
|
|
||||||
LPARAM lParam)
|
|
||||||
{
|
|
||||||
if ( message == WM_ERASEBKGND )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return ::CallWindowProc(CASTWNDPROC s_wndprocNotebookSpinBtn, hwnd, message, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // USE_NOTEBOOK_ANTIFLICKER
|
|
||||||
|
|
||||||
#endif // wxUSE_NOTEBOOK
|
#endif // wxUSE_NOTEBOOK
|
||||||
|
Reference in New Issue
Block a user