diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 799b1588a1..8a9a2aa7bc 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -185,7 +185,6 @@ public: // -------------- void OnPaint(wxPaintEvent& event); - void OnEraseBackground(wxEraseEvent& event); #ifdef __WXWINCE__ void OnInitDialog(wxInitDialogEvent& event); #endif diff --git a/samples/erase/erase.cpp b/samples/erase/erase.cpp index cc6ca65d4f..d00ccf0de3 100644 --- a/samples/erase/erase.cpp +++ b/samples/erase/erase.cpp @@ -59,6 +59,8 @@ public: void UseBuffer(bool useBuffer) { m_useBuffer = useBuffer; Refresh(); } bool UsesBuffer() const { return m_useBuffer; } + void EraseBgInPaint(bool erase) { m_eraseBgInPaint = erase; Refresh(); } + private: void OnPaint( wxPaintEvent &event ); void OnChar( wxKeyEvent &event ); @@ -73,6 +75,9 @@ private: // use wxMemoryDC in OnPaint()? bool m_useBuffer; + // erase background in OnPaint()? + bool m_eraseBgInPaint; + DECLARE_EVENT_TABLE() }; @@ -84,6 +89,7 @@ public: private: void OnUseBuffer(wxCommandEvent& event); + void OnEraseBgInPaint(wxCommandEvent& event); void OnChangeBgStyle(wxCommandEvent& event); void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); @@ -113,6 +119,7 @@ enum { // menu items Erase_Menu_UseBuffer = 100, + Erase_Menu_EraseBgInPaint, Erase_Menu_BgStyleErase, Erase_Menu_BgStyleSystem, Erase_Menu_BgStylePaint, @@ -144,7 +151,8 @@ bool MyApp::OnInit() // ---------------------------------------------------------------------------- BEGIN_EVENT_TABLE(MyFrame, wxFrame) - EVT_MENU(Erase_Menu_UseBuffer, MyFrame::OnUseBuffer) + EVT_MENU(Erase_Menu_UseBuffer, MyFrame::OnUseBuffer) + EVT_MENU(Erase_Menu_EraseBgInPaint, MyFrame::OnEraseBgInPaint) EVT_MENU_RANGE(Erase_Menu_BgStyleErase, Erase_Menu_BgStylePaint, MyFrame::OnChangeBgStyle) @@ -165,6 +173,8 @@ MyFrame::MyFrame() wxMenu *menuFile = new wxMenu("", wxMENU_TEAROFF); menuFile->AppendCheckItem(Erase_Menu_UseBuffer, "&Use memory DC\tCtrl-M"); + menuFile->AppendCheckItem(Erase_Menu_EraseBgInPaint, + "&Erase background in EVT_PAINT\tCtrl-R"); menuFile->AppendSeparator(); menuFile->AppendRadioItem(Erase_Menu_BgStyleErase, "Use wxBG_STYLE_&ERASE\tCtrl-E"); @@ -194,6 +204,11 @@ void MyFrame::OnUseBuffer(wxCommandEvent& event) m_canvas->UseBuffer(event.IsChecked()); } +void MyFrame::OnEraseBgInPaint(wxCommandEvent& event) +{ + m_canvas->EraseBgInPaint(event.IsChecked()); +} + void MyFrame::OnChangeBgStyle(wxCommandEvent& event) { int style = wxBG_STYLE_ERASE + event.GetId() - Erase_Menu_BgStyleErase; @@ -233,6 +248,7 @@ MyCanvas::MyCanvas(wxFrame *parent) : wxScrolledWindow(parent, wxID_ANY) { m_useBuffer = false; + m_eraseBgInPaint = false; SetScrollbars( 10, 10, 40, 100, 0, 0 ); @@ -269,6 +285,20 @@ void MyCanvas::OnChar( wxKeyEvent &event ) void MyCanvas::DoPaint(wxDC& dc) { + if ( m_eraseBgInPaint ) + { + dc.SetBackground(*wxLIGHT_GREY); + dc.Clear(); + + dc.DrawText("Background erased in OnPaint", 65, 110); + } + else if ( GetBackgroundStyle() == wxBG_STYLE_PAINT ) + { + dc.SetTextForeground(*wxRED); + dc.DrawText("You must enable erasing background in OnPaint to avoid " + "display corruption", 65, 110); + } + dc.SetBrush( *wxBLACK_BRUSH ); dc.DrawRectangle( 10,10,60,50 ); diff --git a/src/msw/window.cpp b/src/msw/window.cpp index fbf9c4ced0..45a3767f01 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -413,7 +413,6 @@ wxCONSTRUCTOR_DUMMY(wxWindow) BEGIN_EVENT_TABLE(wxWindowMSW, wxWindowBase) EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged) - EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground) #ifdef __WXWINCE__ EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog) #endif @@ -4705,52 +4704,59 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event) } bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc) -{ - wxDCTemp dc(hdc, GetClientSize()); - wxDCTempImpl *impl = (wxDCTempImpl*) dc.GetImpl(); - - impl->SetHDC(hdc); - impl->SetWindow((wxWindow *)this); - - wxEraseEvent event(m_windowId, &dc); - event.SetEventObject(this); - bool rc = HandleWindowEvent(event); - - // must be called manually as ~wxDC doesn't do anything for wxDCTemp - impl->SelectOldObjects(hdc); - - return rc; -} - -void wxWindowMSW::OnEraseBackground(wxEraseEvent& event) { // standard non top level controls (i.e. except the dialogs) always erase // their background themselves in HandleCtlColor() or have some control- // specific ways to set the colours (common controls) if ( IsOfStandardClass() && !IsTopLevel() ) + return false; + + switch ( GetBackgroundStyle() ) { - event.Skip(); - return; + case wxBG_STYLE_ERASE: + // we need to generate an erase background event + { + wxDCTemp dc(hdc, GetClientSize()); + wxDCTempImpl *impl = (wxDCTempImpl*) dc.GetImpl(); + + impl->SetHDC(hdc); + impl->SetWindow((wxWindow *)this); + + wxEraseEvent event(m_windowId, &dc); + event.SetEventObject(this); + bool rc = HandleWindowEvent(event); + + // must be called manually as ~wxDC doesn't do anything for + // wxDCTemp + impl->SelectOldObjects(hdc); + + if ( rc ) + { + // background erase by the user-defined handler + return true; + } + } + // fall through + + case wxBG_STYLE_SYSTEM: + if ( !DoEraseBackground(hdc) ) + { + // let the default processing to take place if we didn't erase + // the background ourselves + return false; + } + break; + + case wxBG_STYLE_PAINT: + // no need to do anything here at all, background will be entirely + // redrawn in WM_PAINT handler + break; + + default: + wxFAIL_MSG( "unknown background style" ); } - if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM ) - { - // don't skip the event here, custom background means that the app - // is drawing it itself in its OnPaint(), so don't draw it at all - // now to avoid flicker - return; - } - - wxDC *dc = event.GetDC(); - if (!dc) return; - wxMSWDCImpl *impl = (wxMSWDCImpl*) dc->GetImpl(); - - // do default background painting - if ( !DoEraseBackground(GetHdcOf(*impl)) ) - { - // let the system paint the background - event.Skip(); - } + return true; } bool wxWindowMSW::DoEraseBackground(WXHDC hDC)