Forbid creation of wxPaintEvent objects from user code

This doesn't work anyhow, so it's better to prevent the code doing this
from compiling instead of getting run-time asserts or worse.

Also simplify construction of these events inside wxWidgets by passing
the window itself to the ctor instead of passing just its ID and calling
SetEventObject() separately later.

For consistency, do the same thing for wxNcPaintEvent too.
This commit is contained in:
Vadim Zeitlin
2020-02-10 14:08:53 +01:00
parent b680ba9596
commit 8fcf46f65c
17 changed files with 65 additions and 46 deletions

View File

@@ -103,6 +103,10 @@ Changes in behaviour which may result in build errors
then you will need to add these libraries to your make or project files
yourself.
- wxPaintEvent objects can no longer be created by the application code. This
was never supposed to work and is now forbidden at compile-time instead of
resulting in errors during run-time.
- WXWIN_OS_DESCRIPTION doesn't exist any longer, use wxGetOsDescription().
- Never documented and not always available private wxGetClipboardData()

View File

@@ -2337,12 +2337,14 @@ private:
class WXDLLIMPEXP_CORE wxPaintEvent : public wxEvent
{
// This ctor is only intended to be used by wxWidgets itself, so it's
// intentionally declared as private when not building the library itself.
#ifdef WXBUILDING
public:
wxPaintEvent(int Id = 0)
: wxEvent(Id, wxEVT_PAINT)
{
}
#endif // WXBUILDING
explicit wxPaintEvent(wxWindowBase* window = NULL);
public:
// default copy ctor and dtor are fine
virtual wxEvent *Clone() const wxOVERRIDE { return new wxPaintEvent(*this); }
@@ -2353,11 +2355,14 @@ private:
class WXDLLIMPEXP_CORE wxNcPaintEvent : public wxEvent
{
// This ctor is only intended to be used by wxWidgets itself, so it's
// intentionally declared as private when not building the library itself.
#ifdef WXBUILDING
public:
wxNcPaintEvent(int winid = 0)
: wxEvent(winid, wxEVT_NC_PAINT)
{ }
#endif // WXBUILDING
explicit wxNcPaintEvent(wxWindowBase* window = NULL);
public:
virtual wxEvent *Clone() const wxOVERRIDE { return new wxNcPaintEvent(*this); }
private:

View File

@@ -2222,7 +2222,7 @@ public:
need a window to be repainted, use wxWindow::Refresh() instead of
trying to manually create an event of this class.
*/
wxPaintEvent(int id = 0);
explicit wxPaintEvent(wxWindow* window);
};

View File

@@ -458,6 +458,22 @@ wxString wxCommandEvent::GetString() const
return m_cmdString;
}
// ----------------------------------------------------------------------------
// wxPaintEvent and wxNcPaintEvent
// ----------------------------------------------------------------------------
wxPaintEvent::wxPaintEvent(wxWindowBase* window)
: wxEvent(window ? window->GetId() : 0, wxEVT_PAINT)
{
SetEventObject(window);
}
wxNcPaintEvent::wxNcPaintEvent(wxWindowBase* window)
: wxEvent(window ? window->GetId() : 0, wxEVT_NC_PAINT)
{
SetEventObject(window);
}
// ----------------------------------------------------------------------------
// wxUpdateUIEvent
// ----------------------------------------------------------------------------

View File

@@ -684,8 +684,7 @@ void wxWindowDFB::PaintWindow(const wxRect& rect)
// only send wxNcPaintEvent if drawing at least part of nonclient area:
if ( !clientRect.Contains(rect) )
{
wxNcPaintEvent eventNc(GetId());
eventNc.SetEventObject(this);
wxNcPaintEvent eventNc(this);
HandleWindowEvent(eventNc);
}
else
@@ -697,8 +696,7 @@ void wxWindowDFB::PaintWindow(const wxRect& rect)
// only send wxPaintEvent if drawing at least part of client area:
if ( rect.Intersects(clientRect) )
{
wxPaintEvent eventPt(GetId());
eventPt.SetEventObject(this);
wxPaintEvent eventPt(this);
HandleWindowEvent(eventPt);
}
else

View File

@@ -5205,12 +5205,10 @@ void wxWindowGTK::GTKSendPaintEvents(const GdkRegion* region)
wxFAIL_MSG( "unsupported background style" );
}
wxNcPaintEvent nc_paint_event( GetId() );
nc_paint_event.SetEventObject( this );
wxNcPaintEvent nc_paint_event( this );
HandleWindowEvent( nc_paint_event );
wxPaintEvent paint_event( GetId() );
paint_event.SetEventObject( this );
wxPaintEvent paint_event( this );
HandleWindowEvent( paint_event );
#if wxGTK_HAS_COMPOSITING_SUPPORT

View File

