Click here to Skip to main content
15,885,278 members
Articles / Desktop Programming / MFC

CSkinProgress

Rate me:
Please Sign up or sign in to vote.
4.97/5 (102 votes)
11 Jul 2003Zlib9 min read 545.1K   14.1K   209  
A bitmapped progress bar in a status bar with optional completion status message
/******************************************************************************/
/* NAME              : SkinProgress.h                                         */
/* PURPOSE           : Place a bitmapped progress bar into the status bar     */
/* CREATED_BY        : Kochise (kochise@caramail.com)                         */
/* CREATION_DATE     : $C_DATE=YYYY/MM/DD$ 22003/05/02                        */
/* MODIFIED_BY       : Kochise (kochise@caramail.com)                         */
/* MODIFICATION_DATE : $M_DATE=YYYY/MM/DD$ 2003/07/12                         */
/* LANGUAGE          : MFC Visual C++ 6                                       */
/* MPROC_TYPE        : Microsoft Windows compatible computer                  */
/*                                                                            */
/*
$Log: E:\Projects\NoeZooArc\SkinProgressTest.zoo\SkinProgressTest\SkinProgress.cpp.adiff $
 *
 *   Rev 1.02 : July 12 2003 14:01:53 (Kochise)
 * Base : CSkinProgress 1.32dev
 *   extracting files : no error
 *   parsing files : no error
 *   diff engine : no error
 *   modify.public.constructor:CSkinProgress
 *   touch.protected.function:CreateCommon
 *   modify.protected.function:ProgressInStatusBar
 *   modify.protected.function:ProgressInDialog
 *   modify.public.function:SetRange
 *   touch.public.function:SetPos
 *   modify.public.function:GetPos
 *   touch.public.function:SetStart
 *   modify.public.function:GetStart
 *   modify.public.function:Reset
 *   add.public.function:SetProgress
 *   add.public.function:GetProgress
 *   modify.public.function:RefreshPanes
 *   touch.protected.function:CompactText
 *   modify.protected.function:GetTimed
 *   modify.protected.function:UpdateProgress
 *   modify.protected.function:OnPaint
 *   compiling project files : no error
 *   packing files : no error
 * http://www.codeproject.com/miscctrl/CSkinProgress.asp
 *
 *   Rev 1.01 : July 06 2003 22:08:37 (Kochise)
 * Base : CSkinProgress 1.28 Devel
 *   extracting files : no error
 *   parsing files : no error
 *   diff engine : no error
 *   modify.public.constructor:CSkinProgress
 *   add.public.constructor:CSkinProgress
 *   modify.public.function:SetBitmap
 *   modify.public.function:ConvBitmap
 *   modify.public.function:SetRange
 *   modify.public.function:SetPos
 *   modify.public.function:OffsetPos
 *   modify.public.function:StepIt
 *   modify.public.function:SetSize
 *   add.public.function:GetSize
 *   add.public.function:GetPos
 *   add.public.function:GetStep
 *   add.public.function:GetLower
 *   add.public.function:GetUpper
 *   add.public.function:SetStart
 *   add.public.function:GetStart
 *   add.public.function:Reset
 *   modify.public.function:SetText
 *   mutate.function:protected.ResizeTextPane->public.RefreshPanes
 *   modify.public.function:RefreshPanes
 *   mutate.function:public.Clear->protected.Clear
 *   add.protected.function:GetTargetRect
 *   mutate.protected.function:Create->CreateCommon
 *   modify.protected.function:CreateCommon
 *   add.protected.function:ProgressInStatusBar
 *   add.protected.function:ProgressInDialog
 *   modify.protected.function:CompactText
 *   add.protected.function:UpdateProgress
 *   modify.protected.function:OnPaint
 *   compiling project files : no error
 *   packing files : no error
 * http://www.codeproject.com/miscctrl/CSkinProgress.asp
 *
 *   Rev 1.00 : May 25 2003 13:25:12 (Kochise)
 * First archived version and released onto CodeProject.
 * Base : CSkinProgress 1.12 Devel
 *   add.public.constructor:CSkinProgress
 *   add.public.constructor:CSkinProgress
 *   add.public.function:SetRange
 *   add.public.function:SetText
 *   add.public.function:SetSize
 *   add.public.function:SetBitmap
 *   add.public.function:CopyBitmap
 *   add.public.function:ConvBitmap
 *   add.public.function:SetPos
 *   add.public.function:OffsetPos
 *   add.public.function:SetStep
 *   add.public.function:StepIt
 *   add.public.function:Clear
 *   add.public.destructor:~CSkinProgress
 *   add.protected.function:Create
 *   add.protected.function:GetStatusBar
 *   add.protected.function:ResizeTextPane
 *   add.protected.function:CompactText
 *   add.protected.function:GetTimed
 *   add.protected.function:OnEraseBkgnd
 *   add.protected.function:OnPaint
 *   add.protected.function:OnSizing
 *   add.protected.function:OnSize
 *   add.protected.function:OnTimer
 *   compiling project files : no error
 *   packing files : no error
 * http://www.codeproject.com/useritems/CSkinProgress.asp
 *
 */
