]> git.saurik.com Git - wxWidgets.git/commitdiff
Applied patch [ 1181975 ] [wxMSW] Removes all flicker from wxNotebook
authorJulian Smart <julian@anthemion.co.uk>
Tue, 19 Apr 2005 08:47:36 +0000 (08:47 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Tue, 19 Apr 2005 08:47:36 +0000 (08:47 +0000)
with modifications. Disabled until you set USE_NOTEBOOK_ANTIFLICKER
to 1. Also added code to refresh edges of the notebook to eliminate
droppings.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33743 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

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

index 1ddd735d415fa8520e0594630593cc7d9afa6d04..90c0fc7b813ab3f3a951fa9b92532e99659fadf5 100644 (file)
@@ -232,6 +232,11 @@ protected:
   WXHBRUSH m_hbrBackground;
 #endif // wxUSE_UXTHEME
 
+  // No need to optimize for WinCE
+#ifndef __WXWINCE__
+  void OnEraseBackground(wxEraseEvent& event);
+  void OnPaint(wxPaintEvent& event);
+#endif
 
   DECLARE_DYNAMIC_CLASS_NO_COPY(wxNotebook)
   DECLARE_EVENT_TABLE()
index 1f97d497b83f509404e2e37d0286a548d4ac97cb..e5b6a4c85a888ae84841271f2343ea4646957f5e 100644 (file)
@@ -35,6 +35,8 @@
 #include  "wx/notebook.h"
 #include  "wx/app.h"
 #include  "wx/sysopt.h"
+#include  "wx/dcclient.h"
+#include  "wx/dcmemory.h"
 
 #include  "wx/msw/private.h"
 
 // hide the ugly cast
 #define m_hwnd    (HWND)GetHWND()
 
+#ifdef __WXWINCE__
+#define USE_NOTEBOOK_ANTIFLICKER    0
+#else
+// Set this to 1 to compile anti-flicker code, which creates a potentially
+// large bitmap for every paint event
+#define USE_NOTEBOOK_ANTIFLICKER    0
+#endif
+
 // ----------------------------------------------------------------------------
 // constants
 // ----------------------------------------------------------------------------
@@ -93,6 +103,10 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
 
 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_SIZE(wxNotebook::OnSize)
     EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
@@ -180,6 +194,25 @@ IMPLEMENT_DYNAMIC_CLASS(wxNotebookPageInfo, wxObject )
 #endif
 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
 // ============================================================================
@@ -762,6 +795,30 @@ void wxNotebook::OnSize(wxSizeEvent& event)
         event.Skip();
         return;
     }
+#ifndef __WXWINCE__
+    else
+    {
+        // Without this, we can sometimes get droppings at the edges
+        // of a notebook, for example a notebook in a splitter window.
+        // This needs to be reconciled with the RefreshRect calls
+        // at the end of this function, which weren't enough to prevent
+        // the droppings.
+        
+        wxSize sz = GetClientSize();
+
+        // Refresh right side
+        wxRect rect(sz.x-4, 0, 4, sz.y);
+        RefreshRect(rect);
+        
+        // Refresh bottom side
+        rect = wxRect(0, sz.y-4, sz.x, 4);
+        RefreshRect(rect);
+        
+        // Refresh left side
+        rect = wxRect(0, 0, 4, sz.y);
+        RefreshRect(rect);
+    }
+#endif
 
     // fit all the notebook pages to the tab control's display area
 
@@ -1179,4 +1236,79 @@ bool wxNotebook::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result)
   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