Setting a ProgressBar Control’s Foreground and Background Colors
The .NET Framework does not provide a way to set foreground color and background color 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