/******************************************************************************/

#if !defined(AFX_SKINPROGRESS_H__1DF43017_611B_44BD_822A_FAA0E01B2257__INCLUDED_)
#define AFX_SKINPROGRESS_H__1DF43017_611B_44BD_822A_FAA0E01B2257__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// SkinProgress.h : header file
//

/*** eSkinProgressBitmap ******************************************************/
/* Purpose : Used in 'OnPaint' for internal purposes, in order to index the   */
/*           m_BarImgLst's elements                                           */
/* Unit    : None                                                             */
/* Range   : enum LIST                                                        */
/* List    :  0 = cSPB_START               : image for the start              */
/*            1 = cSPB_BEFORE              : image for before <m_nLeft>       */
/*            2 = cSPB_LEFT  = cSPB_TOP    : image for <m_nLeft>/<m_nLower>   */
/*            3 = cSPB_CENTER              : image for the center of the bar  */
/*            4 = cSPB_BAR                 : image for the bar body           */
/*            5 = cSPB_RIGHT = cSPB_BOTTOM : image for <m_nRight>             */
/*            6 = cSPB_AFTER               : image for after <m_nRight>       */
/*            7 = cSPB_BACKGROUND          : image for the bar background     */
/*            8 = cSPB_END                 : image for the end                */
/*            9 = cSPB_EnumElements        : current number of elements       */
/* Example : None                                                             */
/******************************************************************************/
typedef enum eSkinProgressBitmap
{
  cSPB_START = 0,
  cSPB_BEFORE,
  cSPB_LEFT,
  cSPB_CENTER,
  cSPB_BAR,
  cSPB_RIGHT,
  cSPB_AFTER,
  cSPB_BACKGROUND,
  cSPB_END,
  cSPB_EnumElements,
  cSPB_TOP    = cSPB_LEFT,
  cSPB_BOTTOM = cSPB_RIGHT,
};

/*** eProgressSkinText ********************************************************/
/* Purpose : TRUE condition flag                                              */
/* Unit    : None                                                             */
/* Range   : enum LIST                                                        */
/* List    :  0 = cSPT_NONE         : no text information                     */
/*            1 = cSPT_PERCENT      : simple percent completion               */
/*            2 = cSPT_TIMED        : complete timed completion               */
/*            3 = cSPT_AUTOSIZE     : switch between cSPT_PERCENT and         */
/*                                    cSPT_TIMED according to the remaining   */
/*                                    place available                         */
/*            4 = cSPT_EnumElements : current number of elements              */
/* Example : None                                                             */
/******************************************************************************/
typedef enum eProgressSkinText
{
  cSPT_NONE = 0,
  cSPT_PERCENT,
  cSPT_TIMED,
  cSPT_AUTOSIZE,
  cSPT_EnumElements
};

