|
|
/*****************************************************************************
* * 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;
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.
wsprintf(tsz, TEXT("%d%%"), iPct); for(ctch=0;tsz[ctch];ctch++);
/*
* Draw the left-hand side. */ //ctch = GetWindowText(hwnd, tsz, cA(tsz));
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 */
/*
* When our text changes, invalidate so we repaint. */ //case WM_SETTEXT:
//InvalidateRect(hwnd, 0, 0);
//break;
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); }
|