Results 1 to 5 of 5

Thread: Graphics Clear Draw Background

  1. #1

    Thread Starter
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    9,589

    Graphics Clear Draw Background

    I'm responding to some feedback on a CodeBank submission here: http://www.vbforums.com/showthread.p...=1#post5485090

    Currently, I have the following class that overrides the OnPaint method:
    Code:
    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Dim textColor As Color = Me.ForeColor
        Dim backColor As Color = Me.BackColor
    
        If _isOutline Then
            backColor = Color.FromArgb(Bootstrap.Utilities.Color.BackgroundWhite.R, Bootstrap.Utilities.Color.BackgroundWhite.G, Bootstrap.Utilities.Color.BackgroundWhite.B)
        ElseIf _isOutline AndAlso Not mouseDowned AndAlso Not mouseEntered Then
            backColor = Bootstrap.Utilities.Color.BackgroundWhite
        ElseIf Not Me.Enabled Then
            backColor = Color.FromArgb(Convert.ToInt32(Byte.MaxValue * 0.65), backColor.R, backColor.G, backColor.B)
        ElseIf mouseDowned Then
            backColor = styleConfigurationMouseEvents(_style).Value
        ElseIf mouseEntered Then
            backColor = styleConfigurationMouseEvents(_style).Key
        End If
    
        If _isOutline Then
            textColor = styleConfiguration(_style).Key
        End If
    
        If _isOutline AndAlso (mouseDowned OrElse mouseEntered) Then
            backColor = styleConfiguration(_style).Key
            textColor = Bootstrap.Utilities.Color.TextWhite
            If _style = StyleType.Warning OrElse _style = StyleType.Light Then
                textColor = Bootstrap.Utilities.Color.TextBody
            End If
        End If
    
        e.Graphics.Clear(backColor)
    
        TextRenderer.DrawText(e.Graphics, Me.Text, Me.Font, Me.DisplayRectangle, textColor, TextFormatFlags.VerticalCenter Or TextFormatFlags.HorizontalCenter)
    
        MyBase.OnPaint(e)
    End Sub
    A developer wanted to add a BackgroundImage, but was running into an issue where the image was never rendered or at least it was rendered briefly before disappearing.

    To recap my comment on why it is happening: The issue stems from the fact that I'm using the Graphics::Clear method. This gives it the visual styles you'd expect a button to have when hovering over the button, pressing down on the mouse, or releasing the mouse.

    However, I'm not sure how to keep those visual styles while at the same time supporting a BackgroundImage. Let alone supporting things like:
    • What if it is a transparent image?
    • What if the image is scrollable?
    • What if the developer wants to also support the BackgroundImageLayout?


    Does Win32 provide support for these things either via a native method or via an API?

  2. #2
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    105,018

    Re: Graphics Clear Draw Background

    The question is what you're actually trying to accomplish with that Clear call. The name suggests that its purpose is to clear anything that is already drawn but that's not really how it works. If that's what you want then you should be calling Invalidate without a parameter before the Paint event is raised. Calling Clear is pretty much the equivalent of calling FillRectangle for the entire control area. I'd suggest that calling it there is probably misguided because it is literally doing what it's supposed to do. I haven't read through that CodeBank issue so I'm not sure of all the details but that method call is saying "paint over the control background with the control's background colour. A background image is part of that background so of course it gets painted over.

  3. #3

    Thread Starter
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    9,589

    Re: Graphics Clear Draw Background

    What I'm trying to do is give the button visual style effects based on the button's current state: is it outlined, is it outlined and a mouse is over it, is the user pressing down on the button, etc.

    The reason I decided to use Clear was because it allowed me to specify the BackColor in the OnPaint without overwriting the BackColor property. It sounds like what I should probably do is overwrite the background color based on the current state of the button in the Enter, Leave, MouseDown, etc. events.

    The side effect to this is that if the user specifies a color in the designer then it'd get overwritten. Then again right now while my code isn't overwriting the property it is ignoring it. So it's the same behavior just with a different implementation.

  4. #4
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    35,064

    Re: Graphics Clear Draw Background

    It rather sounds like you don't want Clear, the way it works, but you want something like Clear. You say that you wanted to use clear to allow you to specify the BackColor without overwriting the property. However, that suggests to me that your real goal was to "paint the entire rectangle with something", and you were thinking that the something would be a solid color. That sounds almost completely right to me, except that what you want Clear to do is paint the entire rectangle with some background, which could be a color or an image. It's almost the same thing. Painting a texture and painting a color are both just painting. So, I'd say you want your own clear.
    My usual boring signature: Nothing

  5. #5
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,012

    Re: Graphics Clear Draw Background

    It seems if you want to support a BackgroundImage, you should code for it. You're overriding the way the control is suppose to be painted, so you'll need to go further. Since the Clear will undo the painting of the background color and the drawing of the background image, since you're painting a conditional background color, then perhaps you should be drawing a conditional BackgroundImage after that.
    Code:
    '...
        e.Graphics.Clear(backColor)
    
        If BackgroundImage IsNot Nothing Then
            e.Graphics.DrawImage(BackgroundImage,0,0)
        End If
    
        TextRenderer.DrawText(e.Graphics, Me.Text, Me.Font, Me.DisplayRectangle, textColor, TextFormatFlags.VerticalCenter Or TextFormatFlags.HorizontalCenter)
    
        MyBase.OnPaint(e)
    End Sub
    Of course, there are different options as how the background image should be drawn, and the above doesn't implement any of them, but it will at least show an unscaled image "underneath" your text, and if not transparent in part, completely obscure the background color chosen.

    I guess if you still wanted to see the background color effects, you could us a translucent version of the color to draw over the background image.
    Code:
    '...
                    e.Graphics.Clear(backColor)
                    If BackgroundImage IsNot Nothing Then
                        e.Graphics.DrawImage(BackgroundImage,0,0)
                        Using tranlucentBrush As New SolidBrush(Color.FromArgb(160,backColor))
                            e.Graphics.FillRectangle(tranlucentBrush,0,0,Me.Width,Me.Height)
                        End Using
                        
                    End If
                    TextRenderer.DrawText(e.Graphics, Me.Text, Me.Font, Me.DisplayRectangle, textColor, TextFormatFlags.VerticalCenter Or TextFormatFlags.HorizontalCenter)
    Last edited by passel; Jul 2nd, 2020 at 01:20 AM.
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width