Click here to Skip to main content
15,881,248 members
Articles / Desktop Programming / MFC
Article

Status Progress Feedback

Rate me:
Please Sign up or sign in to vote.
4.68/5 (10 votes)
6 Jul 20047 min read 69.3K   2.7K   46   3
A status control that can provide feedback to a user on the progress of one or many operations

Image 1

Image 2

Description

There are often times when an application needs to perform a lengthy operation-or series of operations; if the operation takes long enough, the programmer will likely want to display the status of the operation as-well-as provide the user with a means of discontinuing the operation. This submission contains a number of MFC classes to provide the programmer with a means by which the status of an operation can be feedback-to and cancelled-from a waiting user.

Design

We will use two primary classes to track the status of an operation. One class will be the actual status control. The status control class will be responsible for displaying the current status to the user. The status control class will allow a user to cancel any operation(s) that are updating the status control. The second class will be the status progress class. The status progress class will be the means by which an operation will communicate with the status control. The status progress class will be configured with a number of steps to perform and each step can, in turn, be broken-up into a number of substeps. When a step is completed the status progress object should increment its current step and check for a cancellation request.

The status control object will initially need to be divided into an initial number of operations or steps. This initial division of the status control's progressbar will be stored in a status progress object. As the steps are performed, the status progress object should increment its current step and check for a cancellation request. If a step has any substeps, the status progress object handling the step can divide its current step into a number of substeps.

Each status progress object will keep track of its current step and its piece of the status control's progressbar, or range. A progress object's range will be set by its parent progress object or the status control-depending on whether it is an initial step or a substep. When a progress object's step is incremented, it will also update the status control's progressbar.

We will make the status control appear to be running independent of the operations that are updating it by processing all the application messages each time the progressbar's position is updated.

Classes

NOTE: The following classes are contained in statusctrl.cpp and statusctrl.h, and they will require the referencecount.h and smartptr.h header files.

CStatusControl

CStatusControl is the primary class that displays an operation's status to the user and accepts cancellation requests. You can create the control using one of the create methods provided in the class. Once created, use configuration methods-provided in the class-for custom configuration of the control. Once configured and displayed, use the progress related methods to break the status control's progressbar into an initial number of steps-each of which can be further subdivided into substeps using the CStatusProgress class. Once the status control is setup and providing feedback to the user, use the status methods to query the cancellation status or manually cancel the operation.

Creation Methods:

  • BOOL CreateInPlaceOf(CWnd* pWnd, DWORD dwStyle = NULL) This method creates the control, and places it in the position of the window indicated by the pWnd argument
  • BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL) This method creates the control using the CWnd::Create method.
  • BOOL CreateEx(DWORD dwExStyle, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, LPVOID lpParam = NULL) This method creates the control using the CWnd::CreateEx method.

Configuration Methods:

  • void SetProgressCtrlText(LPCSTR lpszText) This method allows the user to configure the text that should appear in the progressbar control
  • void SetProgressCtrlStyle(DWORD dwStyle); This method allows the user to configure the style that should be used in the progressbar control
    • SP_USE_PBS_STYLE - Use default CProgressCtrl painting routine
    • SP_BLOCK_STYLE - Use the class's paint routine to display status blocks
    • SP_SMOOTH_STYLE - Use the class's paint routing to display smooth status
    • SP_SHOWPERCENT - ORed with SP_SMOOTH_STYLE or SP_BLOCK_STYLE to indicate the percent completed showed be displayed
    • SP_SHOWMSG - ORed with SP_SMOOTH_STYLE or SP_BLOCK_STYLE to indicate the user will provide text to be displayed
  • void SetProgressCtrlNumBlocks(UINT nNumBlocks); This method allows the user to configure the number of blocks that should be displayed in the progressbar control
  • BOOL MoveProgressCtrl(RECT& rect) This method allows the user to resize/reposition the progressbar control
  • BOOL MoveCancelButton(RECT& rect); This method allows the user to resize/reposition the cancel button

Progress Methods:

  • void SetSteps(int nNumSteps, CStatusProgress& retSubProgress) This method is used to break the initial status control's progressbar into a number of steps. The retSubProgress argument is used to return the configured status control's step information. The retSubProgress can be used to further subdivide the current step into a number of substeps.
  • void SetProgressPos(int nPos, BOOL bDispatchAllPendingMessages = TRUE); This method is used to set the progressbar position. You should never need to call this, as the CStatusProgress object's call it when their current step is incremented.

Status Methods:

  • void Reset(void) This method is used to reset the cancel status and the progressbar position
  • void Cancel(void) This method is used for manual cancellations from outside of the control
  • BOOL IsCancelled() This method is used to query the cancellation status

CStatusProgress

