Progress Bar Control

The progress bar is generally used to prompt the progress of a task for the user, and is frequently used for tasks such as copying file, installing software. Calling CreateWindow function with CTRL_PROGRESSBAR as the control class name can create a progress bar. Figure 1 is the typical running effect of a progress bar.

alt

Figure 1 Progress bar control

Styles of Progress Bar

Progress bar has only the following two styles available:

  • PBS_NOTIFY: The progress bar control with this style can generate notification messages.。

  • PBS_VERTICAL: Display the progress bar vertically, as shown in Figure 2.

alt

Figure 2 Vertical progress bar control

The combination of styles commonly used by a progress bar controls is:

WS_CHILD | WS_VISIBLE | PBS_NOTIFY

Messages of Progress Bar

Setting Range of Progress Bar

The range of a progress bar is 0 to 100 by default, and an application can set its own progress bar range by calling PBM_SETRANGE message:

SendMessage (hwndEdit, PBM_SETRANGE, min, max) ;

PROMPT The range of a progress bar can be set to be a negative value.

Setting Step Value of Progress Bar

We can set the step value for a progress bar, and make the progress bar stepping forward when each stage task is complete. The step value is 10 by default, and can be changed by sending PBM_SETSTEP message, as shown in the following:

SendMessage (hwndEdit, PBM_SETSTEP, 5, 0) ;

The above message changes the step value of a progress bar to be 5.

PROMPT The step value of a progress bar can be set to be a negative value.

You should set the position of the progress bar as the max value of its range when the step value is a negative and the progress bar will decrease from its max range to min.

Setting Position of Progress Bar

We can also set the current position of a progress bar optionally with PBM_SETPOS message:

SendMessage (hwndEdit, PBM_SETPOS, 50, 0) ;

The above message sets the current position of a progress bar to be 50.

Setting Offset Based-on Current Position

We can also set the offset of the new position based on the current position to change the progress position:

SendMessage (hwndEdit, PBM_DELTAPOS, 10, 0) ;

The above message will add 10 to the new position based on the current position, i.e., new position is the current position plus 10.

PROMPT The offset of a progress bar can be set to be a negative value.

Advancing Position by One Step

PBM_STEPIT can be sent to advance the current position, and the new position equals the result of the current position plus the step value:

SendMessage (hwndEdit, PBM_STEPIT, 0, 0) ;

NOTE The present progress bar control does not provide any messages for getting the current position, the current step increment, and the current position range.

Notification Codes of Progress Bar

Progress bar with PBS_NOTIFY style may possibly generate the following notification codes:

  • PBN_REACHMAX: Reach the maximum position.

  • PBN_REACHMIN: Reach the minimum position.

Sample Program

List 1 gives an example of using the progress bar control. This program provides two functions. Calling createProgressWin function will create a main window with a progress bar and then return. We can control the progress bar of the main window in our own program, and call destroyProgressWin function to destroy the progress main window after completing the task. The two functions actually come from MiniGUIExt library of MiniGUI. List 1 gives the example of the implementation and the usage of these two functions, and the running effect is as shown in Figure 3. Please refer to progressbar.c of the sample program package mg-samples of this guide for the complete source code.

List 1 Example of using progress bar

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>

#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>

