You said that redrawing the whole screen isn't recommended for Mac. Do you know what is?
From the highest authority: viewtopic.php?p=247297#p247297
did you mean the DragContainter Class in your DragCanvas project
Well, both. The DragContainer class specifically and the DragCanvas project generally.
In the DragContainer.Paint event, I do this:
Sub Paint(g As Graphics)
If lastWidth <> Me.Width Or lastHeight <> Me.Height Then
//The canvas has been resized, so we need to regen the buffer
buffer = New Picture(Me.Width, Me.Height, 24)
lastWidth = Me.Width
lastHeight = Me.Height
g.DrawPicture(buffer, 0, 0)
The Update() method of the DragContainer example is where all the actual drawing gets done. If the Canvas hasn't been resized then the only thing the Paint event does is draw the unmodified buffer, otherwise it calls Update() and then draws the newly generated buffer. Other events or methods also call Update if they've modified anything (and they may or may not call Refresh/Invalidate to force a Paint.) You can certainly have a different method each draw different or even overlapping regions on the buffer, calling them as needed (and as little as possible from the Paint event.)
Drawing to the screen will always be expensive, and multiple Paint events can fire in a very short period of time. The core idea is that you want to get in and get out of the Paint event as quickly as possible
since there may be 10 more coming quick.
when a user "clicks" an image icon, I capture the Mouse, determine which Icon it is, then redraw the screen with that Icon in its "Down" image, and then g.DrawPicture(). Is that right? The whole screen would be redrawn with the Clicked Icon in its Down position, and then the MouseUp capture redraws the whole thing again, with all icons in their "Up" position.
Yes. The buffer is the current state of the canvas, which you modify as needed/wanted. When the Paint event fires you just call g.DrawPicture(Buffer, 0, 0)
. Since the buffer persists until it's explicitly destroyed, you don't necessarily need to redraw everything, but you would need to devise a way of determining what needs to be redrawn and what doesn't. The DragContainer example just redraws everything when Update is called.
In your example code on GitHub I noticed you used Refresh(false) and Invalidate(false).Refresh
triggers the Paint event, Invalidate
merely suggests a Paint event. Passing True to either one will erase the canvas first, whereas passing false will not. Erasing the background is a case-by-case thing, since it can be good but it's also more expensive.