Home

Windows Controls: The Progress Control

  

Introduction to Progress Controls

 

Description

 

The Progress control is used to display the evolution of an activity, especially for a long operation. Like a label, a progress control is used only to display information to the user who cannot directly change it.

Practical LearningPractical Learning: Introducing Progress Controls

  1. Start Microsoft Visual Studio
  2. To create a new application, on the main menu, click File -> New Project...
  3. In the middle list, click MFC Application and set the name to ProgressClock1
  4. Click OK
  5. In the first page of the wizard, click Next
  6. In the second page of the wizard, click Dialog based and click Next
  7. In the third page of the wizard, click Finish

Creating a Progress Control

To create a progress control, on the Toolbox, you can click the Progress Control Progress Control and click the desired area on the parent window. In the .rc file, the line used to create a progress control uses the following formula:

CONTROL "", ID, "msctls_progress32", WS_BORDER, 12, 192, 180, 14

After adding the control to its host, as done for the other controls, you can add a member variable to it.

The progress control is based on the CProgressCtrl class. Therefore, to dynamically create a progress control, declare a variable or a pointer to CProgressCtrl using its constructor. To initialize it, call its Create() member function and set the necessary characteristics. Here is an example:

void CExerciseDlg::OnBnClickedProgressControl()
{
    // TODO: Add your control notification handler code here
    CProgressCtrl *Progress = new CProgressCtrl;

    Progress->Create(WS_CHILD | WS_VISIBLE,
     		     CRect(10, 10, 288, 35), this, 0x16);
}

The CProgressCtrl class is also equipped with the CreateEx() member function that allows you to add extended styles to the control.

Practical LearningPractical Learning: Creating Progress Controls

  1. Design the dialog box as follows:
     
    Progressive Clock
    Control Caption ID
    Static Text Static Text Value  
    Static Text Static Text Hours:  
    Progress Control Progress Control   IDC_PROGRESS_HOURS
    Static Text Static Text 00 IDC_HOURS
    Static Text Static Text Minutes:  
    Progress Control Progress Control   IDC_PROGRESS_MINUTES
    Static Text Static Text 00 IDC_MINUTES
    Static Text Static Text Seconds:  
    Progress Control Progress Control   IDC_PROGRESS_SECONDS
    Static Text Static Text 00 IDC_SECONDS
    Button Button Cancel IDCANCEL
  2. Right-click each of the progress controls and 00 static controls then click Add Variable...
  3. Create the variables as follows:
     
    ID
    Category Type Name
    IDC_PROGRESS_HOURS Control CProgressCtrl m_ProgressHours
    IDC_HOURS Value int m_Hours
    IDC_PROGRESS_MINUTES Control CProgressCtrl m_ProgressMinutes
    IDC_WEEK1TUESDAY Value int m_Minutes
    IDC_WEEK1WEDNESDAY Value CProgressCtrl m_ProgressSeconds
    IDC_WEEK1THURSDAY Value int m_Seconds
 
 
 

Characteristics of a Progress Control

   

The Position of a Progress Control

A progress control uses a numeric value to draw its position. By default, it uses an integer (a value between -2,147,483,648 to 2,147,483,647).

A progress control shows its current value using a position. It draw a blue rectangle from the begining to that position. To let you specify the position, the CProgressCtrl class is equipped with a mmember function named SetPos. Its syntax is:

int SetPos(int nPos);

This member function can be called either to set the initial value of the control or to simply change it at any time. Here is an example:

void CExerciseDlg::OnBnClickedProgressControl()
{
    // TODO: Add your control notification handler code here
    CProgressCtrl *Progress = new CProgressCtrl;

    Progress->Create(WS_CHILD | WS_VISIBLE,
		     CRect(10, 10, 288, 35), this, 0x16);
    Progress->SetPos(38);
}

 

Progress Control

While the control is working, if you want to find out the value it is holding, you can call the CProgressCtrl::GetPos() member function. Its syntax is:

int GetPos( );

This member function returns the current position of the progress control. Here is an example of calling it:

Progress Control

CExerciseDlg::CExerciseDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CExerciseDlg::IDD, pParent)
	, m_Evolution(0)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CExerciseDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_PROGRESSOR, m_Progress);
	DDX_Text(pDX, IDC_EVOLUTION, m_Evolution);
}

