You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
317 lines
7.7 KiB
317 lines
7.7 KiB
/*****************************************************************************
|
|
*
|
|
* Progress.c
|
|
*
|
|
* Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* Abstract:
|
|
*
|
|
* Our private progress control (because commctrl might be damanged)
|
|
*
|
|
* Contents:
|
|
*
|
|
* Progress_Init
|
|
*
|
|
*****************************************************************************/
|
|
#include "sigverif.h"
|
|
|
|
/***************************************************************************
|
|
*
|
|
* GWL_* for Progress goo.
|
|
*
|
|
***************************************************************************/
|
|
|
|
#define GWL_CUR GWLP_USERDATA
|
|
|
|
/***************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func int | Progress_GetRectPos |
|
|
*
|
|
* Compute the position within the drawing rectangle that
|
|
* corresponds to the current position.
|
|
*
|
|
* This is basically a MulDiv, except that we don't let the
|
|
* bar get all the way to 100% unless it really means it.
|
|
*
|
|
*
|
|
***************************************************************************/
|
|
|
|
int
|
|
Progress_GetRectPos(
|
|
int cx,
|
|
int iCur,
|
|
int iMax
|
|
)
|
|
{
|
|
int iRc;
|
|
|
|
if (iCur != iMax) {
|
|
iRc = MulDiv(cx, iCur, iMax);
|
|
} else {
|
|
iRc = cx;
|
|
}
|
|
|
|
return iRc;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func LRESULT | Progress_OnPaint |
|
|
*
|
|
* Draw the first part in the highlight colors.
|
|
*
|
|
* Draw the second part in the 3dface colors.
|
|
*
|
|
***************************************************************************/
|
|
|
|
void
|
|
Progress_OnPaint(
|
|
HWND hwnd
|
|
)
|
|
{
|
|
HDC hdc;
|
|
PAINTSTRUCT ps;
|
|
HRESULT hr;
|
|
|
|
hdc = BeginPaint(hwnd, &ps);
|
|
if (hdc) {
|
|
UINT taPrev;
|
|
RECT rc;
|
|
int cx;
|
|
COLORREF clrTextPrev, clrBackPrev;
|
|
int iCur, iMax, iPct;
|
|
int ctch;
|
|
HFONT hfPrev;
|
|
TCHAR tsz[256];
|
|
SIZE size;
|
|
|
|
//
|
|
// Set up the DC generically.
|
|
//
|
|
taPrev = SetTextAlign(hdc, TA_CENTER | TA_TOP);
|
|
hfPrev = SelectFont(hdc, GetWindowFont(GetParent(hwnd)));
|
|
|
|
//
|
|
// Set up the colors for the left-hand side.
|
|
//
|
|
clrTextPrev = SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
|
|
clrBackPrev = SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
|
|
|
|
//
|
|
// Now do some math.
|
|
//
|
|
GetClientRect(hwnd, &rc);
|
|
|
|
cx = rc.right;
|
|
|
|
iCur = LOWORD(GetWindowLong(hwnd, GWL_CUR));
|
|
iMax = HIWORD(GetWindowLong(hwnd, GWL_CUR));
|
|
|
|
if (iMax == 0) {
|
|
iMax = 1; /* Avoid divide by zero */
|
|
}
|
|
|
|
if (iCur > 0) {
|
|
|
|
iPct = (iCur * 100) / iMax;
|
|
if (iPct < 1) {
|
|
iPct = 1;
|
|
}
|
|
} else {
|
|
iPct = 0;
|
|
}
|
|
|
|
rc.right = Progress_GetRectPos(cx, iCur, iMax);
|
|
|
|
//
|
|
// Update the percentage text in the progress bar.
|
|
//
|
|
hr = StringCchPrintf(tsz, cA(tsz), TEXT("%d%%"), iPct);
|
|
if (FAILED(hr) && (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) {
|
|
tsz[0] = TEXT('\0');
|
|
}
|
|
|
|
for(ctch=0;tsz[ctch];ctch++);
|
|
|
|
//
|
|
// Draw the left-hand side.
|
|
//
|
|
if (!GetTextExtentPoint32(hdc, tsz, ctch, &size)) {
|
|
|
|
ExtTextOut( hdc, cx/2, 1,
|
|
ETO_CLIPPED | ETO_OPAQUE,
|
|
&rc, tsz, ctch, 0);
|
|
|
|
} else {
|
|
|
|
ExtTextOut( hdc, cx/2, (rc.bottom - rc.top - size.cy + 1) / 2,
|
|
ETO_CLIPPED | ETO_OPAQUE,
|
|
&rc, tsz, ctch, 0);
|
|
}
|
|
|
|
//
|
|
// Now set up for the right-hand side.
|
|
//
|
|
SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
|
|
SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
|
|
|
|
rc.left = rc.right;
|
|
rc.right = cx;
|
|
|
|
//
|
|
// Draw the right-hand side.
|
|
//
|
|
if (!GetTextExtentPoint32(hdc, tsz, ctch, &size)) {
|
|
|
|
ExtTextOut( hdc, cx/2, 1,
|
|
ETO_CLIPPED | ETO_OPAQUE,
|
|
&rc, tsz, ctch, 0);
|
|
|
|
} else {
|
|
|
|
ExtTextOut( hdc, cx/2, (rc.bottom - rc.top - size.cy + 1) / 2,
|
|
ETO_CLIPPED | ETO_OPAQUE,
|
|
&rc, tsz, ctch, 0);
|
|
}
|
|
|
|
SetBkColor(hdc, clrBackPrev);
|
|
SetTextColor(hdc, clrTextPrev);
|
|
SelectFont(hdc, hfPrev);
|
|
SetTextAlign(hdc, taPrev);
|
|
|
|
EndPaint(hwnd, &ps);
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func LRESULT | Progress_OnSetPos |
|
|
*
|
|
* Update the state and invalidate the section that is affected.
|
|
*
|
|
***************************************************************************/
|
|
|
|
void
|
|
Progress_OnSetPos(
|
|
HWND hwnd,
|
|
WPARAM wp
|
|
)
|
|
{
|
|
int iCur, iMax;
|
|
RECT rc;
|
|
LONG lState = GetWindowLong(hwnd, GWL_CUR);
|
|
|
|
|
|
GetClientRect(hwnd, &rc);
|
|
|
|
iCur = LOWORD(GetWindowLong(hwnd, GWL_CUR));
|
|
iMax = HIWORD(GetWindowLong(hwnd, GWL_CUR));
|
|
|
|
if (iMax == 0) {
|
|
iMax = 1; /* Avoid divide by zero */
|
|
}
|
|
|
|
rc.left = Progress_GetRectPos(rc.right, iCur, iMax);
|
|
rc.right = Progress_GetRectPos(rc.right, (int)wp, iMax);
|
|
|
|
InvalidateRect(hwnd, 0, 0);
|
|
|
|
SetWindowLong(hwnd, GWL_CUR, MAKELONG(wp,HIWORD(lState)));
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func LRESULT | Progress_WndProc |
|
|
*
|
|
* There really isn't much to do.
|
|
*
|
|
* The string is our window text (which Windows manages for us).
|
|
*
|
|
* The progress bar itself is kept in the high/low words of
|
|
* our GWL_USERDATA.
|
|
*
|
|
* HIWORD(GetWindowLong(GWL_USERDATA)) = maximum
|
|
* LOWORD(GetWindowLong(GWL_USERDATA)) = current value
|
|
*
|
|
***************************************************************************/
|
|
|
|
LRESULT CALLBACK
|
|
Progress_WndProc(
|
|
HWND hwnd,
|
|
UINT wm,
|
|
WPARAM wp,
|
|
LPARAM lp
|
|
)
|
|
{
|
|
switch (wm) {
|
|
|
|
case WM_PAINT:
|
|
Progress_OnPaint(hwnd);
|
|
return 0;
|
|
|
|
//
|
|
// When the range resets, invalidate so we repaint.
|
|
//
|
|
// wp = new current pos
|
|
// lp = new range
|
|
//
|
|
case PBM_SETRANGE:
|
|
lp = HIWORD(lp);
|
|
SetWindowLong(hwnd, GWL_CUR, MAKELONG(wp, lp));
|
|
/* FALLTHROUGH */
|
|
|
|
case PBM_SETPOS:
|
|
Progress_OnSetPos(hwnd, wp);
|
|
break;
|
|
|
|
case PBM_DELTAPOS:
|
|
lp = LOWORD(GetWindowLong(hwnd, GWL_CUR));
|
|
Progress_OnSetPos(hwnd, wp + lp);
|
|
break;
|
|
|
|
case WM_ERASEBKGND:
|
|
return 0;
|
|
}
|
|
|
|
return DefWindowProc(hwnd, wm, wp, lp);
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func void | Progress_InitRegisterClass |
|
|
*
|
|
* Register our window classes.
|
|
*
|
|
***************************************************************************/
|
|
|
|
void
|
|
Progress_InitRegisterClass(void)
|
|
{
|
|
WNDCLASS wc;
|
|
|
|
//
|
|
// Progress control.
|
|
//
|
|
wc.style = 0;
|
|
wc.lpfnWndProc = Progress_WndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = cbX(DWORD);
|
|
wc.hInstance = g_App.hInstance;
|
|
wc.hIcon = 0;
|
|
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
|
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
|
|
wc.lpszMenuName = 0;
|
|
wc.lpszClassName = TEXT("progress");
|
|
|
|
RegisterClass(&wc);
|
|
}
|