/*** dCSP_DIALOG_PROGRESS *****************************************************/
/* Purpose : Activate the usage of CWnd object as anchor for the progress bar */
/* Unit    : None                                                             */
/* Range   : None                                                             */
/* List    : None                                                             */
/* Example : Lately implemented, but when activated, allows the use of CWnd   */
/*           objects to put the progress bar everywhere you want, in dialog   */
/*           box for instance...                                              */
/******************************************************************************/
#define dCSP_DIALOG_PROGRESS

/*** dCSP_TIMED_REDRAW ********************************************************/
/* Purpose : Activate the redraw on timer                                     */
/* Unit    : None                                                             */
/* Range   : None                                                             */
/* List    : None                                                             */
/* Example : I implemented this to reduce to calcultation time when activated */
/*           by forcing the bar to redraw/refresh ONLY 50 times a second.     */
/******************************************************************************/
//#define dCSP_TIMED_REDRAW

/*** dCSP_VERTICAL_BAR ********************************************************/
/* Purpose : Activate the vertical bar possibilities                          */
/* Unit    : None                                                             */
/* Range   : None                                                             */
/* List    : None                                                             */
/* Example : None                                                             */
/******************************************************************************/
#define dCSP_VERTICAL_BAR

/*** dCSP_SLIDERBAR_METHOD ****************************************************/
/* Purpose : Activate the full slider bar calculation and reverse display     */
/* Unit    : None                                                             */
/* Range   : None                                                             */
/* List    : None                                                             */
/* Example : None                                                             */
/******************************************************************************/
#define dCSP_SLIDERBAR_METHOD

// SPECIFICS CONDITIONAL COMPILATION DEFINES - ONLY FOR SPECIFIC USAGES ////////

/*** dCSP_RESOURCE_BITMAP *****************************************************/
/* Purpose : Activate the use of the default resource bitmap, instead of the  */
/*           AQUA_BITMAP array                                                */
/* Unit    : None                                                             */
/* Range   : None                                                             */
/* List    : None                                                             */
/* Example : None                                                             */
/******************************************************************************/
//#define dCSP_RESOURCE_BITMAP

/*** dCSP_CREATE_BITMAP_FILE **************************************************/
/* Purpose : Create the BITMAP file in 'SetBitmap', to change the defaut      */
/*           AQUA_BITMAP array                                                */
/* Unit    : None                                                             */
/* Range   : None                                                             */
/* List    : None                                                             */
/* Example : Just activate this, then launch the progress bar WITH A PROVIDED */
/*           bitmap (useless to use the default one, otherwise you'll just    */
/*           get a copy of it in the current video mode) and a '.cpp' file is */
/*           created at the root of drive C: ! Just replace the               */
/*           aucAQUA_BITMAP array and the sbmAQUA_BITMAP structure at the     */
/*           beginning of the 'SkinProgress.cpp' file, desactivate this       */
/*           define and everything should works fine once recompilated...     */
/******************************************************************************/
//#define dCSP_CREATE_BITMAP_FILE

/*** dCSP_DISPLAY_STRETCH *****************************************************/
/* Purpose : Display <m_pStretchBmp> content instead of the progress bar,     */
/*           used to snap shot for documentation upon vertical bar            */
/*           segmentation                                                     */
/* Unit    : None                                                             */
/* Range   : None                                                             */
/* List    : None                                                             */
/* Example : None                                                             */
/* WARNING : Force VERTICAL_BAR calculation if used with dCSP_VERTICAL_BAR    */
/******************************************************************************/
//#define dCSP_DISPLAY_STRETCH

/////////////////////////////////////////////////////////////////////////////
// CSkinProgress window

class CSkinProgress : public CStatic
{
  public: // --- PUBLIC -----------------------------------------------------
    // Construction

// *** CONSTRUCTORS ***

    // Default constructor
	  CSkinProgress
    ();

