Robin posted a small test program the other day called mesh.py, which draws
horizontal and vertical lines on a panel to give a mesh effect, and then
changes the colour of a rectangle to red while the mouse pointer is inside
the rectangle. It is a nice little demo, and it has given me some ideas for
something I will need soon.
There is one thing I do not understand about the program. It uses
RefreshRect(rect) to update the display as the mouse moves from one
rectangle to another, but I do not see anything in the OnPaint handler that
retrieves 'rect' to repaint that portion of the screen only. As far as I can
see, OnPaint redraws the whole screen every time.
I also notice that OnPaint uses a BufferedPaintDC instead of a PaintDC. Is
this how it works? Does it automatically use 'rect' to retrieve that portion
from the BufferedPaintDC and physically redraw only that portion?
Any insights into how this actually works will be appreciated.
There is one thing I do not understand about the program. It uses
RefreshRect(rect) to update the display as the mouse moves from one
rectangle to another, but I do not see anything in the OnPaint handler that
retrieves 'rect' to repaint that portion of the screen only. As far as I can
see, OnPaint redraws the whole screen every time.
I think that's right, yes.
I also notice that OnPaint uses a BufferedPaintDC instead of a PaintDC. Is
this how it works? Does it automatically use 'rect' to retrieve that portion
from the BufferedPaintDC and physically redraw only that portion?
nope -- the bufferedDC means that all the drawing happens in an odd-screen bitmap (buffer), which is then blitted all at once to the screen, so that you don't get any flashing, or seeing the screen update as it goes.
One could be smarted about drawing only that portion that changes, but you what they say about premature optimization...
For what it's worth, if I were to optimize that, I'd probably keep the grid in a buffer and draw the highlighted rectangle on top of it -- then you'd only be drawing the rectangle each time.
Maybe that's how it's done -- I didn't look closely at that code.
-Chris
···
--
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Robin posted a small test program the other day called mesh.py, which draws
horizontal and vertical lines on a panel to give a mesh effect, and then
changes the colour of a rectangle to red while the mouse pointer is inside
the rectangle. It is a nice little demo, and it has given me some ideas for
something I will need soon.
There is one thing I do not understand about the program. It uses
RefreshRect(rect) to update the display as the mouse moves from one
rectangle to another, but I do not see anything in the OnPaint handler that
retrieves 'rect' to repaint that portion of the screen only. As far as I can
see, OnPaint redraws the whole screen every time.
Yes and no. The code is drawing everythign and is not doing anything to optimize the drawing to the update region, but the platform will. It will only move the pixels to the display that are within the update region, (and the clipping region if one is set.) Most of the time this is enough of an optimization that I don't worry about doing anything else. On the other hand if the content to be painted is complex and/or time consuming then you can use window.GetUpdateRegion() within the EVT_PAINT handler to get the area(s) that need to be repainted. You can iterate through the collection of rectangles in the region, or just use region.GetBox() to get a single rectangle that contains the others.
I also notice that OnPaint uses a BufferedPaintDC instead of a PaintDC. Is
this how it works?
BufferedPaintDC is simply a convenience that uses a MemoryDC with a bitmap while drawing, and then blits it to the PaintDC when finished.
Does it automatically use 'rect' to retrieve that portion
from the BufferedPaintDC and physically redraw only that portion?
That is done by the platform as described above, and would be done regardless of whether a buffer is used or not. The main reason to use a buffered dc is so that there is only one drawing operation that actually moves pixels to the screen (the blit of the bitmap at the end) otherwise on Windows you can sometimes see intermediate steps and the result is some flicker or flashing.
···
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!