Eliminating flicker in transparent controls

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


Answer this question

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

    Thanks for your tips, I found another (similar) way to solve my problem:

    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

    If you can eliminate the control, and just draw all graphics directly to single control, that seems to be the only way to get good transparency.
  • 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



  • Eliminating flicker in transparent controls