home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: WPS_PM
/
WPS_PM.zip
/
xfld085s.zip
/
helpers
/
progbars.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-23
|
12KB
|
329 lines
/*
*@@sourcefile progbars.c:
* contains progress bar helper functions.
*
* These can turn any static control into a working progress bar.
* See pbarProgressBarFromStatic for how to use this.
*
* Function prefixes (new with V0.81):
* -- pbar* progress bar helper functions
*
*@@include #include <os2.h>
*@@include #include "progbars.h"
*/
/*
* Copyright (C) 1997-99 Ulrich Möller.
* This file is part of the XFolder source package.
* XFolder is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, in version 2 as it comes in the
* "COPYING" file of the XFolder main distribution.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
// #define INCL_DOSDEVIOCTL
// #define INCL_DOS
// #define INCL_DOSERRORS
#define INCL_WIN
#define INCL_GPI
#include <os2.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "gpih.h"
#include "progbars.h"
/*
* PaintProgress:
* this does the actual painting. It is called
* both by WM_PAINT and by WM_UPDATEPROGRESSBAR
* with different HPS's then.
*/
VOID PaintProgress(PPROGRESSBARDATA pData, HWND hwndBar, HPS hps)
{
POINTL ptl1, ptlText, aptlText[TXTBOX_COUNT];
RECTL rcl, rcl2;
CHAR szPercent[10] = "";
// switch to RGB mode
GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL);
if (pData->ulPaintX <= pData->ulOldPaintX)
{
// draw frame and background only if this is either
// a "real" WM_PAINT (i.e., the window was overlapped
// and needs repainting; then ulPaintX == ulOldPaintX)
// or if ulNow has _de_creased
GpiSetColor(hps, WinQuerySysColor(HWND_DESKTOP, SYSCLR_BUTTONDARK, 0));
ptl1.x = 0;
ptl1.y = 0;
GpiMove(hps, &ptl1);
ptl1.y = (pData->rtlBar.yTop);
GpiLine(hps, &ptl1);
ptl1.x = (pData->rtlBar.xRight);
GpiLine(hps, &ptl1);
GpiSetColor(hps, WinQuerySysColor(HWND_DESKTOP, SYSCLR_BUTTONLIGHT, 0));
ptl1.y = 0;
GpiLine(hps, &ptl1);
ptl1.x = 0;
GpiLine(hps, &ptl1);
pData->rtlBar.xLeft = 1;
pData->rtlBar.yBottom = 1;
WinFillRect(hps, &(pData->rtlBar),
WinQuerySysColor(HWND_DESKTOP, SYSCLR_SCROLLBAR, 0));
}
// draw percentage?
if (pData->ulAttr & PBA_PERCENTFLAGS)
{
// make string
sprintf(szPercent, "%d %%", ((100 * pData->ulNow) / pData->ulMax) );
// calculate string space
GpiQueryTextBox(hps, strlen(szPercent), szPercent,
TXTBOX_COUNT, (PPOINTL)&aptlText);
// calculate coordinates
ptlText.x = pData->rtlBar.xLeft +
( ( (pData->rtlBar.xRight-pData->rtlBar.xLeft)
- (aptlText[TXTBOX_BOTTOMRIGHT].x-aptlText[TXTBOX_BOTTOMLEFT].x)
)
/ 2);
ptlText.y = 3 + pData->rtlBar.yBottom +
( ( (pData->rtlBar.yTop-pData->rtlBar.yBottom)
- (aptlText[TXTBOX_TOPLEFT].y-aptlText[TXTBOX_BOTTOMLEFT].y)
)
/ 2);
// do we need to repaint the background under the percentage?
if ( ( (ptlText.x
+ ( aptlText[TXTBOX_BOTTOMRIGHT].x
- aptlText[TXTBOX_BOTTOMLEFT].x)
)
> pData->ulPaintX)
&& (pData->ulPaintX > pData->ulOldPaintX)
)
{
// if we haven't drawn the background already,
// we'll need to do it now for the percentage area
rcl.xLeft = ptlText.x;
rcl.xRight = ptlText.x + (aptlText[TXTBOX_BOTTOMRIGHT].x-aptlText[TXTBOX_BOTTOMLEFT].x);
rcl.yBottom = ptlText.y;
rcl.yTop = ptlText.y + (aptlText[TXTBOX_TOPLEFT].y-aptlText[TXTBOX_BOTTOMLEFT].y);
WinFillRect(hps, &rcl,
WinQuerySysColor(HWND_DESKTOP, SYSCLR_SCROLLBAR, 0));
}
}
// now draw the actual progress
rcl2.xLeft = pData->rtlBar.xLeft;
rcl2.xRight = (pData->ulPaintX > (rcl2.xLeft + 3))
? pData->ulPaintX
: rcl2.xLeft + ((pData->ulAttr & PBA_BUTTONSTYLE)
? 3 : 1);
rcl2.yBottom = pData->rtlBar.yBottom;
rcl2.yTop = pData->rtlBar.yTop-1;
if (pData->ulAttr & PBA_BUTTONSTYLE)
{
RECTL rcl3 = rcl2;
// draw "raised" inner rect
rcl3.xLeft = rcl2.xLeft;
rcl3.yBottom = rcl2.yBottom;
rcl3.yTop = rcl2.yTop+1;
rcl3.xRight = rcl2.xRight+1;
gpihDraw3DFrame(hps, &rcl3, 2, TRUE);
// WinInflateRect(WinQueryAnchorBlock(hwndBar), &rcl2, -2, -2);
rcl2.xLeft += 2;
rcl2.yBottom += 2;
rcl2.yTop -= 2;
rcl2.xRight -= 2;
}
if (rcl2.xRight > rcl2.xLeft) {
GpiSetColor(hps, WinQuerySysColor(HWND_DESKTOP,
// SYSCLR_HILITEBACKGROUND,
SYSCLR_BUTTONMIDDLE,
0));
ptl1.x = rcl2.xLeft;
ptl1.y = rcl2.yBottom;
GpiMove(hps, &ptl1);
ptl1.x = rcl2.xRight;
ptl1.y = rcl2.yTop;
GpiBox(hps, DRO_FILL | DRO_OUTLINE,
&ptl1,
0,
0);
}
// now print the percentage
if (pData->ulAttr & PBA_PERCENTFLAGS)
{
GpiMove(hps, &ptlText);
GpiSetColor(hps, WinQuerySysColor(HWND_DESKTOP,
// SYSCLR_HILITEFOREGROUND,
SYSCLR_BUTTONDEFAULT,
0));
GpiCharString(hps, strlen(szPercent), szPercent);
}
// store current X position for next time
pData->ulOldPaintX = pData->ulPaintX;
}
/*
*@@ fnwpProgressBar:
* this is the window procedure for the progress bar control,
* which is a static rectangle control subclassed by
* pbarProgressBarFromStatic.
*
* We need to capture WM_PAINT to draw the progress bar according
* to the current progress, and we also update the static text field
* (percentage) next to it.
*
* This also evaluates the WM_UPDATEPROGRESSBAR message.
*/
MRESULT EXPENTRY fnwpProgressBar(HWND hwndBar, ULONG msg, MPARAM mp1, MPARAM mp2)
{
HPS hps;
PPROGRESSBARDATA pData = (PPROGRESSBARDATA)WinQueryWindowULong(hwndBar, QWL_USER);
PFNWP OldStaticProc = NULL;
MRESULT mrc = NULL;
if (pData) {
OldStaticProc = pData->OldStaticProc;
switch(msg) {
/*
* WM_UPDATEPROGRESSBAR:
* post or send this message to the progress
* bar to have a new progress displayed.
* Parameters:
* ULONG mp1 current value
* ULONG mp2 max value
* Example: mp1 = 100, mp2 = 300 will result
* in a progress of 33%.
*/
case WM_UPDATEPROGRESSBAR: {
if ( (pData->ulNow != (ULONG)mp1)
|| (pData->ulMax != (ULONG)mp2)
)
{
pData->ulNow = (ULONG)mp1;
pData->ulMax = (ULONG)mp2;
}
else
// value not changed: do nothing
break;
// check validity
if (pData->ulNow > pData->ulMax)
pData->ulNow = pData->ulMax;
// avoid division by zero
if (pData->ulMax == 0) {
pData->ulMax = 1;
pData->ulNow = 0;
// paint 0% then
}
// calculate new X position of the progress
pData->ulPaintX =
(ULONG)(
( (ULONG)(pData->rtlBar.xRight-pData->rtlBar.xLeft)
* (ULONG)(pData->ulNow)
)
/ (ULONG)pData->ulMax
);
if (pData->ulPaintX != pData->ulOldPaintX) {
// X position changed: redraw
// WinInvalidateRect(hwndBar, NULL, FALSE);
HPS hps = WinGetPS(hwndBar);
PaintProgress(pData, hwndBar, hps);
WinReleasePS(hps);
}
break; }
case WM_PAINT: {
RECTL rcl;
hps = WinBeginPaint(hwndBar, NULLHANDLE, &rcl);
PaintProgress(pData, hwndBar, hps);
WinEndPaint(hps);
break; }
default:
mrc = OldStaticProc(hwndBar, msg, mp1, mp2);
}
}
return (mrc);
}
/*
*@@ pbarProgressBarFromStatic:
* this function turns an existing static rectangle control
* into a progress bar by subclassing its window procedure
* with fnwpProgressBar.
* This way you can easily create a progress bar in the Dialog
* Editor; after loading the dlg template, simply call this
* function with the hwnd of the static control to make it a
* status bar.
*
* In order to _update_ the progress bar, simply post or send
* WM_UPDATEPROGRESSBAR to the static (= progress bar) window;
* this message is equal to WM_USER and needs the following
* parameters:
* -- mp1 ULONG ulNow: the current progress
* -- mp2 ULONG ulMax: the maximally possible progress
* (= 100%)
*
* The progress bar automatically calculates the current progress
* display. For example, if ulMax == 8192 and ulNow == 4096,
* a progress of 50% will be shown. It is possible to change
* ulMax after the progress bar has started display. If ulMax
* is 0, a progress of 0% will be shown (to avoid division
* by zero traps).
*
* ulAttr accepts of the following:
* -- PBA_NOPERCENTAGE: do not display percentage
* -- PBA_ALIGNLEFT: left-align percentage
* -- PBA_ALIGNRIGHT: right-align percentage
* -- PBA_ALIGNCENTER: center percentage
* -- PBA_BUTTONLOOK: no "flat", but button-like look
*/
BOOL pbarProgressBarFromStatic(HWND hwndStatic, ULONG ulAttr)
{
PFNWP OldStaticProc = WinSubclassWindow(hwndStatic, fnwpProgressBar);
if (OldStaticProc) {
PPROGRESSBARDATA pData = (PPROGRESSBARDATA)malloc(sizeof(PROGRESSBARDATA));
pData->ulMax = 1;
pData->ulNow = 0;
pData->ulPaintX = 0;
pData->ulAttr = ulAttr;
pData->OldStaticProc = OldStaticProc;
WinQueryWindowRect(hwndStatic, &(pData->rtlBar));
(pData->rtlBar.xRight)--;
(pData->rtlBar.yTop)--;
WinSetWindowULong(hwndStatic, QWL_USER, (ULONG)pData);
return (TRUE);
}
else return (FALSE);
}