windows-nt/Source/XPSP1/NT/base/ntsetup/legacy/dll/gauge.c
2020-09-26 16:20:57 +08:00

647 lines
15 KiB
C

#include "precomp.h"
#pragma hdrstop
/* file gauge.c */
HWND hwndProgressGizmo = NULL;
static INT iCnt = 0;
static WNDPROC fpxProDlg;
static DWORD rgbFG;
static DWORD rgbBG;
extern HWND hwndFrame;
extern HANDLE hinstShell;
extern BOOL fMono;
BOOL fUserQuit = fFalse;
static BOOL fInsideGizmosQuitCode = fFalse;
extern BOOL APIENTRY FYield(VOID);
INT gaugeCopyPercentage = -1 ;
#ifndef COLOR_HIGHLIGHT
#define COLOR_HIGHLIGHT (COLOR_APPWORKSPACE + 1)
#define COLOR_HIGHLIGHTTEXT (COLOR_APPWORKSPACE + 2)
#endif
#define COLORBG rgbBG
#define COLORFG rgbFG
BOOL
ProInit(
IN BOOL Init
)
{
WNDCLASS rClass;
BOOL b;
if(Init) {
rClass.hCursor = LoadCursor(NULL, IDC_ARROW);
rClass.hIcon = NULL;
rClass.lpszMenuName = NULL;
rClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
rClass.hInstance = hInst;
rClass.style = CS_HREDRAW | CS_VREDRAW;
rClass.lpfnWndProc = ProBarProc;
rClass.cbClsExtra = 0;
rClass.cbWndExtra = 2 * sizeof(WORD);
}
rClass.lpszClassName = PRO_CLASS;
if(Init) {
if(fMono) {
rgbBG = RGB( 0, 0, 0);
rgbFG = RGB(255, 255, 255);
} else {
rgbBG = RGB( 0, 0, 255);
rgbFG = RGB(255, 255, 255);
}
b = RegisterClass(&rClass);
} else {
b = UnregisterClass(rClass.lpszClassName,hInst);
}
return(b);
}
/***************************************************************************/
VOID APIENTRY ProClear(HWND hdlg)
{
AssertDataSeg();
if (!hdlg)
hdlg = hwndProgressGizmo;
SetDlgItemText(hdlg, ID_STATUS1, "");
SetDlgItemText(hdlg, ID_STATUS2, "");
SetDlgItemText(hdlg, ID_STATUS3, "");
SetDlgItemText(hdlg, ID_STATUS4, "");
}
BOOL
ControlInit(
IN BOOL Init
)
{
WNDCLASS cls;
if(Init) {
cls.hCursor = LoadCursor(NULL, IDC_ARROW);
cls.hIcon = NULL;
cls.lpszMenuName = NULL;
cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
cls.hInstance = hInst;
cls.style = CS_HREDRAW | CS_VREDRAW;
cls.lpfnWndProc = fnText;
cls.cbClsExtra = 0;
cls.cbWndExtra = 0;
}
cls.lpszClassName = "stext";
return(Init ? RegisterClass(&cls) : UnregisterClass(cls.lpszClassName,hInst));
}
static int getNumericSymbol ( SZ szSymName )
{
SZ sz = SzFindSymbolValueInSymTab( szSymName ) ;
return sz ? atoi( sz ) : -1 ;
}
#define SYM_NAME_CTR_X "!G:STF_DLG_PRO_CTR_X"
#define SYM_NAME_CTR_Y "!G:STF_DLG_PRO_CTR_Y"
static void centerOnDesktop ( HWND hdlg )
{
RECT rc ;
POINT pt, ptDlgSize ;
int ixBias = getNumericSymbol( SYM_NAME_CTR_X ),
iyBias = getNumericSymbol( SYM_NAME_CTR_Y ),
cx = GetSystemMetrics( SM_CXFULLSCREEN ),
cy = GetSystemMetrics( SM_CYFULLSCREEN ),
l ;
// Get specified or default bias
if ( ixBias <= 0 || ixBias >= 100 )
ixBias = 50 ; // default value is 1/2 across
if ( iyBias <= 0 || iyBias >= 100 )
iyBias = 50 ; // default value is 1/3 down
// Compute logical center point
pt.x = (cx * ixBias) / 100 ;
pt.y = (cy * iyBias) / 100 ;
GetWindowRect( hdlg, & rc ) ;
ptDlgSize.x = rc.right - rc.left ;
ptDlgSize.y = rc.bottom - rc.top ;
pt.x -= ptDlgSize.x / 2 ;
pt.y -= ptDlgSize.y / 2 ;
// Force upper left corner back onto screen if necessary.
if ( pt.x < 0 )
pt.x = 0 ;
if ( pt.y < 0 )
pt.y = 0 ;
// Now check to see if the dialog is getting clipped
// to the right or bottom.
if ( (l = pt.x + ptDlgSize.x) > cx )
pt.x -= l - cx ;
if ( (l = pt.y + ptDlgSize.y) > cy )
pt.y -= l - cy ;
if ( pt.x < 0 )
pt.x = 0 ;
if ( pt.y < 0 )
pt.y = 0 ;
SetWindowPos( hdlg, NULL,
pt.x, pt.y,
0, 0, SWP_NOSIZE | SWP_NOACTIVATE ) ;
}
/*
** ProDlgProc(hWnd, wMessage, wParam, lParam)
**
** Description:
** The window proc for the Progress dialog box
** Arguments:
** hWnd window handle for the dialog
** wMessage message number
** wParam message-dependent
** lParam message-dependent
** Returns:
** 0 if processed, nonzero if ignored
***************************************************************************/
INT_PTR APIENTRY ProDlgProc(HWND hdlg, UINT wMessage, WPARAM wParam, LPARAM lParam)
{
static SZ szProCancelMsg;
static SZ szProCancelCap;
Unused(lParam); // GET_WM_COMMAND does not use the lParam
AssertDataSeg();
switch (wMessage)
{
case WM_INITDIALOG:
if ((szProCancelMsg = SzFindSymbolValueInSymTab("ProCancelMsg")) == (SZ)NULL ||
(szProCancelCap = SzFindSymbolValueInSymTab("ProCancelCap")) == (SZ)NULL ) {
PreCondition(fFalse, fTrue);
return(fTrue);
}
ProClear(hdlg);
/* BLOCK */ /* centered on the screen - we really want this to be
a WS_CHILD instead of WS_POPUP so we can do something
intelligent inside the frame window */
centerOnDesktop( hdlg ) ;
gaugeCopyPercentage = 0 ;
return(fTrue);
// case WM_ACTIVATE:
// if (wParam != 0)
// SendMessage(hwndFrame, WM_NCACTIVATE, 1, 0L);
// break;
case WM_CLOSE:
gaugeCopyPercentage = -1 ;
PostMessage(
hdlg,
WM_COMMAND,
MAKELONG(IDC_X, BN_CLICKED),
0L
);
return(fTrue);
case WM_COMMAND:
if (!fInsideGizmosQuitCode
&& (LOWORD(wParam) == IDCANCEL || LOWORD(wParam) == IDC_B))
{
fInsideGizmosQuitCode = fTrue;
if (!FYield())
{
fInsideGizmosQuitCode = fFalse;
DestroyWindow(hwndFrame);
}
if ( MessageBox(
hdlg,
(LPSTR)szProCancelMsg,
(LPSTR)szProCancelCap,
MB_YESNO | MB_ICONEXCLAMATION
) == IDYES ) {
fUserQuit = fTrue;
fInsideGizmosQuitCode = fFalse;
return(fFalse);
}
fInsideGizmosQuitCode = fFalse;
SendMessage(hwndFrame, WM_NCACTIVATE, 1, 0L);
}
break;
}
return(fFalse);
}
/*
** ProBarProc(hWnd, wMessage, wParam, lParam)
**
** Description:
** The window proc for the Progress Bar chart
** Arguments:
** hWnd window handle for the dialog
** wMessage message number
** wParam message-dependent
** lParam message-dependent
** Returns:
** 0 if processed, nonzero if ignored
***************************************************************************/
LRESULT APIENTRY ProBarProc(HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT rPS;
RECT rc1, rc2;
INT dx, dy, x;
WORD iRange, iPos;
CHP rgch[30];
INT iHeight = 0, iWidth = 0;
HFONT hfntSav = NULL;
static HFONT hfntBar = NULL;
SIZE size;
AssertDataSeg();
switch (wMessage)
{
case WM_CREATE:
SetWindowWord(hWnd, BAR_RANGE, 10);
SetWindowWord(hWnd, BAR_POS, 0);
return(0L);
case BAR_SETRANGE:
case BAR_SETPOS:
SetWindowWord(hWnd, wMessage - WM_USER, (WORD)wParam);
InvalidateRect(hWnd, NULL, fFalse);
UpdateWindow(hWnd);
return(0L);
case BAR_DELTAPOS:
iRange = (WORD)GetWindowWord(hWnd, BAR_RANGE);
iPos = (WORD)GetWindowWord(hWnd, BAR_POS);
if (iRange <= 0)
iRange = 1;
if (iPos > iRange)
iPos = iRange;
if (iPos + wParam > iRange)
wParam = iRange - iPos;
SetWindowWord(hWnd, BAR_POS, (WORD)(iPos + wParam));
if ((iPos * 100 / iRange) < ((iPos + (WORD)wParam) * 100 / iRange))
{
InvalidateRect(hWnd, NULL, fFalse);
UpdateWindow(hWnd);
}
return(0L);
case WM_SETFONT:
hfntBar = (HFONT)wParam;
if (!lParam)
return(0L);
InvalidateRect(hWnd, NULL, fTrue);
case WM_PAINT:
BeginPaint(hWnd, &rPS);
if (hfntBar)
hfntSav = SelectObject(rPS.hdc, hfntBar);
GetClientRect(hWnd, &rc1);
{
HGDIOBJ hStockObject = GetStockObject(BLACK_BRUSH);
if (hStockObject) {
FrameRect(rPS.hdc, &rc1, hStockObject);
InflateRect(&rc1, -1, -1);
}
}
rc2 = rc1;
iRange = GetWindowWord(hWnd, BAR_RANGE);
iPos = GetWindowWord(hWnd, BAR_POS);
if (iRange <= 0)
iRange = 1;
if (iPos > iRange)
iPos = iRange;
dx = rc1.right;
dy = rc1.bottom;
x = (WORD)((DWORD)iPos * dx / iRange) + 1;
if (iPos < iRange)
iPos++;
gaugeCopyPercentage = ((DWORD) iPos) * 100 / iRange ;
wsprintf(rgch, "%3d%%", (WORD) gaugeCopyPercentage );
GetTextExtentPoint(rPS.hdc, rgch, strlen(rgch), &size);
iWidth = size.cx;
iHeight = size.cy;
rc1.right = x;
rc2.left = x;
SetBkColor(rPS.hdc, COLORBG);
SetTextColor(rPS.hdc, COLORFG);
ExtTextOut(rPS.hdc, (dx-iWidth)/2, (dy-iHeight)/2,
ETO_OPAQUE | ETO_CLIPPED, &rc1, rgch, strlen(rgch), NULL);
SetBkColor(rPS.hdc, COLORFG);
SetTextColor(rPS.hdc, COLORBG);
ExtTextOut(rPS.hdc, (dx-iWidth)/2, (dy-iHeight)/2,
ETO_OPAQUE | ETO_CLIPPED, &rc2, rgch, strlen(rgch), NULL);
if (hfntSav)
SelectObject(rPS.hdc, hfntSav);
EndPaint(hWnd, (LPPAINTSTRUCT)&rPS);
return(0L);
}
return(DefWindowProc(hWnd, wMessage, wParam, lParam));
}
/*
** ProOpen ()
**
** Returns:
** 0 if processed, nonzero if ignored
***************************************************************************/
HWND APIENTRY ProOpen(HWND hwnd, INT id)
{
CHP szTmpText[cchpBufTmpLongMax];
Unused(id);
AssertDataSeg();
//
// Maintain the number of times the progress guage is opened
//
iCnt++;
//
// Check if progress guage still present
//
if (!hwndProgressGizmo)
{
//
// Get Progress Dialog procedure instance
//
#ifdef DLL
fpxProDlg = ProDlgProc;
#else /* !DLL */
fpxProDlg = (WNDPROC)MakeProcInstance(ProDlgProc, hinstShell);
#endif /* !DLL */
//
// Fetch dialog resource name
//
if (!LoadString(hinstShell, IDS_PROGRESS, szTmpText, cchpBufTmpLongMax)) {
strcpy( szTmpText, "Progress" );
}
//
// Create the Progress dialog
//
hwndProgressGizmo = CreateDialog(hinstShell, (LPCSTR)szTmpText, hwnd, (DLGPROC)fpxProDlg);
//
// Fill in @ items with text from the INF
//
EvalAssert(FFillInDialogTextFromInf(hwndProgressGizmo, hinstShell));
//
// Show the guage and paint it
//
ShowWindow(hwndProgressGizmo, SHOW_OPENWINDOW);
UpdateWindow(hwndProgressGizmo);
EnableWindow(hwndFrame, fFalse);
// SendMessage(hwndFrame, WM_NCACTIVATE, 1, 0L);
}
return(hwndProgressGizmo);
}
/*
** ProClose(hwndFrame)
**
** Returns:
** 0 if processed, nonzero if ignored
***************************************************************************/
BOOL APIENTRY ProClose(HWND hwndFrame)
{
AssertDataSeg();
iCnt--;
if (hwndProgressGizmo && iCnt == 0)
{
EnableWindow(hwndFrame, fTrue);
DestroyWindow(hwndProgressGizmo);
FreeProcInstance(fpxProDlg);
hwndProgressGizmo = NULL;
}
return(fTrue);
}
/***************************************************************************/
BOOL APIENTRY ProSetText(INT i, LPSTR sz)
{
AssertDataSeg();
if (hwndProgressGizmo)
{
SetDlgItemText(hwndProgressGizmo, i, sz);
return(fTrue);
}
return(fFalse);
}
/***************************************************************************/
BOOL APIENTRY ProSetCaption(LPSTR szCaption)
{
if (hwndProgressGizmo)
{
SetWindowText(hwndProgressGizmo, szCaption);
return(fTrue);
}
return(fFalse);
}
/***************************************************************************/
BOOL APIENTRY ProSetBarRange(INT i)
{
AssertDataSeg();
if (hwndProgressGizmo)
{
SendDlgItemMessage(hwndProgressGizmo, ID_BAR, BAR_SETRANGE, i, 0L);
return(fTrue);
}
return(fFalse);
}
/***************************************************************************/
BOOL APIENTRY ProSetBarPos(INT i)
{
AssertDataSeg();
if (hwndProgressGizmo)
{
SendDlgItemMessage(hwndProgressGizmo, ID_BAR, BAR_SETPOS, i, 0L);
return(fTrue);
}
return(fFalse);
}
/***************************************************************************/
BOOL APIENTRY ProDeltaPos(INT i)
{
AssertDataSeg();
if (hwndProgressGizmo)
{
SendDlgItemMessage(hwndProgressGizmo, ID_BAR, BAR_DELTAPOS, i, 0L);
return(fTrue);
}
return(fFalse);
}
/*
** text control that uses ExtTextOut() IE no flicker!
****************************************************************************/
LRESULT APIENTRY fnText(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
RECT rc;
CHP rgch[256];
INT len;
HFONT hfntSav = NULL;
static HFONT hfntText = NULL;
SIZE size;
switch (wMsg)
{
case WM_SETTEXT:
DefWindowProc(hwnd, wMsg, wParam, lParam);
InvalidateRect(hwnd,NULL,fFalse);
UpdateWindow(hwnd);
return(0L);
case WM_ERASEBKGND:
return(0L);
case WM_SETFONT:
hfntText = (HFONT)wParam;
if (!lParam)
return(0L);
InvalidateRect(hwnd, NULL, fTrue);
case WM_PAINT:
BeginPaint(hwnd, &ps);
if (hfntText)
hfntSav = SelectObject(ps.hdc, hfntText);
GetClientRect(hwnd,&rc);
len = GetWindowText(hwnd, rgch, sizeof(rgch));
SetBkColor(ps.hdc, GetSysColor(COLOR_BTNFACE));
SetTextColor(ps.hdc, GetSysColor(COLOR_WINDOWTEXT));
ExtTextOut(ps.hdc, 0, 0, ETO_OPAQUE, &rc, rgch, len, NULL);
// see if text was too long. If so, place '...' at end of field.
if(GetTextExtentPoint(ps.hdc,rgch,len,&size)) {
if((size.cx > rc.right - rc.left + 1)
&& GetTextExtentPoint(ps.hdc,"...",3,&size))
{
ExtTextOut(ps.hdc,rc.right-size.cx+1,0,0,NULL,"...",3,NULL);
}
}
if (hfntSav)
SelectObject(ps.hdc, hfntSav);
EndPaint(hwnd, &ps);
return(0L);
}
return(DefWindowProc(hwnd, wMsg, wParam, lParam));
}
#ifdef UNUSED
/*
** wsDlgInit(hdlg)
**
** Handle the init message for a dialog box
***************************************************************************/
VOID APIENTRY wsDlgInit(HWND hdlg)
{
AssertDataSeg();
/* Center the dialog. */
centerOnDesktop( hdlg ) ;
}
#endif /* UNUSED */