Allow to not create wxPaintDC in EVT_PAINT handler in wxMSW.

Failure to create a wxPaintDC in EVT_PAINT handler resulted in many serious
and difficult to debug problems under wxMSW. We used to document that the user
shouldn't do it but this wasn't enough (see #11648). We could also assert if
we detected that a handler didn't create a wxPaintDC but it seems better to
just handle this case gracefully for consistency with the other platforms.

Add wxDidCreatePaintDC global variable which is reset before generating
wxPaintEvent and set to true when ::BeginPaint() is called from wxPaintDC
ctor and validate the update region of the window ourselves if it wasn't set
(meaning that wxPaintDC wasn't created).

Update the documentation to emphasize the link between EVT_PAINT handlers and
wxPaintDC but without saying that wxPaintDC object must always be created in
the handler as this is not true any more.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63229 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2010-01-23 13:22:25 +00:00
parent 975fb32b5c
commit 7ca106e860
4 changed files with 37 additions and 10 deletions

View File

@@ -1547,16 +1547,8 @@ public:
A paint event is sent when a window's contents needs to be repainted.
Please notice that in general it is impossible to change the drawing of a
standard control (such as wxButton) and so you shouldn't attempt to handle
paint events for them as even if it might work on some platforms, this is
inherently not portable and won't work everywhere.
@remarks
Note that in a paint event handler, the application must always create a
wxPaintDC object, even if you do not use it. Otherwise, under MS Windows,
refreshing for this and other windows will go wrong.
For example:
The handler of this event must create a wxPaintDC object and use it for
painting the window contents. For example:
@code
void MyWindow::OnPaint(wxPaintEvent& event)
{
@@ -1565,6 +1557,12 @@ public:
DrawMyDocument(dc);
}
@endcode
Notice that you must @e not create other kinds of wxDC (e.g. wxClientDC or
wxWindowDC) in EVT_PAINT handlers and also don't create wxPaintDC outside
of this event handlers.
You can optimize painting by retrieving the rectangles that have been damaged
and only repainting these. The rectangles are in terms of the client area,
and are unscrolled, so you will need to do some calculations using the current
@@ -1601,6 +1599,12 @@ public:
}
@endcode
@remarks
Please notice that in general it is impossible to change the drawing of a
standard control (such as wxButton) and so you shouldn't attempt to handle
paint events for them as even if it might work on some platforms, this is
inherently not portable and won't work everywhere.
@beginEventTable{wxPaintEvent}
@event{EVT_PAINT(func)}