1. Herfried K. Wagner’s VB.Any
  2. .NET
  3. Frequently Asked Questions

Setting a progressbar control’s foreground and background color

Setting a progressbar control's foreground and background color
<URL:http://dotnet.mvps.org/dotnet/faqs/?id=setprogressbarcolors&lang=en>
----------------------------------------------------------------------------

Setting a progressbar control's foreground and background color

The .NET Framework doesn't provide a way to set forecolor and backcolor of
a progressbar control.  This can be done using p/invoke calls.  The default
color of the progressbar's foreground or background is represented as
'CLR_DEFAULT'.  It's not supported to deal with this value directly in
.NET, so we use 'Color.Transparent' instead to store this value.  To make
usage of the class more intuitive, assigning the value of its 
DefaultColor' property to its color properties resets the property value to
the default color.

The reason why we do not simply inherit from 'ProgressBar' is that
'ProgressBar' is a 'NotInheritable' class.

When instantiating the class, a progressbar object must be passed to the
constructor.  In the constructor, the control's foreground and background
values will be reset to their default values.  This is necessary to make
the properties return correct values:

\\\
Public Class ProgressBarHelper
    Private Declare Auto Function SendMessage Lib "user32.dll" ( _
        ByVal hWnd As IntPtr, _
        ByVal wMsg As Int32, _
        ByVal wParam As IntPtr, _
        ByVal lParam As IntPtr _
    ) As IntPtr

    Private Const WM_USER As Int32 = &H400

    Private Const CCM_FIRST As Int32 = &H2000
    Private Const CCM_SETBKCOLOR As Int32 = (CCM_FIRST + &H1)

    Private Const PBM_SETBARCOLOR As Int32 = (WM_USER + 9)
    Private Const PBM_SETBKCOLOR As Int32 = CCM_SETBKCOLOR

    Private Const CLR_DEFAULT As Int32 = &HFF000000

    Private m_ProgressBar As ProgressBar
    Private m_BackColor As Color
    Private m_ForeColor As Color
    Private m_OldBackColor As Color
    Private m_OldForeColor As Color

    Public Sub New(ByVal ProgressBar As ProgressBar)
        If ProgressBar Is Nothing Then
            Throw New NullReferenceException()
        End If
        m_ProgressBar = ProgressBar

        ' Reset colors to make calls to property gets for 'ForeColor' and
        ' 'BackColor' return the right value.
        Me.ForeColor = DefaultColor
        Me.BackColor = DefaultColor
    End Sub

    Public ReadOnly Property ProgressBar() As ProgressBar
        Get
            Return m_ProgressBar
        End Get
    End Property

    Public Property ForeColor() As Color
        Get
            Return m_ForeColor
        End Get
        Set(ByVal Value As Color)
            m_ForeColor = Value
            SetBarColor(Me.ForeColor)
        End Set
    End Property

    Public Property BackColor() As Color
        Get
            Return m_BackColor
        End Get
        Set(ByVal Value As Color)
            m_BackColor = Value
            SetBkColor(Me.BackColor)
        End Set
    End Property

    Public Shared ReadOnly Property DefaultColor() As Color
        Get
            Return Color.Transparent
        End Get
    End Property

    Private Function SetBarColor(ByVal Color As Color) As Color
        Return _
            ProgressBarColorToDotNetColor( _
                SendMessage( _
                    m_ProgressBar.Handle, _
                    PBM_SETBarCOLOR, _
                    IntPtr.Zero, _
                    New IntPtr(DotNetColorToProgressBarColor(Color)) _
                ).ToInt32() _
            )
    End Function

    Private Function SetBkColor(ByVal Color As Color) As Color
        Return _
            ProgressBarColorToDotNetColor( _
                SendMessage( _
                    m_ProgressBar.Handle, _
                    PBM_SETBKCOLOR, _
                    IntPtr.Zero, _
                    New IntPtr(DotNetColorToProgressBarColor(Color)) _
                ).ToInt32() _
            )
    End Function

    Private Function DotNetColorToProgressBarColor( _
        ByVal Color As Color _
    ) As Int32
        If Color = DefaultColor Then
            Return CLR_DEFAULT
        Else
            Return ColorTranslator.ToWin32(Color)
        End If
    End Function

    Private Function ProgressBarColorToDotNetColor( _
        ByVal Color As Int32 _
    ) As Color
        If Color = CLR_DEFAULT Then
            Return DefaultColor
        Else
            Return ColorTranslator.FromWin32(Color)
        End If
    End Function
End Class
///

Usage:

\\\
Dim p As New ProgressBarHelper(Me.ProgressBar1)
p.ForeColor = Color.Red
p.BackColor = Color.Blue
///