Transparency Revisited...

R

Rlrcstr

I've seen posts all over the place that talk all around this, but I haven't
seen anything that resolves the issue.

Is it possible to make a picturebox have a transparent background? I've
tried every combination of setting I can find, but to no avail. I'm writing
a drawing program and I have a grid in the background. I get a lot of
flicker when drawing the shapes, well enough to be annoying, anyway. I
figured if I could draw them on a picturebox with a transparent background,
I could eliminate the need to redraw the backround grid all the time.

Anyone have any suggestions? Thanks.

J
 
J

Joop

If you want to draw shapes, you would probably do it on-the-fly. So, no need
to use a picturebox, draw them on the form by setting their Alpha to
something less than 255 when setting their colors. Other than this, you will
get this error for the picture box: "The control doesn't support transparent
colors"....
 
R

Rlrcstr

I've tried all kinds of settings, but I never get that error. And drawing
the shapes directly on the form does not solve the problem of the flicker.
I will still need to draw the grid.

Anyone have any suggestions on how to separate the two drawing planes?

J
 
G

Guest

Draw the shapes on bitmaps then use bitblt to copy the bitmaps to the desired
location on your forms graphics object passed as a parameter in the paint
event of the form. You can use the invalidate method with the cliprectangle
set to where you want the bitmap to be drawn. Also, you may want to consider
double buffering to help reduce flicker.
 
R

Rlrcstr

Sounds like you have some experience with this... I'm tryinig to make an
object oriented drawing program. Nothing that hasn't been done before, I'm
sure, but it's a project for learning to mess with graphics in .NET.

I've got shape objects that draw themselves. I was using a picbox on a for
as the canvas and painting the grid directly on that. As a shape is being
drawn, I was using the draw methid of the shape object - basically means I
needed to redraw all the object even as the mouse was moving while drawing -
creates the familiar rubber band effect.

But redrawing the background grid was giving flicker because, obviously all
the shapes were wiped out when the backgroound was redrawn. Came up with
the thought of a pic box with a transparent background figuring I'd only
have to redraw the grid on resize or reconfiguration of the grid (visible,
size, style, whatever).

I just can't beleive that it's so hard to find a way to do that. Seemed
like such a simple concept.

Anyway... So if there's no way to do it liked I envisioned, I need to work
on something like the double buffering concept. Do you have good examples
of that? I'll search for it, as well, but I figure I'd ask since you
mentioned it... Thanks.

J
 
G

Guest

You can set double buffering using the .SetStyles method for the control or
Form. Note that you need to read it carefully because using double buffering
requires the userdraw the control or form background if any and any text or
shapes on the background.

Tha basic concept I would use for your problem is to create a bitmap the
same size as your form client area. You would need to recreate this bitmap
everytime the form was resized. You can draw your backgound if you have one
on the bitmap or if the background is another bitmap, just copy that bitmap
to the bitmap you are using for the form (call it formbitmap).

You can convert the shapes into bitmaps and use bitblt to copy them to the
formbitmap at the position you want them. When they move, just recopy the
background bitmap and the shapes in their niew locations.

Use bitblt for all the copying of background bitmap and shape bitmaps to the
formbitmap and GDI for drawing text or whatever on the formbitmap. When you
are finished drawing, use the Invalidate (cliprect) to redraw the form. Note
that the cliprect is the area that you jusr redrew on the formbitmap
(probably the whole bitmap rectangle in your case).

In the Paint event (this is triggered by the .Invalidate method or a user
moving another window over the form) you can copy the formbitmap
(cliprectangle portion) to the form's graphics object which is passed as a
parameter in the Paint Event. For example (note that gph is the graphics
object for the bitmap on which you can draw text, etc. on the formbitmap.

Public Class myform

formbitmap As Bitmap = New Bitmap(Me.Width, Me.Height, Me.CreateGraphics)
dim gph as graphics = Graphics.FromImage(formbitmap)
.....
'Do your drawing on gph and use bitblt to copy background orshape bitmaps to
formbitmap
'Note: you can find lots of examples of copying a bitmap to another bitmap
on Google.
.....
.....

myform.Invalidate() 'redraws the whole form or
myform.Invalidate(cliprect) 'redraws only the rectange where changes were made
'Note that when the form is redrawn because the user popped up a message box
or somehow put another window over the form then removed it then the Paint
event will be called where the cliprect is the whole form.

'Note that if the user resizes the form, then you will have to dispose of
the current formbitmap and the graphics object the create them:
gph.Dispose:formbitmap.Dispose
formbitmap As Bitmap = New Bitmap(Me.Width, Me.Height, Me.CreateGraphics)
dim gph as graphics = Graphics.FromImage(formbitmap)

'Note: When you Close the form, then in the dispose event you need to
dispose of gph and formbitmap.

End Class

Private Sub myform_Paint(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Dim hdcControl As IntPtr = e.Graphics.GetHdc
Dim hdcBitmapDC As IntPtr = gph.GetHdc
Dim hdcBitmapHandle As IntPtr = formbitmap.GetHbitmap
SelectObject(hdcBitmapDC, hdcBitmapHandle)
BitBlt(hdcControl, e.ClipRectangle.X, e.ClipRectangle.Y, _
e.ClipRectangle.Width, e.ClipRectangle.Height, hdcBitmapDC,
e.ClipRectangle.X, _ e.ClipRectangle.Y, &HCC0020)
DeleteObject(hdcBitmapHandle)
gph.ReleaseHdc(hdcBitmapDC)
e.Graphics.ReleaseHdc(hdcControl)
end sub

Hope this helps. You will find that bitblt is blazing fast and I'll almost
guarantee that you won't have flicker especially if you use double buffering
 
R

Rlrcstr

Your help is truly appreciated. But I have a couple of questions...

I was just going to implement the doublebuffering in the picturebox. As I've already got the form laid out with it, etc...

But if I try to set any control style flags:
Me.picCanvas.SetStyle(ControlStyles.AllPaintingInWmPaint, True)

(I know I have to set the other flags, as well, but that doesn't change anything.)

I just get a compiler error:

"System.Windows.Forms.Control.Protected Sub SetStyle(flag As System.Windows.Forms.ControlStyles, value As Boolean)' is not accessible in this context because it is 'Protected'."

Not sure if makes a difference that this is a usercontrol, not a standard form. I can set the flags for the user control itself, but not a child control?

I will try to implement the buffering manually, but I'd like to understand why I can't get to it, or at least in what context I would be able to get to that method. If it's defined as a protected method of the control, how could I ever use it?

Thanks.

Jerry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top