    // Default constructor with parameters
	  CSkinProgress
    (
      LPCTSTR  i_poStrMessage,
      int      i_nUpper       = 100,
      int      i_nProgress    = cSPT_PERCENT,
      int      i_nPane        = 0,
      int      i_nSize        = 200,
      CBitmap* i_poBitmap     = NULL
#ifdef dCSP_SLIDERBAR_METHOD
     ,BOOL     i_bReverse     = false
#endif // dCSP_SLIDERBAR_METHOD
    );

#ifdef dCSP_DIALOG_PROGRESS
    // Default constructor with parameters
	  CSkinProgress
    (
      CWnd*    i_poWndProgress,
      int      i_nUpper       = 100, 
      CBitmap* i_poBitmap     = NULL,
#ifdef dCSP_SLIDERBAR_METHOD
      BOOL     i_bReverse     = false,
#endif // dCSP_SLIDERBAR_METHOD
      CWnd*    i_poWndMessage = NULL,
      LPCTSTR  i_poStrMessage = NULL,
      int      i_nProgress    = cSPT_NONE
    );
#endif // dCSP_DIALOG_PROGRESS

// *** DESTRUCTOR ***

	  virtual ~CSkinProgress();

    // Attributes

    // Operations

// *** BITMAP PROCESS ***

    // Change of progress bar image
    BOOL SetBitmap
    (
      CBitmap* i_poBitmap     = NULL
#ifndef dCSP_TIMED_REDRAW
     ,BOOL     i_bDisplay     = true
#endif // dCSP_TIMED_REDRAW
    );

    // Copy a bitmap
    BOOL CopyBitmap
    (
      CBitmap* o_poBitmap,
      CBitmap* i_poBitmap
    );

    // Convert a bitmap to a specified device context
    BOOL ConvBitmap
    (
      CBitmap* o_poBitmap,
      CBitmap* i_poBitmap,
      CDC*     i_poDC         = NULL
    );

// *** PROGRESS INTERFACE ***

    // Set the new range
	  BOOL SetRange
    (
      int      i_nLower,
      int      i_nUpper,
      int      i_nStep        = 1,
      BOOL     i_bResamble    = false
#ifndef dCSP_TIMED_REDRAW
     ,BOOL     i_bDisplay     = true
#endif // dCSP_TIMED_REDRAW
    );

    // Set <m_nRight> value
	  int SetPos
    (
      int      i_nPos
#ifndef dCSP_TIMED_REDRAW
     ,BOOL     i_bDisplay     = true
#endif // dCSP_TIMED_REDRAW
    );

    // Forward of <i_nOffset> value
	  int OffsetPos
    (
      int      i_nOffset
#ifndef dCSP_TIMED_REDRAW
     ,BOOL     i_bDisplay     = true
#endif // dCSP_TIMED_REDRAW
    );

    // Set <m_nStep> value
	  int SetStep
    (
      int      i_nStep
    );

    // Forward of <m_nStep> value
	  int StepIt
    (
#ifndef dCSP_TIMED_REDRAW
      BOOL     i_bDisplay     = true
#endif // dCSP_TIMED_REDRAW
    );

// *** EXTENDED PROGRESS INTERFACE ***

    // Set size of the progress bar
	  BOOL SetSize
    (
      int      i_nSize
#ifndef dCSP_TIMED_REDRAW
     ,BOOL     i_bDisplay     = true
#endif // dCSP_TIMED_REDRAW
    );

    // Get width or height of the progress bar in pixel, mostly used in CSkinSlider
	  int GetSize
    (
    );

    // Get <m_nRight> value
	  int GetPos
    (
      BOOL     i_bPercent     = false
    );

    // Get <m_nStep> value
	  int GetStep
    (
    );

    // Get <m_nLower> value
	  int GetLower
    (
    );

    // Get <m_nUpper> value
	  int GetUpper
    (
    );

#ifdef dCSP_SLIDERBAR_METHOD
    // Set <m_nLeft> value
	  int SetStart
    (
      int      i_nStart
#ifndef dCSP_TIMED_REDRAW
     ,BOOL     i_bDisplay     = true
#endif // dCSP_TIMED_REDRAW
    );

