On 2007-11-15 21:05:37 -0800, "Peter Webb"
<(E-Mail Removed)> said:
> Not in this case.
If you say so.
> [...]
> I can't just cache a background copy, because I want to draw to this
> using the Graphics methods. There does not seem a direct facility to
> draw an object but not display it, unless I use double buffered
> graphics.
Well, first of all, even the BufferedGraphics class you've mentioned
includes a Graphics property, which you can use to draw into the
BufferedGraphics instance. Then you could use the
BufferedGraphics.Render(Graphics) method in the form's OnPaint() to
actually draw that buffer as the background.
But alternatively, there's always the plain vanilla Bitmap class.
Create a Bitmap instance the size you want (based on the size of the
background you need for the form you're drawing into), use the
Graphics.FromImage() method to get a Graphics instance from that, and
draw to the Bitmap that way.
And then, as you could with BufferedGraphics, you can use the
Graphics.DrawImage() method in the OnPaint() method to draw the
background to the form.
Then, once the background has been drawn in OnPaint(), draw your circles.
> That's because I don't know how to do what I want, so I can't use
> proper terminology.
Okay, fair enough. Hopefully the above gives you the tools and
terminology you need.
> [...]
> loop:
> {
>
> *** write the new track points to myBuffer
>
> myotherBuffer=new BufferedGraphics();
> myotherBuffer=myBuffer.clone(); // save a version of the background
> with new tracks in myotherBuffer
This part is wasteful, because...
>
> **** write the circles to myBuffer and render to screen
This part is unnecessary. Just draw both the background image and the
circles directly to the screen.
If flicker is an issue, then set DoubleBuffered to true in the form,
and let the OS deal with that.
> myBuffer=myotherbuffer; // reloads the copy of the background without
> the circles
>
> }
>
> This would work fine, and just involves copying a bitmap to a new location.
>
> Unfortunately, I can't clone myBuffer, and if I just go:
> myotherbuffer = mybuffer;
> I am updating the object ref, not copying the object.
Well, it's fairly easy to make a copy of a Bitmap or BufferedGraphics
instance, but you don't need to.
> There must be a simple way to do this.
There is. See above.
> All I am really trying to do is generate two drawing layers - one for
> the foreground, one for the background. You see this is every drawing
> package I have ever used, and its a very common requirement.
Actually, lots of drawing programs exist that don't know anything about
layers. But whether they do or not, GDI, GDI+, etc. aren't drawing
programs. They are drawing APIs.

And as an API, they don't know
anything about layers. The only layers that exist are those that you
impose programmatically.
You can do that by drawing the rear-most layers first, followed by
those in front. In this case, you seem to have basically just two. So
you maintain the background image, and the state necessary to draw the
foreground, and then in OnPaint() draw the background image first, then
all the stuff in the foreground (your orbiting circles).
There is a concept of layering in the "User" portion of Win32, and
likewise the Control-based classes in .NET. But they don't handle
transparent controls very well, and I don't think using that layering
for handling drawing issues would perform very well anyway.
It's possible that WPF supports layering. I just don't know anything
about it. I'm comfortable enough with the basic GDI/GDI+ techniques
that I haven't felt a need to look into it yet.
> It would seem strange if there wasn't some way of emulating two layers
> in some manner - even if it is not through the buffering "trick" that I
> have described (and which unfortunately doesn't work).
Emulating the layers is simple: just draw things in the right order,
back to front (standard "painter's" algorithm).
Pete