CStatusProgress is the means by which a CStatusControl can have its status updated and queried for a cancellation request. After the initial CStatusControl object is created, it is initially broken-up into a number of steps; these steps are returned in a CStatusProgress object. A CStatusProgress object can be broken-up into smaller steps, and these steps are returned in another CStatusProgress object.

  • void Init(void) Initializes the object
  • void Attach(CStatusControlPtr pStatusCtrl)
    Attaches the CStatusControl to the object
  • void Cancel(void)
    Cancels the status control
  • BOOL IsCancelled(void) Queries for a status control cancellation
  • void SetSteps(int nNumSteps, CStatusProgress& retSubProgress)
    Breaks the object's current step into a number of substeps
  • void StepIt(BOOL bDispatchAllPendingMessages = TRUE)
    Increments the objects current step
  • void SetText(LPCSTR lpszText)
    Sets the text that should appear in the status control's progressbar

CStatusControlPtr

CStatusControlPtr is a smartpointer class that wraps a CStatusControl object. Its is used in the CStatusProgress class to ensure that the CStatusControl pointed to by the class is not destroyed until all CStatusProgess objects using the control are destroyed.

CStatusProgressControl

CStatusProgressControl is a subclass of the CProgressCtrl MFC class. It was written in order to provide an option for displaying the percent completed in the progressbar. It also provides the ability to specify how many blocks should appear if the progressbar is configured to display blocks. The class adds three methods to the CProgressCtrl class.

  • void SetStyle(DWORD dwStyle) This method allows the user to specify how the control should be painted.
    • SP_USE_PBS_STYLE - Use default CProgressCtrl painting routine
    • SP_BLOCK_STYLE - Use the class's paint routine to display status blocks
    • SP_SMOOTH_STYLE - Use the class's paint routing to display smooth status
    • SP_SHOWPERCENT - Used with SP_SMOOTH_STYLE or SP_BLOCK_STYLE to indicate the percent completed showed be displayed
    • SP_SHOWMSG - Used with SP_SMOOTH_STYLE or SP_BLOCK_STYLE to indicate the user will provide text to be displayed
  • void SetNumBlocks(UINT nNumBlocks) This method allows the user to specify the number of blocks that should be displayed when the style is SP_BLOCK_STYLE
  • void SetMessage(LPCSTR lpszMsg) This method allows the user to specify the text to display in the progressbar

CStatusDlg

CStatusDlg is a class that provides a modeless dialog container for a CStatusControl. It is provided as a means to place the CStatusControl into a separate window.

  • void DoModeless(CWnd* pParent = NULL, LPCSTR lpszTitle = "", DWORD dwProgressStyle = SP_USE_PBS_STYLE, UINT nNumBlocks = 0, LPCSTR lpszText = "") This method creates a modeless dialog box containing a status control.
  • CStatusControlPtr GetStatusControlPtr(); This method returns the status control contained in the dialog.
  • void SetSteps(int nNumSteps, CStatusProgress& retSubProgress); This method simply forwards the request to the contained status control.
  • void Reset(void); This method simply forwards the request to the contained status control.
  • void Cancel(void); This method simply forwards the request to the contained status control.
  • BOOL IsCancelled();
    This method simply forwards the request to the contained status control.

Example of usage

...
...
int nNumberOfSteps = 100;

// Create and display the status control...
CStatusControlPtr pStatusCtrl = new CStatusControl;
pStatusCtrl->Create("STATUS", WS_CHILD | WS_VISIBLE,
    CRect(10, 10, 210, 32), this, NULL, NULL);

// Allocate the initial steps from the status control...
CStatusProgress progress;
pStatusCtrl->SetSteps(nNumberOfSteps, progress);

// Perform the operations...
for (int nStep = 0; nStep < nNumberOfSteps; nStep++)
{
    // Perform the current operation...
    Sleep(100);

    // Update the current step...
    progress.StepIt();
    // Check for cancellation...
    // If we're received a cancellation request...
    if (progress.IsCancelled())
        // Discontinue operation...
        break;
}
...
...

See the sourcecode provided for more examples of how the status control can be used.

Caveats

If a long operation is not broken into small enough steps, a cancellation might not get processed within an acceptable time limit. The status progress is recursively broken-up into steps to represent the division of operations, and hence does not reflect the actual time of each operation.

Contact Information

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralLooks good Pin
General_Disturbance12-Nov-06 18:36
General_Disturbance12-Nov-06 18:36 
GeneralGreat class Pin
FredParcells16-Nov-04 6:00
FredParcells16-Nov-04 6:00 
QuestionMore user friendly? Pin
AndrewSmirnov13-Jul-04 2:39
AndrewSmirnov13-Jul-04 2:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.