    // Get <m_nLeft> value
	  int GetStart
    (
      BOOL     i_bPercent     = false
    );
#endif // dCSP_SLIDERBAR_METHOD

    // Restart the progress bar
    void Reset
    (
#ifndef dCSP_TIMED_REDRAW
      BOOL     i_bDisplay     = true
#endif // dCSP_TIMED_REDRAW
    );

// *** TEXT INTERFACE ***

    // Set the new text
	  BOOL SetText 
    (
      LPCTSTR  i_poStrMessage
#ifndef dCSP_TIMED_REDRAW
     ,BOOL     i_bDisplay     = true
#endif // dCSP_TIMED_REDRAW
    );

    // Set progress text
	  BOOL SetProgress
    (
      int      i_nProgress
#ifndef dCSP_TIMED_REDRAW
     ,BOOL     i_bDisplay     = true
#endif // dCSP_TIMED_REDRAW
    );

    // Get <m_nProgressText> value
	  int GetProgress
    (
    );

// *** UPDATE PROCESS ***

    // Recalc the layout of the panes and refresh them, must be used in [OnSizing(...)] of the parent function
    BOOL RefreshPanes
    (
    );

    // Overrides
	    // ClassWizard generated virtual function overrides
	    //{{AFX_VIRTUAL(CSkinProgress)
	    //}}AFX_VIRTUAL

    // Implementation

  protected: // --- PROTECTED -----------------------------------------------
    // Attributes

#ifdef dCSP_VERTICAL_BAR
    BOOL       m_bVertical;          // true if vertical *NEVER USE IN CSkinProgress for Status Bar*
#endif // dCSP_VERTICAL_BAR
    int        m_nSize;              // Percentage size of control (if <0, autosize with the text if in pane 0)
    int        m_nPane;              // ID of status bar pane progress bar is to appear in

    CString    m_oStrMessage;        // Message to display in pane 0
    CString    m_oStrPrevMessage;    // Message to display in pane 0
    CString    m_oStrPrevText;       // Previous text in pane m_nPane

    int        m_nProgressText;      // Settings of the Progress text

    int        m_nLower;             // Min value
    int        m_nUpper;             // Max value
    int        m_nStep;              // Step increment

#ifdef dCSP_SLIDERBAR_METHOD
    int        m_nPrevLeftAff;       // For 'OnPaint'
    int        m_nLeftAff;           // For 'OnPaint'
    int        m_nPrevLeft;          // Previous position (m_nLower <= m_nPrevLeft <= m_nUpper)
    int        m_nLeft;              // Current position  (m_nLower <= m_nLeft <= m_nUpper)
#endif // dCSP_SLIDERBAR_METHOD

    int        m_nPrevRightAff;      // For 'OnPaint'
    int        m_nRightAff;          // For 'OnPaint'
    int        m_nPrevRight;         // Previous position (m_nLower <= m_nPrevRight <= m_nUpper)
    int        m_nRight;             // Current position  (m_nLower <= m_nRight <= m_nUpper)

    int        m_nPrevEndAff;        // For 'OnPaint'
    int        m_nEndAff;            // For 'OnPaint'

#ifdef dCSP_SLIDERBAR_METHOD
    BOOL       m_bReverse;           // Reverse display, start from the end to the beginning of the progress bar
#endif // dCSP_SLIDERBAR_METHOD

    int        m_nBmpWidth;          // Width of each m_BarImgLst element
    int        m_nBmpHeight;         // Height of each m_BarImgLst element

    CRect      m_oRectPane;          // Position  of the progress bar used in [RefreshPanes()]
    CRect      m_oRectPaint;         // Dimension of the progress bar used in [OnPaint()]

    CBitmap*   m_poBaseBmp;          // The base bitmap
    CBitmap*   m_poCompatibleBmp;    // The client DC compatible base bitmap
    CBitmap*   m_poStretchBmp  ;     // The stretched picture to adapt it to the bar size
    CImageList m_oBarImgLst;         // The ImageList that contains all the progress bar picture elements
    CBitmap*   m_poProgressBmp;      // The progress bar, created, modified and displayed in [OnPaint()]

#ifdef dCSP_DIALOG_PROGRESS
    CWnd*      m_poWndProgress;      // The base CWnd used to create the progress bar
    CWnd*      m_poWndMessage;       // The base CWnd used to create the text pane
#endif // dCSP_DIALOG_PROGRESS

