# VBForums UtilityBank > UtilityBank - Utilities >  Basic Progress Bar Control

## Mxjerrett

EDIT:
Ok guys, the next version has been released and is available from the same download link as before. I am looking for an actual name to call this rather than just progress bar. So go ahead and feed them to me.  :Smilie: 
END EDIT

I whipped this up late last night, so it isn't perfect. I am sure there are many ways to shorten the code and I bet it can be made better, but for now I'll leave it as is. I am going to add the ability to change the font of the percentage, but that will come later.

I've never even so much as drawn with an API before so this was completely new to me. Also I've never made a usercontrol, but this was some good experience.


Version: 1.0.1

Features:


```
Able to set the background color (using 2 colors)
Able to set the fill color (using 2 colors)
Able to enable, disable gradients
Able to change font color
Able to disable percentage
Able to add a drop shadow
Able to set border color
Min and Max values.
```

Update Log:


```
'||||||||||||||||||||||||||||||||||||||||||||||||
'|                   UPDATE LOG                 |
'| times are all central time (GMT -6)          |
'|                                              |
'| June  8, 2008 - 11:30PM                      |
'|               - Work Begins                  |
'|                                              |
'| June 10, 2008 - 11:10PM                      |
'|               - stream-lined code            |
'|                 removed many unnecessary     |
'|                 calculations and calls.      |
'|               - added Min and Max value      |
'|                                              |
'||||||||||||||||||||||||||||||||||||||||||||||||
```

Benchmark Tests


```
Tested at 10000 loops
Microsoft Common Controls: 812ms
ProgressBar Control V 1.0.0: 5250ms | 84.5% less efficient at 10000 loops
ProgressBar Control V 1.0.1: 4688ms | 82.7% less efficient at 10000 loops
```


Pictures:

----------


## Merri

Back in the days I also started off by making a progress bar control as my first usercontrol. It was also one of the first things that got me interested on the speed side of things, because I noticed a progress bar could sometimes slow down a loop by a great deal. The progress bar in the Common Controls OCX is a great example of this.

Some of mine if you want to take a peek: 1.8 and 2.0

----------


## si_the_geek

That looks like an impressive first attempt.  :Thumb: 

There are a few things that slow it down, mainly due to repeating work.

A good example of this is the Red/Green/Blue functions, which each repeat the code to fill _strHexColour_.  As they are all used only once, by the same routine, what you could do is put them all into that routine (and thus only have the _strHexColour_ code once).. you could also remove the need for strings (which are slow), and find the values using maths instead (for an example, see the "_Convert colour number to colour name_" link in my signature, lines 9 to 12).

There are several other examples in the Redraw routine (which is run frequently, thus has a big effect), such as repeated calls to the RGB function with the same parameters (when you could call it once, and store the result to a variable), and repeating things like _UserControl.ScaleHeight / 2_ (which again could be stored - and could even be moved to the Resize event).  Also the .Right property of Rectangles(2) and (3) does not need to be calculated each time, only when the .Value changes, or the control is resized.


I haven't checked Merri's versions, but suspect you could get more ideas from them.

----------


## Mxjerrett

Hmm thanks for the tips SI. I'll correct them now. Also I am going to make a couple modifications to allow for min and max values. Do you know how to change the font when you use drawtext?

----------


## si_the_geek

I can't remember how you change the font, as I don't tend to use API's for text (I normally use Me.Print instead).  A forum search should find examples tho.

----------


## Merri

You can find extensive tips for DrawText by taking a look into UniLabel control I've created. In the other hand the control is also very complex as it includes all the features that are related to labels, but atleast you should get a hint on how to handle fonts. It has a procedure Private_SetFont that changes the current font in use. UserControl_Terminate removes the font. Private_WndProcContainer and Private_WndProcUserControl both have WM_PAINT messages that handle drawing the text. From there you can see that I change the font while I'm drawing, but also restore the original font right after I've drawn.

With progress bar you can simplify things quite a bit, but there is enough stuff that I'm not collecting it nicely into one code block example :P (Working on yet another Unicode control atm.)

You can find UniLabel in UniControls thread.

----------


## Mxjerrett

Hey guys I made some updates, tell me what you think now? Better or worse?

----------


## si_the_geek

I can't run it at the moment unfortunately, but the code looks better.  :Thumb: 

Did you use a compiled version to test the speed?  It can make a big difference.

----------


## Mxjerrett

hmm, no I just used the control, but I'll compile and test it now.

----------


## Merri

You need a bit more error checking, if I just add it to the form and run without setting anything, I get an immediate divizion by zero:



```
PercentWidth = IIf(m_Value > m_MinVal, UserControl.ScaleWidth - (((UserControl.ScaleWidth / m_MaxVal)) * (m_MaxVal - Value + m_MinVal)) - 1, 1)
```

The problem here is that you're using IIf, which is really one of the worst implementations in VB. It is a simple and super slow function, so all parameters you give it will be executed. A regular If works much better  :Smilie: 

You also want to give default values for Min and Max in InitProperties.


When control is added to the form:

Initialize -> InitProperties -> Show

In any other case:

Initialize -> ReadProperties -> Show

----------


## Mxjerrett

Hmm, I did exactly what you just said, and I didn't get any problem.

Also I already have:


```
    m_MinVal = m_def_MinVal
    m_MaxVal = m_def_MaxVal
    m_Value = m_def_Value
```

Under InitProperties

----------


## Merri

Here is exactly what I do to get the error:Download the control, I let it open up directly to VB.I add a form.I insert the progress bar to the form.I resize the progress bar.I hit run.VB complains that there is no startup form. I put it in place.I get the divizion by zero error.

----------


## Mxjerrett

I tried and I could not reproduce the error sorry.

----------


## si_the_geek

I couldn't either.. but would still recommend changing IIF to a regular IF, and not just in this situation.

An IIF is not only slow, but is also prone to the kind of errors Merri got.  This is because it _always_ calculates both the True and False results, whereas a normal If only calculates what is needed.

----------


## Mxjerrett

I did fix it, and on my next version it will be part of it.

----------

