progressbar style...

lidds

Junior Contributor
Joined
Nov 9, 2004
Messages
210
Does anyone know how to create a progressbar simular to Window XP splash screen progressbar, in which only has 3 progressbar segments move to and from within the progressbar whilst loading????

Cheers

Simon
 
A custom control animation using a timer might do the trick...

You'll have to do a little math to get the resizing to work right but it shouldn't be too hard. I don't know of a control out of the box that will allow you to do this.
 
Am new to vb.net so have never had to do anything like this, don't suppose you have an example or know of any tutorials, or is it just best to google it??

Thanks for the help though
 
Here's a poor man's version. Drop the code into a custom control.

Code:
    Private _x As Integer
    Private _color As Color
    Private _width As Integer
    Private _border As Boolean

    Private WithEvents _tmr As System.Windows.Forms.Timer

    Public Property RectColor() As Color
        Get
            Return _color
        End Get
        Set(ByVal Value As Color)
            _color = Value
        End Set
    End Property

    Public Property RectWidth() As Integer
        Get
            Return _width
        End Get
        Set(ByVal Value As Integer)
            _width = Value
        End Set
    End Property

    Public Property HasBorder() As Boolean
        Get
            Return _border
        End Get
        Set(ByVal Value As Boolean)
            _border = Value

            DrawBorder()

        End Set
    End Property

    Public Sub StartPB()

        _tmr = New System.Windows.Forms.Timer

        _tmr.Interval = 1

        AddHandler _tmr.Tick, AddressOf DrawBar

        _tmr.Start()

    End Sub

    Public Sub StopPB()

        _tmr.Stop()

    End Sub

    Private Sub DrawBar(ByVal sender As Object, ByVal e As EventArgs)

        _x += 1

        'account for border if necessary
        If _x = 0 Then
            If _border Then _x = 1
        End If

        'set to negative size of rects so it draws smoothly
        If _x > Me.Width Then _x = -(_width * 3 + 2)

        'create graphics object for drawing
        Dim gr As Graphics = Me.CreateGraphics

        gr.Clear(Me.BackColor)

        If _border Then gr.DrawRectangle(Pens.Black, New Rectangle(0, 0, Me.Width - 1, Me.Height - 1))

        gr.FillRectangle(New SolidBrush(_color), New Rectangle(_x, IIf(_border, 1, 0), _width, IIf(_border, Me.Height - 2, Me.Height)))
        gr.FillRectangle(New SolidBrush(_color), New Rectangle(_x + _width + 1, IIf(_border, 1, 0), _width, IIf(_border, Me.Height - 2, Me.Height)))
        gr.FillRectangle(New SolidBrush(_color), New Rectangle(_x + (_width * 2) + 2, IIf(_border, 1, 0), _width, IIf(_border, Me.Height - 2, Me.Height)))

    End Sub

    Private Sub DrawBorder()

        Dim gr As Graphics = Me.CreateGraphics

        gr.Clear(Me.BackColor)

        If _border Then gr.DrawRectangle(Pens.Black, New Rectangle(0, 0, Me.Width - 1, Me.Height - 1))

    End Sub

    Private Sub ProgressBarEx_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Resize
        DrawBorder()
    End Sub

    Private Sub ProgressBarEx_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
        DrawBorder()
    End Sub
 
try PBM_SETMARQUEE & PBS_MARQUEE

first you need to extend the style of the progressbar if you are familiar with GetWindowLong / SetWindowLong.

then do a SendMessage(Handle_To_ProgressBar_Here PBM_SETMARQUEE , True , Time_in_MilliSeconds_Here )

from Msdn ...
PBM_SETMARQUEE Message

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

Sets the progress bar to marquee mode. This causes the progress bar to move like a marquee.

Syntax