    SYSTEMTIME m_sStartTimeSystem;   // Creation time of the SkinProgress
    LONGLONG   m_nStartTimeLongLong; // Same for 'GetTimed'

    // Operations

// *** CLEANER ***

    // Deletion of the progress bar, restoration of the context
	  void Clear
    (
    );

// *** SYSTEM INTERFACE ***

    // Get the window's status bar handler
    CStatusBar* GetStatusBar
    (
    );

    // Get the target CRect of the progress bar
    BOOL GetTargetRect
    (
      CRect* o_poProgressRect
    );

// *** INITIALIZATORS ***

    // I have put here 'Create...', to avoid to call them twice on an existing CSkinProgress !
    BOOL CreateCommon
    (
      LPCTSTR  i_poStrMessage,
      int      i_nUpper        = 100,
      int      i_nProgress     = cSPT_PERCENT,
      CBitmap* i_poBitmap      = NULL
#ifdef dCSP_SLIDERBAR_METHOD
     ,BOOL     i_bReverse      = false
#endif // dCSP_SLIDERBAR_METHOD
    );

    // Specific Create for Status Bar
	  BOOL ProgressInStatusBar
    (
      LPCTSTR  i_poStrMessage,
      int      i_nUpper        = 100,
      int      i_nProgress     = cSPT_PERCENT,
      int      i_nPane         = 0,
      int      i_nSize         = 200,
      CBitmap* i_poBitmap      = NULL
#ifdef dCSP_SLIDERBAR_METHOD
     ,BOOL     i_bReverse      = false
#endif // dCSP_SLIDERBAR_METHOD
    );

#ifdef dCSP_DIALOG_PROGRESS
    // Specific Create for Dialog
	  BOOL ProgressInDialog
    (
      CWnd*    i_poWndProgress,
      int      i_nUpper        = 100,
      CBitmap* i_poBitmap      = NULL,
#ifdef dCSP_SLIDERBAR_METHOD
      BOOL     i_bReverse      = false,
#endif // dCSP_SLIDERBAR_METHOD
      CWnd*    i_poWndMessage  = NULL,
      LPCTSTR  i_poStrMessage  = NULL,
      int      i_nProgress     = cSPT_NONE
    );
#endif // dCSP_DIALOG_PROGRESS

// *** DATA PROCESS ***

    // Calculation of the '...' text that fits in the (i_nMaxWidth + i_nAddWidth) place
    int CompactText
    (
      CString* io_pString,
      CDC*     i_pDC, 
      int      i_nMaxWidth, 
      int      i_nAddWidth     = 0
    );

    // Get the complete timed message (64 bits calculation inside)
    BOOL GetTimed
    (
      CString* o_poTimed
    );

// *** UPDATE PROCESS ***

    // Update of the progress bar values
    BOOL UpdateProgress
    (
      CRect*   o_poRectPaint   = NULL
    );

// *** WINDOWS MAPPED PROCESSING ***

	  // Generated message map functions
	    //{{AFX_MSG(CSkinProgress)
	    afx_msg BOOL OnEraseBkgnd(CDC* i_pDC);
	    afx_msg void OnPaint();
	    afx_msg void OnSizing(UINT fwSide, LPRECT pRect);
	    afx_msg void OnSize(UINT nType, int cx, int cy);
	    afx_msg void OnTimer(UINT nIDEvent);
	  //}}AFX_MSG

	  DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_SKINPROGRESS_H__1DF43017_611B_44BD_822A_FAA0E01B2257__INCLUDED_)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The zlib/libpng License


Written By
Software Developer
France France
KOCH David, 41 years old
Coder (embedded, C/C++, ASM, Erlang)

Comments and Discussions