Hello all,
I am working on an application that requires transparent controls.
I have used Bob Powells method (http://www.bobpowell.net/transcontrols.htm) and
it works just fine. However, it is not possible to use double-buffering.
This is mostly not a problem, but for some controls that I use (e.g. a transparent
gauge-type thing drawn with GDI+ that changes frequently) there is a noticable
flicker while drawing.
What I do is that on setting the value property I call the draw method, invalidate
the parent's background for the control rectangle, call update() on the parent and
then proceed drawing the control. This works fine, the background is restored but
the flickering remains.
Any suggestion on how to improve this is highly appreciated. :-)
Daniel

Eliminating flicker in transparent controls
Pillsbury
sure there are:
[code] and [/code]
(replace the square brakets with the html tags <>)
for more check <a href="http://www.windowsforms.net/Forums/transform.txt">the transform text file on this site</a>
mzl !
Todd Biggs
I use a bitmap which I set as background image for my control.
From this bitmap I derive a Graphics context and a handle :
Graphics g = this.CreateGraphics();
memBm = new Bitmap(this.Width,this.Height,g);
Graphics memGr = Graphics.FromImage(memBm);
g.Dispose();
To set the bitmap data I have a simple blitting function:
protected void Blit(System.Drawing.Rectangle rect) {
memDC = memGr.GetHdc();
if(myChart.GraphicsContext.BitBlt(rect,this.memDC)==0) // this calls the GDi BitBlt() func
System.Diagnostics.Trace.WriteLine("bitblt returned false!");
memGr.ReleaseHdc(memDC);
}
Now I can enable double buffering and paint nicely on my control. Of course, the problems
with overlapping controls not doing the transparency right is still there but it works for me.
btw. are there an editor tags for code snips
Ygor Goldberg
rexrageous
i dont understand the bob powel method at all, but maybe you can use regions
what i do is draw everything on a bitmap with the same size as my control, but only when its needed, (the control has resized, or a property has changed or something)
this way the control doesnt draw everything difficult, just a bitmap
and you can use double-buffering
example :
'Bitmap to draw on
Private Picture As Bitmap
'Here you paint everything
Private Sub DrawPicture(ByVal aa As Boolean)
If Not Picture Is Nothing Then Picture.Dispose()
'Im invisible, so dont draw anything
If Me.Width = 0 OrElse Me.Height = 0 Then
Picture = New Bitmap(1, 1, Imaging.PixelFormat.Format32bppPArgb)
Exit Sub
End If
'Create new bitmap and graphics
Picture = New Bitmap(Me.Width, Me.Height, Imaging.PixelFormat.Format32bppPArgb)
Dim G As Graphics = Graphics.FromImage(Picture)
G.FillRectangle(New SolidBrush(Me.BackColor), Me.Bounds)
'All your paint stuff here
G.Dispose()
Me.Region = CreateRegion(Picture, Me.BackColor)
End Sub
'Create a region from a bitmap and a color
Friend Shared Function CreateRegion(ByVal Picture As Bitmap, ByVal TransColor As Color) As Region
Dim TempReg As New Region(New Rectangle(0, 0, 0, 0))
Dim BackColor As Color = TransColor
Dim Row, Col As Integer
For Row = 0 To Picture.Height - 1
Dim StartCol As Integer = -1
Dim StopCol As Integer = -1
For Col = 0 To Picture.Width
If Col = Picture.Width Then
If StartCol <> -1 Then
StopCol = Col
Dim UnionReg As New Region(New Rectangle(StartCol, Row, StopCol - StartCol, 1))
TempReg.Union(UnionReg)
UnionReg = Nothing
End If
Else
If Picture.GetPixel(Col, Row).Equals(BackColor) = False Then
If StartCol = -1 Then StartCol = Col
ElseIf Picture.GetPixel(Col, Row).Equals(BackColor) = True Then
If StartCol <> -1 Then
StopCol = Col
Dim UnionReg As New Region(New Rectangle(StartCol, Row, StopCol - StartCol, 1))
TempReg.Union(UnionReg)
UnionReg = Nothing
StartCol = -1
StopCol = -1
End If
End If
End If
Next
Next
Return TempReg
End Function
'The size has changed
Protected Overrides Sub OnSizeChanged(ByVal e As System.EventArgs)
MyBase.OnSizeChanged(e)
DrawPicture()
Me.Invalidate()
End Sub
'A property, in this case the text, has changed
Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
MyBase.OnTextChanged(e)
DrawPicture()
Me.Invalidate()
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
If Picture Is Nothing Then DrawPicture()
e.Graphics.DrawImageUnscaled(Picture, 0, 0)
End Sub