Body Monitor


In this exercise, we will use progress bars and timers.


Besides the Progress control, Visual C++ provides two other progress-oriented controls: the Microsoft Progress Control Version 5.0 and the Microsoft Progress Control Version 6.0 with the main difference on their ability to assume one or two orientations.

Practical Learning: Introducing Body Monitor

  1. Start Microsoft Visual C++ and create a new MFC AppWizard (exe) application named BodyMonitor
  2. Create the project as a Dialog Based and set the Dialog Title as Body Monitor without the About Box
  3. Delete the TODO line and move the buttons to the bottom section of the dialog

Creating Progress Bars

To add a progress bar to your application, from the Insert ActiveX Control dialog box, select the desired one. For this lesson, because everything available in Version 5.0 is also available in Version 6.0, we will use the later.

After adding a progress bar to a parent window, it assumes a horizontal display. This is controlled by the Orientation property (not available in Version 5.0) whose default value is 0 ccOrientationHorizontal. If you want the progress bar to be vertical, change this property to a 1 ccOrientationVertical value.

The range of values that a progress bar can assume is set using the Min property for the minimum value and the Max field for the highest value.

Practical Learning: Creating Progress Bars

  1. Right-click anywhere on the dialog box and click Insert ActiveX Control
  2. In the ActiveX Control list of the Insert ActiveX Control dialog box, click Microsoft ProgressBar Control, version 6.0
  3. Click OK
  4. Right-click the newly added control and click Properties. In the Properties window, click the Control tab and change the Orientation property to 1 ccOrientationVertical
  5. On the dialog box, right-click the ProgressBar and click Copy. Right-click anywhere on the dialog box and click Paste many times until you get 10 ProgressBar controls
  6. Design the dialog box as follows (only the top labels and the ProgressBar controls need IDs):
    Control ID Caption Additional Properties
    Static Text IDC_VAL_BLOOD 000 Align Text: Center
    Static Text IDC_VAL_HEART 000 Align Text: Center
    Static Text IDC_VAL_KIDNEY 000 Align Text: Center
    Static Text IDC_VAL_BRAIN 000 Align Text: Center
    Static Text IDC_VAL_LLUNG 000  Align Text: Center
    Static Text IDC_VAL_RLUNG 000 Align Text: Center
    Static Text IDC_VAL_PANCREAS 000 Align Text: Center
    Static Text IDC_VAL_LIVER 000 Align Text: Center
    Static Text IDC_VAL_BLADDER 000 Align Text: Center
    Static Text IDC_VAL_STOMACH  000 Align Text: Center
    ProgressBar   IDC_PRGR_BLOOD 000 Align Text: Center
    ProgressBar   IDC_PRGR_HEART    
    ProgressBar   IDC_PRGR_KIDNEY    
    ProgressBar   IDC_PRGR_BRAIN    
    ProgressBar   IDC_PRGR_LLUNG    
    ProgressBar   IDC_PRGR_RLUNG    
    ProgressBar   IDC_PRGR_PANCREAS    
    ProgressBar   IDC_PRGR_LIVER    
    ProgressBar   IDC_PRGR_BLADDER    
    ProgressBar   IDC_PRGR_STOMACH    
  7. Press Ctrl + W to access the ClassWizard. Add a CString Value Variable for each label that has an ID and Add a CProgressBar Control Variable for each ProgressBar control as follows:
    Identifier Value Variable Control Variable
    IDC_VAL_BLOOD m_ValBlood  
    IDC_VAL_HEART m_ValHeart  
    IDC_VAL_KIDNEY m_ValKidney  
    IDC_PRGR_BLOOD   m_Blood
    IDC_PRGR_HEART   m_Heart
    IDC_PRGR_KIDNEY   m_Kidney
    IDC_PRGR_BRAIN   m_Brain
    IDC_PRGR_LLUNG   m_LLung
    IDC_PRGR_RLUNG   m_RLung
    IDC_PRGR_PANCREAS   m_Pancreas
    IDC_PRGR_LIVER   m_Liver
    IDC_PRGR_BLADDER   m_Bladder
    IDC_PRGR_STOMACH   m_Stomach
  8. Click OK
  9. Using the Resource Symbols dialog box, add ten new identifiers as IDT_BLOOD, IDT_HEART, IDT_KIDNEY, IDT_BRAIN, IDT_LLUNG, IDT_RLUNG, IDT_PANCREAS, IDT_LIVER, IDT_BLADDER, and IDT_STOMACH
  10. Click Close
  11. In the OnInitDialog() event of the dialog class, create the following timers and generate a random seed:
    BOOL CBodyMonitorDlg::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
    	SetTimer(IDT_BLOOD, 650, NULL);
    	SetTimer(IDT_HEART, 200, NULL);
    	SetTimer(IDT_KIDNEY, 450, NULL);
    	SetTimer(IDT_BRAIN, 1000, NULL);
    	SetTimer(IDT_LLUNG, 750, NULL);
    	SetTimer(IDT_RLUNG, 850, NULL);
    	SetTimer(IDT_PANCREAS, 800, NULL);
    	SetTimer(IDT_LIVER, 1200, NULL);
    	SetTimer(IDT_BLADDER, 550, NULL);
    	SetTimer(IDT_STOMACH, 1500, NULL);
    	return TRUE;  // return TRUE  unless you set the focus to a control
  12. Save All

