Leaked source code of windows server 2003
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

/*****************************************************************************
*
* 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);
}