@@ -65,8 +65,7 @@ extern "C" {
static gint
gtk_glwindow_map_callback( GtkWidget * WXUNUSED(widget), wxGLCanvas *win )
{
wxPaintEvent event( win->GetId() );
event.SetEventObject( win );
wxPaintEvent event( win );
win->HandleWindowEvent( event );
win->GetUpdateRegion().Clear();
@@ -302,8 +301,7 @@ void wxGLCanvas::OnInternalIdle()
{
if (!m_updateRegion.IsEmpty())
{
wxPaintEvent event( GetId() );
event.SetEventObject( this );
wxPaintEvent event( this );
HandleWindowEvent( event );
GetUpdateRegion().Clear();

View File

@@ -3599,12 +3599,10 @@ void wxWindowGTK::GtkSendPaintEvents()
m_clearRegion.Clear();
}
wxNcPaintEvent nc_paint_event( GetId() );
nc_paint_event.SetEventObject( this );
wxNcPaintEvent nc_paint_event( this );
HandleWindowEvent( nc_paint_event );
wxPaintEvent paint_event( GetId() );
paint_event.SetEventObject( this );
wxPaintEvent paint_event( this );
HandleWindowEvent( paint_event );
m_clipPaintRegion = false;

View File

@@ -1621,8 +1621,7 @@ void wxWindow::DoPaint()
eraseEvent.SetEventObject(this);
HandleWindowEvent(eraseEvent);
wxPaintEvent event(GetId());
event.SetEventObject(this);
wxPaintEvent event(this);
HandleWindowEvent(event);
m_needsRefresh = false;

View File

@@ -5260,8 +5260,7 @@ bool wxWindowMSW::HandlePaint()
paintStack.push(PaintData(this));
wxPaintEvent event(m_windowId);
event.SetEventObject(this);
wxPaintEvent event(this);
bool processed = HandleWindowEvent(event);
@@ -5280,8 +5279,7 @@ bool wxWindowMSW::HandlePaint()
// note that we must generate NC event after the normal one as otherwise
// BeginPaint() will happily overwrite our decorations with the background
// colour
wxNcPaintEvent eventNc(m_windowId);
eventNc.SetEventObject(this);
wxNcPaintEvent eventNc(this);
HandleWindowEvent(eventNc);
// don't keep an HRGN we don't need any longer (GetUpdateRegion() can only

View File

@@ -1989,9 +1989,8 @@ bool wxWindowMac::MacDoRedraw( long time )
{
// paint the window itself
wxPaintEvent event(GetId());
wxPaintEvent event(this);
event.SetTimestamp(time);
event.SetEventObject(this);
handled = HandleWindowEvent(event);
}
@@ -2040,8 +2039,7 @@ void wxWindowMac::MacPaintChildrenBorders()
if ( m_updateRegion.Contains(clientOrigin.x+x-10, clientOrigin.y+y-10, w+20, h+20) )
{
// paint custom borders
wxNcPaintEvent eventNc( child->GetId() );
eventNc.SetEventObject( child );
wxNcPaintEvent eventNc( child );
if ( !child->HandleWindowEvent( eventNc ) )
{
child->MacPaintBorders(0, 0) ;

View File

@@ -62,7 +62,7 @@ void wxQtGLWidget::resizeGL(int w, int h)
void wxQtGLWidget::paintGL()
{
wxPaintEvent event( GetHandler()->GetId() );
wxPaintEvent event( GetHandler() );
EmitEvent(event);
}

View File

@@ -1281,8 +1281,7 @@ bool wxWindowQt::QtHandlePaintEvent ( QWidget *handler, QPaintEvent *event )
}
// send the paint event (wxWindowDC will draw directly):
wxPaintEvent paint( GetId() );
paint.SetEventObject(this);
wxPaintEvent paint( this );
handled = ProcessWindowEvent(paint);
m_updateRegion.Clear();
}

View File

@@ -216,8 +216,7 @@ long wxTopLevelWindow::GetDecorationsStyle() const
void wxTopLevelWindow::RefreshTitleBar()
{
wxNcPaintEvent event(GetId());
event.SetEventObject(this);
wxNcPaintEvent event(this);
GetEventHandler()->ProcessEvent(event);
}

View File

@@ -1282,8 +1282,7 @@ void wxWindowX11::SendPaintEvents()
m_clipPaintRegion = true;
wxPaintEvent paint_event( GetId() );
paint_event.SetEventObject( this );
wxPaintEvent paint_event( this );
HandleWindowEvent( paint_event );
m_updateRegion.Clear();
@@ -1324,8 +1323,7 @@ void wxWindowX11::SendNcPaintEvents()
}
}
wxNcPaintEvent nc_paint_event( GetId() );
nc_paint_event.SetEventObject( this );
wxNcPaintEvent nc_paint_event( this );
HandleWindowEvent( nc_paint_event );
m_updateNcArea = false;

View File

@@ -534,3 +534,14 @@ public:
void OnIdle(wxIdleEvent&) { }
};
#endif // C++11
// Another compilation-time-only test, but this one checking that these event
// objects can't be created from outside of the library.
#ifdef TEST_INVALID_EVENT_CREATION
void TestEventCreation()
{
wxPaintEvent eventPaint;
}
#endif // TEST_INVALID_EVENT_CREATION

View File

@@ -365,9 +365,9 @@ failtest_combobox:
failtest_evthandler:
@$(RM) test_evthandler.o
@for d in GLOBAL STATIC METHOD FUNCTOR NO_HANDLER DERIVED WRONG_CLASS; do \
if $(MAKE) CXXWARNINGS=-DTEST_INVALID_BIND_$$d test_evthandler.o 2>/dev/null; then \
echo "*** Compilation with TEST_INVALID_BIND_$$d unexpectedly succeeded.">&2; \
@for d in BIND_GLOBAL BIND_STATIC BIND_METHOD BIND_FUNCTOR BIND_NO_HANDLER BIND_DERIVED BIND_WRONG_CLASS EVENT_CREATION; do \
if $(MAKE) CXXWARNINGS=-DTEST_INVALID_$$d test_evthandler.o 2>/dev/null; then \
echo "*** Compilation with TEST_INVALID_$$d unexpectedly succeeded.">&2; \
exit 1; \
fi; \
done; \