Macintosh-like Progress Control

Environment: Windows NT4 SP4, Visual C++ 6

This image shows an example of my CMacProgressCtrl and CMacSliderCtrl. For more information on the CMacSliderCtrl, please refer to this article.

This class is my attempt at recreating the progress control of the Macintosh. This control (CMacProgressCtrl) allows you to change its colors as well as set an "indeterminate state" (similar to the "barber pole" look of progress controls on the Mac). This state can be used to indicate to the user that the length of time to finish the current operation is unknown.

Public Member Functions

void SetColor(COLORREF crColor)
void SetIndeterminate(BOOL bIndeterminate = TRUE)
BOOL GetIndeterminate()

Steps to add a CMacProgressCtrl to a dialog

  • Add the desired files to your project.
  • Add the #include directive to the header file of your dialog class.
  • Add a progress control to your dialog in the resource editor.
  • Use ClassWizard to add a member variable of type CMacProgressCtrl for the corresponding controls you just added. If the CMacProgressCtrl classe is not in the Variable Type list, choose CProgressCtrl, and manually change the types in the header file of your dialog class.
  • Downloads

    Special Note: The demo and source files are the sames available in the CMacSliderCtrl article.
    Download demo project - 35 Kb
    Download source - 11 Kb


    • Progess bar resize and look

      Posted by Legacy on 04/15/2003 12:00am

      Originally posted by: proxima centauri

      This control looks great as it is in the demo.
      However, if I resize the progress bar control, to make it larger, the "macintosh" effect is lost and it doesn't look as sharp. This is due to the fact that you are using magic numbers (fixed number values) instead of parameterized value considering the height and width of the control to draw the mac-like effect.

      Any chance anybody had spare time to implement it?


    • api windows

      Posted by Legacy on 10/23/2002 12:00am

      Originally posted by: didier

      not mfc slider , with api windows ?

      Style : wProc(WM_PAINT), SendMessage etc.


    • Fix for: Immediate display of channel, thumb, and selection color changes for both Mac Sliders.

      Posted by Legacy on 07/11/2001 12:00am

      Originally posted by: Keith L Hatfield

      A. Add the following four lines:

      void CMacTest2Dlg::OnButtonSelColor()
      CColorDialog dlg(m_sldMac1.GetSelectionColor());
      if (dlg.DoModal() != IDOK)
      //Start NEW
      //End NEW

      to: CMacTest2Dlg::OnButtonSelColor().

      Add with appropriate object name modifications to: CMacTest2Dlg::OnButtonSelcolor2(),
      and CMacTest2Dlg::OnButtonThumbcolor2().

      Seems to generate the correct WMs to CMacSliderCtrl::OnCustomDraw().

      B. Since there is a button for changing the second CMacSliderCtrl's selection color, here's what you do to get it working:

      1. Edit the Properties of IDC_SLIDER_MAC2 and on the Styles tab check "Enable Selection".

      2. Add the following line to BOOL MacTest2Dlg::OnInitDialog():

      m_sldMac2.SetSelection(35, 65);

    • Real fix for Color problems in Release mode

      Posted by Legacy on 05/08/2001 12:00am

      Originally posted by: Tim Ranker

      The problem was in the "if" statements of LightenColor.
      It was an unsafe assumption that (b<COLOR> + bIncreaseVal) was to be evaluated and treated as a data type larger than a BYTE. In release mode, the compiler's optimizations treated (b<COLOR> + bIncreaseVal) as a byte resulting in (b<COLOR> + bIncreaseVal) always being <= 255. Changing the colors to words for the calculations fixes the problem.

      COLORREF CFingerView::LightenColor(const COLORREF crColor, BYTE bIncreaseVal)
      WORD wRed = GetRValue(crColor);
      WORD wGreen = GetGValue(crColor);
      WORD wBlue = GetBValue(crColor);

      if ((wRed + bIncreaseVal) <= 255)
      wRed += bIncreaseVal;
      if ((wGreen + bIncreaseVal) <= 255)
      wGreen += bIncreaseVal;
      if ((wBlue + bIncreaseVal) <= 255)
      wBlue += bIncreaseVal;

      return RGB(wRed, wGreen, wBlue);


    • Change Background color

      Posted by Legacy on 01/18/2001 12:00am

      Originally posted by: byungbok

      I added bk-color change code .....

      void CMacSliderCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)

      if (lpcd->dwDrawStage == CDDS_PREPAINT)
      // <----------- Add
      CDC *pDC = CDC::FromHandle(lpcd->hdc);
      int nSavedDC = pDC->SaveDC();

      CRect rect(lpcd->rc);
      // RGB(...) we can change ,we want to a color

      // $ <--------------Add

      // Request prepaint notifications for each item.

      // Because we returned CDRF_NOTIFYITEMDRAW in response to
      // CDDS_PREPAINT, CDDS_ITEMPREPAINT is sent when the control is
      // about to paint an item.
      if (lpcd->dwDrawStage == CDDS_ITEMPREPAINT)
      CDC *pDC = CDC::FromHandle(lpcd->hdc);
      CRect rect(lpcd->rc);
      int nSavedDC = pDC->SaveDC();

      if (lpcd->dwItemSpec == TBCD_TICS)
      *pResult = CDRF_DODEFAULT;
      } // if drawing tics
      else if (lpcd->dwItemSpec == TBCD_THUMB)


    • FIXED: Color problems in release

      Posted by Legacy on 02/18/2000 12:00am

      Originally posted by: Sengoku

      Replace the color functions with these:

      COLORREF LightenColor(const COLORREF crColor, UINT nIncreaseVal);
      COLORREF DarkenColor(const COLORREF crColor, UINT nReduceVal);

      COLORREF LightenColor(const COLORREF crColor, UINT nIncreaseVal)
      BYTE byRed = GetRValue(crColor);
      BYTE byGreen = GetGValue(crColor);
      BYTE byBlue = GetBValue(crColor);

      if ((byRed + nIncreaseVal) <= 255)
      byRed = BYTE(byRed + nIncreaseVal);
      if ((byGreen + nIncreaseVal) <= 255)
      byGreen = BYTE(byGreen + nIncreaseVal);
      if ((byBlue + nIncreaseVal) <= 255)
      byBlue = BYTE(byBlue + nIncreaseVal);

      return RGB(byRed, byGreen, byBlue);

      COLORREF DarkenColor(const COLORREF crColor, UINT nReduceVal)
      BYTE byRed = GetRValue(crColor);
      BYTE byGreen = GetGValue(crColor);
      BYTE byBlue = GetBValue(crColor);

      if (byRed >= nReduceVal)
      byRed = BYTE(byRed - nReduceVal);
      if (byGreen >= nReduceVal)
      byGreen = BYTE(byGreen - nReduceVal);
      if (byBlue >= nReduceVal)
      byBlue = BYTE(byBlue - nReduceVal);

      return RGB(byRed, byGreen, byBlue);

    • Color problem in Release-Builds

      Posted by Legacy on 01/14/2000 12:00am

      Originally posted by: Harald Dietewich


      I have found out difference colorings in the CMacProgressCtrl when changing between Release- and Debug-Builds. In Debug-Builds, everything is OK. But when I do a Release-Build, the color is not the same!! I have also tested with the demo project by deleting the two lines that explicitly set the color in OnInitDialog(), so that my systems COLOR_HIGHLIGHT (= DWORD(8421376)) will be used.

      // m_progMac1.SetColor(RGB(255, 0, 0));
      // m_progMac2.SetColor(RGB(0, 0, 255));

      But you can explicitly use


      This also leads to different colors for the different builds. I have found out that removing the compilers optimization (switches "Full optimization" and "Global optimization") for release builds solves the problem. But I would like to know, why. For now, I have helped by including the following pragma immediately after #include "stdafx.h" in MacProgressCtrl.cpp:

      #pragma optimize("g", off)

      At the end of the file, the settings are restored with:

      #pragma optimize("", on)

      My system: TRUE COLOR on 1024*768, NT4 SP5, VC++ 6.0 SP3. Any idea?


      The line no. 219

      pOldPen = pDC->SelectObject(&m_penColor);

      in CMacProgressCtrl::DrawHorizontalBar() is wrong and can be deleted completely. If not deleted it must be changed to


      at least. The wrong statement leads to the wrong oldPen being selected at the end of the function.

    • Use of MacProgressCtrl with VC5

      Posted by Legacy on 01/13/2000 12:00am

      Originally posted by: Christian Schoenweger

      Is there a posibility to compile (and use) the control with VC5 instead of VC6 ?

    Leave a Comment
    • Your email address will not be published. All fields are required.

    Top White Papers and Webcasts

    • Anthony Christie, the Chief Marketing Officer for Level Communications, is responsible for customer experience, worldwide marketing and product management. In this informative asset, he shares his insights into why a private network connection to cloud-bases applications is the right decision for your enterprise. Download now to find out more.

    • Enterprises are increasingly looking to platform as a service (PaaS) to lower their costs and speed their time to market for new applications. Developing, deploying, and managing applications in the cloud eliminates the time and expense of managing a physical infrastructure to support them. PaaS offerings must deliver additional long-term benefits, such as a lower total cost of ownership (TCO), rapid scalability, and ease of integration, all while providing robust security and availability. This report …

    Most Popular Programming Stories

    More for Developers

    RSS Feeds

    Thanks for your registration, follow us on our social networks to keep up-to-date