BEGIN_MESSAGE_MAP(CExerciseDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_PROGRESS_CONTROL, &CExerciseDlg::OnBnClickedProgressControl)
	ON_BN_CLICKED(IDC_PROGRESS_VALUE, &CExerciseDlg::OnBnClickedProgressValue)
END_MESSAGE_MAP()

// CExerciseDlg message handlers

... No Change

void CExerciseDlg::OnBnClickedProgressValue()
{
	// TODO: Add your control notification handler code here
	m_Evolution = m_Progress.GetPos();

	UpdateData(FALSE);
}

The Range of Values of a Progress Control

To express its evolution, a progress control uses values from a minimum to a maximum. These limit values are set using the CProgressCtrl::SetRange() or the CProgressCtrl::SetRange32() member functions. Their syntaxes are:

void SetRange(short nLower, short nUpper);
void SetRange32(int nLower, int nUpper);

The nLower argument sets the minimum value for the control. The nUpper argument is the maximum value of the control. Here is an example:

void CExerciseDlg::OnBnClickedProgressControl()
{
    // TODO: Add your control notification handler code here
    CProgressCtrl *Progress = new CProgressCtrl;

    Progress->Create(WS_CHILD | WS_VISIBLE,
		     CRect(10, 10, 288, 35), this, 0x16);
    Progress->SetRange(1, 100);
}

If the range of values has already been set and you want to find it out, you can call the CProgressCtrl::GetRange() member function. Its syntax is:

void GetRange(int& nLower, int& nUpper);

This member function returns two values: nLower is the current minimum value of the control while nUpper is returned as its maximum value.

The Step of Value of a Progress Control

Once a progress control has been created and when it comes up, it assumes its minimum value. While the control is working, it keeps changing its value by stepping to the next value. By default, its next value is set to 10. If you want to specify a different incremental value, call the CProgressCtrl::SetStep() member function whose syntax is:

int SetStep(int nStep);

The nStep argument is the value set to increment the position of the progress control. Once this value is set, when the control is progressing, it increments its value by that value to get to the next step. If you want to explicitly ask it to step to the next incremental value, call the CProgressCtrl::StepIt() member function. Its syntax is:

int StepIt();

Here is an example of calling these member functions:

void CExerciseDlg::OnBnClickedProgressValue()
{
	// TODO: Add your control notification handler code here
	m_Progress.StepIt();
	m_Evolution = m_Progress.GetPos();

	UpdateData(FALSE);
}

Practical LearningPractical Learning: Implementing Progress Controls

  1.  In the Class View, expand the name of the project and click CProgressClock
  2. In the lower part of the Class View, double-click OnInitDialog
  3. To specify the initial values of the progress controls, change the event as follows:
    BOOL CProgressClockDlg::OnInitDialog()
    {
        CDialogEx::OnInitDialog();
    
        // Set the icon for this dialog.  The framework does this automatically
        //  when the application's main window is not a dialog
        SetIcon(m_hIcon, TRUE);			// Set big icon
        SetIcon(m_hIcon, FALSE);		// Set small icon
    
        // TODO: Add extra initialization here
        m_ProgressHours.SetRange(0, 23);
        m_ProgressHours.SetStep(1);
        m_ProgressMinutes.SetRange(0, 59);
        m_ProgressMinutes.SetStep(1);
        m_ProgressSeconds.SetRange(0, 59);
        m_ProgressSeconds.SetStep(1);
    
        SetTimer(1, 40, NULL);
    
        return TRUE;  // return TRUE  unless you set the focus to a control
    }
  4. In the Class View, click CProgressClock
  5. In the Properties window, click the Messages button Messages
  6. Click WM_TIMER, then click its arrow and select <Add> OnTimer
  7. Implement the event as follows:
    void CProgressClockDlg::OnTimer(UINT_PTR nIDEvent)
    {
        // TODO: Add your message handler code here and/or call default
        // Get the current time of the computer
        CTime CurTime = CTime::GetCurrentTime();
    
        // Find the hour, the minute, and the second values of the time
        int ValHours = CurTime.GetHour();
        int ValMinutes = CurTime.GetMinute();
        int ValSeconds = CurTime.GetSecond();
    
        // Change each progress bar accordingly
        m_ProgressHours.SetPos(ValHours);
        m_ProgressMinutes.SetPos(ValMinutes);
        m_ProgressSeconds.SetPos(ValSeconds);
    
        // Display the position of the progress in the right label
        m_Hours   = m_ProgressHours.GetPos();
        m_Minutes = m_ProgressMinutes.GetPos();
        m_Seconds = m_ProgressSeconds.GetPos();
    
        UpdateData(FALSE);
    
        CDialogEx::OnTimer(nIDEvent);
    }
  8. To test the application, press F5
     
    Progressive Clock
     
    Progressive Clock
  9. Close the dialog box and return to your programming environment

