Visual Basic Window/Form Routines
Pure VB: Customizable PhotoShop-Style ProgressBar in a MDI App
     
Posted:   Sunday June 1, 1997
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6
Developed with:   VB4-32, Windows 95
OS restrictions:   None
Author:   VBnet - Randy Birch
     

Related:  

SetParent: Add a VB Progress Bar to a VB StatusBar
SendMessage: Change the Colour of a VB ProgressBar
Pure VB: Customizable PhotoShop-Style ProgressBar
CreateWindowEx: Creating a Common Control Progress Bar - Overview
CreateWindowEx: Creating the Common Control Flood Panel via the API
SetParent: Display Modal Form Activity on a Parent Form's 'PhotoShop-style' Progress Bar
SetParent: Display Modal Form Activity in a Parent Form's VB Progress Bar
     
 Prerequisites
None.

bitbltfloodmdi.gif (4394 bytes)This page is a conclusion to the code presented in Creating a Custom PhotoShop-Style Flood Panel to add a custom flood status panel to a new or existing MDI application.

The routine here is based on code originally developed to overcome some of the display limitations of the original VB3 SSPanel FloodPercent control, namely justification of text and positioning as a member inside a status panel. The routine was originally developed in VB3, and has been updated for use under 32-bit VB. The method presented here remains a more than viable alternative to a standard flood/status control.

The inspiration for the design was the Adobe PhotoShop status panel, which indicates progress of an operation as a text message overtop a progress bar. As the progress continues, the text reverses to remain readable. The code below can be easily integrated into any existing MDI (or SDI) project where a fully-customizable status panel is required.
 BAS Module Code
Place the following code into the general declarations area of a bas module:

Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright 1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'used to avoid the need to repeatedly pass
'a string when calling the FloodUpdate routine   
Dim fmsg As String
  
'variable set in the FloodDisplay sub   
Dim f As PictureBox


Public Sub FloodDisplay(upperLimit, floodMessage As String)
   
   'set the module-level variable f
   'equal to the parent form flood panel   
    Set f = frmMDIMain.tbFlood
       
   'initialize the control by setting:
   'white (the text colour)
   'black (the flood panel colour)
   'not Xor pen
   'solid fill   
    f.BackColor = &HFFFFFF
    f.ForeColor = &H0&
    f.DrawMode = 10
    f.FillStyle = 0
       
   'set the scalewidth equal to the
   'upper limit of the items to count   
    f.ScaleWidth = upperLimit
      
    f.Cls
    f.Visible = True
       
   'set a form-level variable for the flood message
   'to avoid the need for continually passing a string   
    fmsg = floodMessage
    
End Sub


Sub FloodHide()
  
  'hide the flood panel   
   f.Visible = False
   f.Cls
  
  'free the memory used by the f object  
   Set f = Nothing
  
End Sub


Public Sub FloodUpdateText(progress)

    Dim r As Long
          
   'make sure that the flood display hasn't already hit 100%

    If progress <= f.ScaleWidth Then    
   
     'trap in case the code below attempts to set
     'the scalewidth greater than the max allowable   
      If progress > f.ScaleWidth Then progress = f.ScaleWidth
              
     'clear the flood   
      f.Cls
        
     'calculate the string's X & Y coordinates for left-justified 
     'and vertically centered text and print the string  
      f.CurrentX = 2
      f.CurrentY = (f.ScaleHeight - f.TextHeight(fmsg)) \ 2
      f.Print fmsg
        
     'fill in the flood bar to the new progress length   
      f.Line (0, 0)-(progress, f.ScaleHeight), f.ForeColor, BF
         
     'REQUIRED: allow the flood to complete drawing   
      DoEvents
    
    End If

End Sub
 Form Code
To create this demo, start a new project and add an MDI window (MDIForm1). Add to the window a container-style object - either a picturebox or a SSPanel from the Pro and Enterprise version. Its name doesn't matter for this code. Set the control's alignment as desired, and add into (by drawing inside the container) a picturebox to act as the flood (tbFlood), and size as required.

Add a second form (Form1) to the project, and set its MDIChild property to true. Set the application's startup option to MDIForm1.

On the child window, draw the three buttons as indicated (Command1, Command2, Command3).

Add the following code to the MDI Child form:

Option Explicit

Private Sub Command3_Click()

    Unload MDIForm1
    
End Sub


Private Sub Command2_Click()

  'hide the flood panel
   FloodHide

End Sub


Private Sub Command1_Click()

    Dim i As Integer
    Dim upperLimit As Integer

    upperLimit = 250
        
   'make the status display flood panel visible.    
    FloodDisplay upperLimit, "MDI Parent Flood Demo... please wait."
    
    For i = 1 To upperLimit
        
      '(code for some action here)    
              
      'update the status display progress by 
      'the unit 1 (from the For..Next loop)    
       FloodUpdateText i
       
    Next

End Sub
 Comments
Because you are, in effect, setting the BackColor for the text and the ForeColor for the background, certain colour combinations can lead to rather interesting results.

In practical use, implementation is rather straightforward. For example, to indicate the progress loading a list of names from a random access file, your code may look like:
    ClientFileNo = FreeFile
   
   'Client is a user defined type containing client data   
    Open "Client.dat" For Random Access _
           Read Write As #ClientFileNo Len = Len(Client)
   
   'this is the number used as upperlimit   
    TotalClients = LOF(ClientFileNo) \ Len(Client)

    FloodDisplay TotalClients, "Loading client names..."

    For i = 1 To TotalClients
    
       Get #ClientFileNo, i, Client
      
      'the current progress is the status of the For...Next loop   
       FloodUpdateText i
             
       '(your code to do something here)   
        
      Next i
    
    FloodHide

Finally, as this entire page may seem daunting at first glance, I have reproduced below (without comments) just the actual module routine required to fill the flood. As you can see, its pretty concise:

Public Sub FloodUpdateText(progress)

    If progress <= f.ScaleWidth Then

      If progress > f.ScaleWidth Then progress = f.ScaleWidth

      f.Cls
      f.CurrentX = 2
      f.CurrentY = (f.ScaleHeight - f.TextHeight(fmsg)) \ 2
      f.Print fmsg
      f.Line (0, 0)-(progress, f.ScaleHeight), f.ForeColor, BF

      DoEvents
    End If

End Sub

 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

Hit Counter