Progress Bars Methods and Events

The values of a progress bar are float, unlike the progress control that mostly uses integers. To set the minimum value for the progress bar, call its SetMin() method. To set the maximum value, call the SetMax() method. These two methods expects a float number as argument. If these values have already been set, you can retrieve them by calling the GetMin() or the GetMax() methods respectively.

To set the initial value of the progress bar or to change its value any timer, you can call the SetValue() method. Also, at anytime, you can retrieve the position of the control by calling the GetValue() method.

Because the user cannot change the value of a progress bar, it does not fire value-related events. On the other hand, it provides you with the ability to do something when the user clicks or positions the mouse over the control. If you user simply positions the mouse or moves it on top of the progress bar, it fires the MouseMove() event. At the same time, if the user presses a mouse button on the progress bar, it fires the MouseDown() event. When the user releases the mouse, the MouseUp() event is sent. Clicking the progress bar causes it to fire the Click() event.

Practical Learning: Using a ProgressBar Control

  1. Generate a WM_TIMER message for the dialog box and implement it as follows:
    void CBodyMonitorDlg::OnTimer(UINT nIDEvent)
    	// TODO: Add your message handler code here and/or call default
    	float Blood = static_cast<float>(rand() % 100);
    	float Heart = static_cast<float>(rand() % 100);
    	float Kidney = static_cast<float>(rand() % 100);
    	float Brain = static_cast<float>(rand() % 100);
    	float LeftLung = static_cast<float>(rand() % 100);
    	float RightLung = static_cast<float>(rand() % 100);
    	float Pancreas = static_cast<float>(rand() % 100);
    	float Liver = static_cast<float>(rand() % 100);
    	float Bladder = static_cast<float>(rand() % 100);
    	float Stomach  = static_cast<float>(rand() % 100);
    	if( nIDEvent == IDT_BLOOD )
    		// Make a sound if the value of the heart is too high
    		if( Blood >= 85 )
    	if( nIDEvent == IDT_HEART )
    	if( nIDEvent == IDT_KIDNEY )
    	if( nIDEvent == IDT_BRAIN )
    	if( nIDEvent == IDT_LLUNG )
    	if( nIDEvent == IDT_RLUNG )
    	if( nIDEvent == IDT_PANCREAS )
    	if( nIDEvent == IDT_LIVER )
    	if( nIDEvent == IDT_BLADDER )
    	if( nIDEvent == IDT_STOMACH )
    	m_ValBlood.Format("%.f.%d", m_Blood.GetValue(), rand()%99);
    	m_ValHeart.Format("%.f\260", m_Heart.GetValue());
    	m_ValKidney.Format("%.f\045", m_Kidney.GetValue());
    	m_ValBrain.Format("<%.f", m_Brain.GetValue());
    	m_ValLLung.Format("%.f'%d\"", m_LLung.GetValue(), 2+rand()%9);
    	m_ValRLung.Format("%.f\261", m_RLung.GetValue());
    	m_ValPancreas.Format("\273%.f", m_Pancreas.GetValue());
    	m_ValLiver.Format("%.f\260", m_Liver.GetValue());
    	m_ValBladder.Format("\247%.f\252", m_Bladder.GetValue());
    	CString SCode;
    	case 0:
    		SCode.Format("%s", "\274");
    	case 1:
    		SCode.Format("%s", "\275");
    	case 2:
    		SCode.Format("%s", "\276");
    	m_ValStomach.Format("%.f%s", m_Stomach.GetValue(), SCode);
  2. Test the application
  3. Close it and return to MSVC

Home Copyright 2003-2005 FunctionX, Inc.