The Color of a Progress Control

By default, the progress control draws its representation in a dark blue color. Microsoft Windows allows you to apply any color of your choice on a progress control. To support this, the CProgressCtrl class is equipped with a member function named SetBarColor. Its syntax is:

COLORREF SetBarColor(COLORREF clrBar);

When calling this function, pass a color as argument. Here is an example:

BOOL CExerciseDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);			// Set big icon
    SetIcon(m_hIcon, FALSE);		// Set small icon

    // TODO: Add extra initialization here
    CProgressCtrl *Progress = new CProgressCtrl;

    Progress->Create(WS_CHILD | WS_VISIBLE,
		     CRect(10, 10, 288, 35), this, 0x16);

    Progress->SetBarColor(RGB(255, 100, 25));
    Progress->SetPos(38);

    return TRUE;  // return TRUE  unless you set the focus to a control
}

Progress Control

To let you find out the color that a progress control is using, the CProgressCtrl class is equipped with a member function named GetBarColor. Its syntax is:

COLORREF GetBarColor() const;

The Background Color of a Progress Control

By default, a progress control is transparent, or it draws its field in the same color as its host. To let you change the color of the field, the CProgressCtrl class is equipped with a member function named SetBkColor. Its syntax is:

COLORREF SetBkColor(COLORREF clrNew);

Here is an example:

BOOL CExerciseDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);			// Set big icon
    SetIcon(m_hIcon, FALSE);		// Set small icon

    // TODO: Add extra initialization here
    CProgressCtrl *Progress = new CProgressCtrl;

    Progress->Create(WS_CHILD | WS_VISIBLE,
		     CRect(10, 10, 288, 35), this, 0x16);

    Progress->SetBkColor(RGB(255, 200, 205));
    Progress->SetBarColor(RGB(105, 5, 0));
    Progress->SetPos(38);

    return TRUE;  // return TRUE  unless you set the focus to a control
}

Progress Control

To let you get the field color of a progress control, the CProgressCtrl class is equipped with a member function named GetBkColor. Its syntax is:

COLORREF GetBkColor() const;

The Orientation of a Progress Control

After adding a progress control to a host, it assumes a horizontal orientation by default. If you want the progress control to be vertical, check its Vertical property or set it to True. If you are dynamically creating the control and you want it vertical, add the PBS_VERTICAL style to it, then change the width and the height to your liking. Here is an example:

BOOL CDlgProgress1Dlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    SetIcon(m_hIcon, TRUE); // Set big icon
    SetIcon(m_hIcon, FALSE); // Set small icon

    // TODO: Add extra initialization here
    CProgressCtrl *Progress = new CProgressCtrl;

    Progress->Create(WS_CHILD | WS_VISIBLE | PBS_VERTICAL,
		     CRect(10, 10, 28, 245), this,0x16);

    return TRUE; // return TRUE unless you set the focus to a control
}

A Smooth Progress Control

A progress control displays regular small rectangles inside a longer or taller rectangle. This outside rectangle serves as their border. If you don't want the border that delimits the control and you are designing the control, set the Border property to False.

The small rectangles appear distinct from one another. If you don't want the small rectangles visible, you can create a smooth progress bar by checking the Smooth property or setting it to True. This is equivalent to adding the PBS_SMOOTH style. Here is an example:

BOOL CDlgProgress1Dlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    SetIcon(m_hIcon, TRUE); // Set big icon
    SetIcon(m_hIcon, FALSE); // Set small icon

    // TODO: Add extra initialization here
    CProgressCtrl *Progress = new CProgressCtrl;

    Progress->Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
		     CRect(10, 10, 288, 35), this,0x16);

    return TRUE; // return TRUE unless you set the focus to a control
}
 
 
   
 

Home Copyright © 2010-2011 FunctionX, Inc.