locked
ControlPaint.Light and ControlPaint.Dark RRS feed

  • Question

  • Hi to all,
    i've started using these two functions ControlPaint.Light and ControlPaint.Dark, but i've a dubt.

    What is the right range of percentage that could be applied to this functions??


    0 to 1 or 1 to 100?

    for example.

    BrightColor = Light(Color.red, 10)
    
    or
    
    BrightColor = Light(Color.red, 0.1)
    

    Thank in advance for the answers.

    Genko.

    Saturday, December 8, 2012 2:49 PM

Answers

  • Interresting.

    You would have expect to see

            If (percDarker <= 0!) Then
                Return SystemColors.ControlDark
            End If
            If (percDarker >= 1!) Then
                Return SystemColors.ControlDarkDark
            End If

    as it is writen, this code can overflow

     Return Color.FromArgb(CByte((controlDark.R - CByte((num * percDarker)))), CByte((controlDark.G - CByte((num2 * percDarker)))), CByte((controlDark.B - CByte((num3 * percDarker)))))
      

    • Marked as answer by _Genko_ Monday, December 10, 2012 10:20 AM
    Monday, December 10, 2012 10:16 AM
  • The documentation clearly states that the floating point value represents a percentage.  This strongly suggests that the correct values to be passed to the method should represent a normalized value.  In other words a value that ranges from 0 to 1, a percentage.

    http://msdn.microsoft.com/en-us/library/h3fxkc2x%28v=vs.100%29.aspx  ControlPaint.Dark

    An inspection of the .NET Framework 4 source code confirms this.  Here is the Dark method.

    Public Shared Function Dark(ByVal baseColor As Color, ByVal percOfDarkDark As Single) As Color
        Dim color As New HLSColor(baseColor)
        Return color.Darker(percOfDarkDark)
    End Function
    
     


    Notice that it calls another method, HLSColor.Darker.  Here's the source code for that method.

    Public Function Darker(ByVal percDarker As Single) As Color
        If Me.isSystemColors_Control Then
            If (percDarker = 0!) Then
                Return SystemColors.ControlDark
            End If
            If (percDarker = 1!) Then
                Return SystemColors.ControlDarkDark
            End If
            Dim controlDark As Color = SystemColors.ControlDark
            Dim controlDarkDark As Color = SystemColors.ControlDarkDark
            Dim num As Integer = (controlDark.R - controlDarkDark.R)
            Dim num2 As Integer = (controlDark.G - controlDarkDark.G)
            Dim num3 As Integer = (controlDark.B - controlDarkDark.B)
            Return Color.FromArgb(CByte((controlDark.R - CByte((num * percDarker)))), CByte((controlDark.G - CByte((num2 * percDarker)))), CByte((controlDark.B - CByte((num3 * percDarker)))))
        End If
        Dim num4 As Integer = 0
        Dim num5 As Integer = Me.NewLuma(-333, True)
        Return Me.ColorFromHLS(Me.hue, (num5 - CInt(((num5 - num4) * percDarker))), Me.saturation)
    End Function
    
     

    Notice the check of the passed floating point value for a value of 0 or 1, which in turn minimum and maximum values respectively. If not, the passed value is used as a multiplier toscale the output value as percentage between the minimum and maximum values.

    A percentage value will always be a value between 0 and 1.

    Hope this helps.

    Rudy    =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.com/


    • Edited by Rudedog2 Sunday, December 9, 2012 4:34 PM
    Sunday, December 9, 2012 4:34 PM