static HWND createProgressWin (HWND hParentWnd, char * title, char * label,
        int id, int range)
{
    HWND hwnd;
    MAINWINCREATE CreateInfo;
    int ww, wh;
    HWND hStatic, hProgBar;

    /* Calculate the window width according to the width of the window client region */
    ww = ClientWidthToWindowWidth (WS_CAPTION | WS_BORDER, 400);
    /* Calculate the window height according to the height of the window client region */
    wh = ClientHeightToWindowHeight (WS_CAPTION | WS_BORDER,
            (range > 0) ? 70 : 35, FALSE);

    /* Create the main window */
    CreateInfo.dwStyle = WS_ABSSCRPOS | WS_CAPTION | WS_BORDER | WS_VISIBLE;
    CreateInfo.dwExStyle = WS_EX_NONE;
    CreateInfo.spCaption = title;
    CreateInfo.hMenu = 0;
    CreateInfo.hCursor = GetSystemCursor(IDC_WAIT);
    CreateInfo.hIcon = 0;
    /* The window procedure of the main window is set to
     * be the default main window procedure
     */
    CreateInfo.MainWindowProc = DefaultMainWinProc;
#ifndef _LITE_VERSION
    CreateInfo.lx = (GetGDCapability (HDC_SCREEN, GDCAP_MAXX) - ww) >> 1;
    CreateInfo.ty = (GetGDCapability (HDC_SCREEN, GDCAP_MAXY) - wh) >> 1;
#else
    CreateInfo.lx = g_rcExcluded.left + (RECTW(g_rcExcluded) - ww) >> 1;
    CreateInfo.ty = g_rcExcluded.top + (RECTH(g_rcExcluded) - wh) >> 1;
#endif
    CreateInfo.rx = CreateInfo.lx + ww;
    CreateInfo.by = CreateInfo.ty + wh;
    CreateInfo.iBkColor = COLOR_lightgray;
    CreateInfo.dwAddData = 0L;
    CreateInfo.hHosting = hParentWnd;

    hwnd = CreateMainWindow (&CreateInfo);
    if (hwnd == HWND_INVALID)
        return hwnd;

    /* Create a static control for prompting in the main window */
    hStatic = CreateWindowEx ("static",
                  label,
                  WS_VISIBLE | SS_SIMPLE,
                  WS_EX_USEPARENTCURSOR,
                  IDC_STATIC,
                  10, 10, 380, 16, hwnd, 0);

    /* Create the progress bar control in the main window */
    if (range > 0) {
        hProgBar = CreateWindowEx ("progressbar",
                  NULL,
                  WS_VISIBLE,
                  WS_EX_USEPARENTCURSOR,
                  id,
                  10, 30, 380, 30, hwnd, 0);
        SendDlgItemMessage (hwnd, id, PBM_SETRANGE, 0, range);
    }
    else
        hProgBar = HWND_INVALID;

    /* Update the controls */
    UpdateWindow (hwnd, TRUE);

    /* Return the handle of the main window */
    return hwnd;
}

static void destroyProgressWin (HWND hwnd)
{
    /* Destroy the controls and the main window  */
    DestroyAllControls (hwnd);
    DestroyMainWindow (hwnd);
    ThrowAwayMessages (hwnd);
    MainWindowThreadCleanup (hwnd);
}

int MiniGUIMain (int argc, const char* argv[])
{
    int i, sum;
    HCURSOR hOldCursor;
    HWND hwnd;

#ifdef _MGRM_PROCESSES
    JoinLayer(NAME_DEF_LAYER , "progressbar" , 0 , 0);
#endif

    /* Set “sandglass” mouse to indicate the system is busy */
    hOldCursor = SetDefaultCursor (GetSystemCursor (IDC_WAIT));

    /* Create the progressbar window, and specify the
     * identifier and range of the progress bar control */
    hwnd = createProgressWin (HWND_DESKTOP, "进度条",
            "正在计算,请稍候...", 100, 2000);

    while (HavePendingMessage (hwnd)) {
         MSG msg;
         GetMessage (&msg, hwnd);
         DispatchMessage (&msg);
    }

    /* Begin the long time calculating progress,and
     * refresh the position of the progressbar when completing
     * the external loop.
     */
    for (i = 0; i < 2000; i++) {
        unsigned long j;

        if (i % 100 == 0) {
            SendDlgItemMessage (hwnd, 100, PBM_SETPOS, i, 0L);
            while (HavePendingMessage (hwnd)) {
                MSG msg;
                GetMessage (&msg, hwnd);
                DispatchMessage (&msg);
            }
        }

        sum = i*5000;
        for (j = 0; j < 500000; j++)
            sum *= j;
        sum += sum;
    }

    /* Destroy the progressbar window */
    destroyProgressWin (hwnd);
    /* Recover the original mouse */
    SetDefaultCursor (hOldCursor);

    return 0;
}

#ifndef _MGRM_PROCESSES
#include <minigui/dti.c>
#endif
alt

Figure 3 Example of progress bar control


<< Menu Button Control | Table of Contents | Track Bar Control >>

Last updated