To send this message, call the SendMessage function as follows.
lResult = SendMessage( // returns LRESULT in lResult (HWND) hWndControl, // handle to destination control (UINT) PBM_SETMARQUEE, // message ID (WPARAM) wParam, // = (WPARAM) (BOOL) wParam; (LPARAM) lParam // = (LPARAM) (UINT) lParam; );
Parameters

wParam
Indicates whether to turn the marquee mode on or off.
lParam
Time in milliseconds between marquee animation updates.
Return Value

Returns whether marquee mode is set.

Remarks

Use this message when you do not know the amount of progress toward completion but wish to indicate that progress is being made.

Send the PBM_SETMARQUEE message to start or stop the animation.
 
It is worth noting that you could easily do this with an animated gif in a picturebox, provided that the progress bar is of a fixed size. (This won't be consistend with user's xp styles/color settings, though)
 
Thanks for all your help, does seems to look quite a bit of a mission just to produce a better looking progressbar. Think I'm gonna do a quick google just to make sure there is not a free activex out there somewhere.

Once again thanks
 
marble_eater said:
It is worth noting that you could easily do this with an animated gif in a picturebox
If you app is going to be a fixed size or even if the progress bar is going to exist in a fixed area such as a panel pane this would definately be a quick and easy work around to get the effects you are looking for. Windows itself took this approach for a lot of different tasks. AAhh...the old days of Windows with the file paper flying out of the cabinet, across the dialog box, crumpling up, and going into the trash..Thank goodness those are gone (mostly).

marble_eater said:
This won't be consistend with user's xp styles/color settings, though
Not a concern for most users but I have seen a few healthy debates on the subject in this forum that might suggest otherwise...
 
dynamic_sysop, I just got a chance to sit down and play with what you were talking about and that is totally sweet. Information on the subject is scarce at best. This is a link to C# code that does what you talk about with the marque stuff. It is a little confusing and I haven't found a VB version yet. Perhaps I or someone else will have time to translate this code and turn it into an easy to use control or something.

That is so cool. lidds, this is definately what you want and it is worth the effort to get it working. so much better than a custom animation or gif could ever be.

This is also kind of funny. An eerily similiar thread in the Etreme VB6 forums.
 
Last edited:
Here's a version that works:
Code:
Imports System
Imports System.Windows.Forms
Imports System.Runtime.InteropServices

Public Class Win32Interop

    Public Const WM_USER As Int32 = 1024
    Public Const PBM_SETMARQUEE As Int32 = (WM_USER + 10)
    Public Const GWL_STYLE As Int32 = -16
    Public Const PBS_MARQUEE As Int32 = 8

    <DllImport("user32.dll", EntryPoint:="GetWindowLong")> _
    Public Shared Function GetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Int32) As Int32

    End Function

    <DllImport("user32.dll", EntryPoint:="SetWindowLong")> _
    Public Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Int32, ByVal dwNewLong As Int32) As Int32

    End Function

    <DllImport("User32", SetLastError:=True)> _
    Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Int32, ByVal wParam As Int32, ByVal lParam As Int32) As Int32

    End Function

End Class

Public Class Form1
    Inherits System.Windows.Forms.Form

    Private _pb As Windows.Forms.ProgressBar

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

        Application.EnableVisualStyles()
        Application.DoEvents()

        _pb = New Windows.Forms.ProgressBar
        _pb.Dock = Windows.Forms.DockStyle.Fill
        Width = 500
        Height = 50

        Controls.Add(_pb)
        Dim i As Int32 = Win32Interop.GetWindowLong(_pb.Handle, Win32Interop.GWL_STYLE)

        Win32Interop.SetWindowLong(_pb.Handle, Win32Interop.GWL_STYLE, i Or Win32Interop.PBS_MARQUEE)
        Win32Interop.SendMessage(_pb.Handle, Win32Interop.PBM_SETMARQUEE, 1, 100)

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        components = New System.ComponentModel.Container
        Me.Text = "Form1"
    End Sub

#End Region
End Class
 
Last edited:
Since we are on the subject, is there a way to get the progress bar to have a smooth style instead of the chunky blocks?
 
Back
Top