All replies

  • Hi,

    just test it. I think 0 to 2 will lighten black up to white:

            Dim c As Color = ControlPaint.Light(Color.Black, 1)
            Me.BackColor = c
            MessageBox.Show(c.ToString())

    ... but these ranges might vary. For instance ControlPaint.Dark with a White color starts by -0.5F for no change up to +1.0f which is black...

    Regards,

      Thorsten


    Saturday, December 8, 2012 3:23 PM
  • The value represents a percentage.  Try using values between 0 and 1.

    Hope this helps.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.com/

    Saturday, December 8, 2012 3:26 PM
  • It looks like it goes from 0 to 2 on my laptop. Actually from -2 to 2.

    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            HScrollBar1.SmallChange = 1
            HScrollBar1.SmallChange = 10
            HScrollBar1.Maximum = 100
            HScrollBar1.Value = 0
    
        End Sub
    
        Private Sub HScrollBar1_Scroll(sender As Object, e As ScrollEventArgs) Handles HScrollBar1.Scroll
            Me.BackColor = ControlPaint.Light(Color.Red, HScrollBar1.Value / 50)
            Me.Refresh()
            Me.Text = HScrollBar1.Value.ToString
        End Sub
    End Class


    You've taught me everything I know but not everything you know.


    Saturday, December 8, 2012 3:35 PM
  • 2nd One,

    The range is from 0 to 1.


    Regards,
    Dhaval Panchal
    Software Engineer
    (Fast Track Software Services)

    Sunday, December 9, 2012 12:43 PM
  • not sure about, i've tried and for me it's -0.5 to 1.5...for Dark

    for light.....i don't know..


    Sunday, December 9, 2012 3:59 PM
  • The documentation clearly states that the floating point value represents a percentage.  This strongly suggests that the correct values to be passed to the method should represent a normalized value.  In other words a value that ranges from 0 to 1, a percentage.

    http://msdn.microsoft.com/en-us/library/h3fxkc2x%28v=vs.100%29.aspx  ControlPaint.Dark

    An inspection of the .NET Framework 4 source code confirms this.  Here is the Dark method.

    Public Shared Function Dark(ByVal baseColor As Color, ByVal percOfDarkDark As Single) As Color
        Dim color As New HLSColor(baseColor)
        Return color.Darker(percOfDarkDark)
    End Function
    
     


    Notice that it calls another method, HLSColor.Darker.  Here's the source code for that method.

    Public Function Darker(ByVal percDarker As Single) As Color
        If Me.isSystemColors_Control Then
            If (percDarker = 0!) Then
                Return SystemColors.ControlDark
            End If
            If (percDarker = 1!) Then
                Return SystemColors.ControlDarkDark
            End If
            Dim controlDark As Color = SystemColors.ControlDark
            Dim controlDarkDark As Color = SystemColors.ControlDarkDark
            Dim num As Integer = (controlDark.R - controlDarkDark.R)
            Dim num2 As Integer = (controlDark.G - controlDarkDark.G)
            Dim num3 As Integer = (controlDark.B - controlDarkDark.B)
            Return Color.FromArgb(CByte((controlDark.R - CByte((num * percDarker)))), CByte((controlDark.G - CByte((num2 * percDarker)))), CByte((controlDark.B - CByte((num3 * percDarker)))))
        End If
        Dim num4 As Integer = 0
        Dim num5 As Integer = Me.NewLuma(-333, True)
        Return Me.ColorFromHLS(Me.hue, (num5 - CInt(((num5 - num4) * percDarker))), Me.saturation)
    End Function
    
     

    Notice the check of the passed floating point value for a value of 0 or 1, which in turn minimum and maximum values respectively. If not, the passed value is used as a multiplier toscale the output value as percentage between the minimum and maximum values.

    A percentage value will always be a value between 0 and 1.

    Hope this helps.

    Rudy    =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.com/


    • Edited by Rudedog2 Sunday, December 9, 2012 4:34 PM
    Sunday, December 9, 2012 4:34 PM
  • Interresting.

    You would have expect to see

            If (percDarker <= 0!) Then
                Return SystemColors.ControlDark
            End If
            If (percDarker >= 1!) Then
                Return SystemColors.ControlDarkDark
            End If

    as it is writen, this code can overflow

     Return Color.FromArgb(CByte((controlDark.R - CByte((num * percDarker)))), CByte((controlDark.G - CByte((num2 * percDarker)))), CByte((controlDark.B - CByte((num3 * percDarker)))))
      

    • Marked as answer by _Genko_ Monday, December 10, 2012 10:20 AM
    Monday, December 10, 2012 10:16 AM

  • as it is writen, this code can overflow

     Return Color.FromArgb(CByte((controlDark.R - CByte((num * percDarker)))), CByte((controlDark.G - CByte((num2 * percDarker)))), CByte((controlDark.B - CByte((num3 * percDarker)))))
      

    I haven't worked out the logic, but first glance says you're probably right.  But, wouldn't adding the greater/less than check slow it down significantly, compared to not making the check?  I guess the designers decided to assign responsibility of ensuring that the "percentage" value passed to the method is within the range of 0 to 1 onto the consumer.

    A ProgressBar shows a somewhat similar design mindset when it comes to writing to the Value property: no bounds checking is made to ensure that the Value the consumer assigns is within the limits defined by the Min and Max value properties.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.com/

    Monday, December 10, 2012 4:29 PM
  • ProgressBar throw when the values are out of bounds

    Public Property Value As Integer
        Get
            Return Me.value
        End Get
        Set(ByVal value As Integer)
            If (Me.value <> value) Then
                If (value >= Me.minimum AndAlso value <= Me.maximum) Then
                    Me.value = value
                    Me.UpdatePos()
                Else
                    Dim str As Object() = New Object(4)
                    str(0) = "Value"
                    str(1) = value.ToString(CultureInfo.CurrentCulture)
                    str(2) = "'minimum'"
                    str(3) = "'maximum'"
                    Throw New ArgumentOutOfRangeException("Value", SR.GetString("InvalidBoundArgument", str))
                End If
            End If
        End Set
    End Property


    • Edited by Crazypennie Monday, December 10, 2012 8:54 PM
    Monday, December 10, 2012 8:53 PM
  • @Crazypennie

    Exactly my point. Take another look at the code you posted!

    An exception is thrown when the passed value is out of range.  The responsibility for not throwing an exception is put on the consumer.   When an out of range value is passed, it is not swallowed up, corrected for, or otherwise ignored.  In both cases, an exception is thrown.

    Your posted sample with the greater/less than checks, handles out of range values for the consumer without their direct knowledge.  I think that is not necessarily a good thing.  I think it is a bad thing to do to the consumer.  When they make a mistake, let them know about it, instead of sweeping it away under the rug.

    The ProgressBar.PerformStep method will never through an exception, however.  I find it to be my preferred method of updating a progressbar control.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.com/

    Wednesday, December 12, 2012 4:40 PM
  • The problem I see with the Darker implementation can be describe like this

    - Ok, the function is expecting a value between 0 and 1 but it will not block any value out of this range.

    - therefore a user can mistakably pass as example 99 ( thinking 99%). And the function can be succesful as darkening the control with this value many times  ... until the internal computation  "percDarker * num"   overflows when casted as byte.

    - The exception that the user will get is NOT gonna be "ArgumentOutOfRangeException" as it should be, but an "OverflowException" which will not give him any hint about the fact that he is using a value out of the expected range.

    -Since the user is not aware of this internal multiplication and not aware of his mistake, for him, he will find the function unstable

    ---------------------

    In the case of the progressBar, the exception returned when the values are wrong is  "ArgumentOutOfRangeException" ... as it should be



    • Edited by Crazypennie Wednesday, December 12, 2012 7:33 PM
    Wednesday, December 12, 2012 7:30 PM
  • If a person passes a value of 99 to a method that is asking for a percentage value, then all mistakes and any misconceptions are their own.

    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.com/

    Thursday, December 13, 2012 5:54 PM