//========= Copyright Valve Corporation, All rights reserved. ============// // // PROGRESS.CPP // // Progress Metering Utility. //=====================================================================================// #include "vxconsole.h" #define PROGRESS_WIDTH 425 #define PROGRESS_HEIGHT 170 #define ID_PROGRESS_STATUS1 100 #define ID_PROGRESS_STATUS2 101 #define ID_PROGRESS_STATUS3 102 #define ID_PROGRESS_PERCENT 103 #define ID_PROGRESS_METER 104 #define ID_PROGRESS_CANCEL 105 //----------------------------------------------------------------------------- // CProgress_WndProc // //----------------------------------------------------------------------------- LRESULT CALLBACK Progress_WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { CProgress *pProgress; CREATESTRUCT *createStructPtr; switch ( message ) { case WM_CREATE: createStructPtr = ( CREATESTRUCT* )lParam; SetWindowLong( hwnd, GWL_USERDATA+0, ( LONG )createStructPtr->lpCreateParams ); return 0L; case WM_DESTROY: pProgress = ( CProgress* )GetWindowLong( hwnd, GWL_USERDATA+0 ); if ( pProgress ) pProgress->m_hWnd = NULL; return 0L; case WM_CTLCOLORSTATIC: SetBkColor( ( HDC )wParam, g_backgroundColor ); return ( BOOL )g_hBackgroundBrush; case WM_COMMAND: switch ( LOWORD( wParam ) ) { case ID_PROGRESS_CANCEL: pProgress = ( CProgress* )GetWindowLong( hwnd, GWL_USERDATA+0 ); if ( pProgress ) pProgress->m_bCancelPressed = true; return ( TRUE ); } break; } return ( DefWindowProc( hwnd, message, wParam, lParam ) ); } //----------------------------------------------------------------------------- // CProgress::Update // // Pump the message loop //----------------------------------------------------------------------------- void CProgress::Update() { MSG msg; while ( PeekMessage( &msg, NULL, 0, 0, PM_NOYIELD|PM_REMOVE ) ) { if ( !TranslateAccelerator( g_hDlgMain, g_hAccel, &msg ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } } } //----------------------------------------------------------------------------- // CProgress::IsCancel // //----------------------------------------------------------------------------- bool CProgress::IsCancel() { return m_bCancelPressed; } //----------------------------------------------------------------------------- // CProgress::SetMeter // //----------------------------------------------------------------------------- void CProgress::SetMeter( int currentPos, int range ) { char buff[16]; int percent; if ( !m_hWnd || !m_hWndPercent || !m_hWndMeter ) return; if ( range >= 0 ) { SendMessage( m_hWndMeter, PBM_SETRANGE, 0, MAKELPARAM( 0, range ) ); m_range = range; } SendMessage( m_hWndMeter, PBM_SETPOS, currentPos, 0 ); if ( m_range > 0 ) { percent = ( int )( 100.0f*currentPos/m_range ); if ( percent > 100 ) percent = 100; } else percent = 0; sprintf( buff, "%d%%", percent ); SetWindowText( m_hWndPercent, buff ); Update(); } //----------------------------------------------------------------------------- // CProgress::SetStatus // //----------------------------------------------------------------------------- void CProgress::SetStatus( const char *line1, const char *line2, const char *line3 ) { if ( !m_hWnd ) return; if ( line1 ) SetWindowText( m_hWndStatus1, line1 ); if ( line2 ) SetWindowText( m_hWndStatus2, line2 ); if ( line3 ) SetWindowText( m_hWndStatus3, line3 ); Update(); } //----------------------------------------------------------------------------- // CProgress::Open // //----------------------------------------------------------------------------- void CProgress::Open( const char* title, bool canCancel, bool bHasMeter ) { HWND hWnd; RECT clientRect; RECT parentRect; int cx; int cy; int cw; int ch; int y; int dialogHeight; dialogHeight = PROGRESS_HEIGHT; if ( !canCancel ) dialogHeight -= 25; if ( !bHasMeter ) dialogHeight -= GetSystemMetrics( SM_CYVSCROLL ); hWnd = CreateWindowEx( WS_EX_CLIENTEDGE, "PROGRESSCLASS", title, WS_POPUP|WS_CAPTION, 0, 0, PROGRESS_WIDTH, dialogHeight, g_hDlgMain, NULL, g_hInstance, ( void* )this ); m_hWnd = hWnd; if ( !m_hWnd ) return; // status text line #1 GetClientRect( m_hWnd, &clientRect ); y = 10; hWnd = CreateWindowEx( 0, WC_STATIC, "", WS_VISIBLE|WS_CHILD|SS_WORDELLIPSIS, 8, 10, clientRect.right-clientRect.left-2*8 - 50, 20, m_hWnd, ( HMENU )ID_PROGRESS_STATUS1, g_hInstance, NULL ); m_hWndStatus1 = hWnd; y += 20; // status text line #2 hWnd = CreateWindowEx( 0, WC_STATIC, "", WS_VISIBLE|WS_CHILD|SS_PATHELLIPSIS, 8, y, clientRect.right-clientRect.left-2*8 -50, 20, m_hWnd, ( HMENU )ID_PROGRESS_STATUS2, g_hInstance, NULL ); m_hWndStatus2 = hWnd; y += 20; // status text line #3 hWnd = CreateWindowEx( 0, WC_STATIC, "", WS_VISIBLE|WS_CHILD|SS_PATHELLIPSIS, 8, y, clientRect.right-clientRect.left-2*8 -50, 20, m_hWnd, ( HMENU )ID_PROGRESS_STATUS3, g_hInstance, NULL ); m_hWndStatus3 = hWnd; y += 20; // set font SendMessage( m_hWndStatus1, WM_SETFONT, ( WPARAM )g_hProportionalFont, TRUE ); SendMessage( m_hWndStatus2, WM_SETFONT, ( WPARAM )g_hProportionalFont, TRUE ); SendMessage( m_hWndStatus3, WM_SETFONT, ( WPARAM )g_hProportionalFont, TRUE ); if ( bHasMeter ) { // percent hWnd = CreateWindowEx( 0, WC_STATIC, "0%", WS_VISIBLE|WS_CHILD|SS_RIGHT, ( clientRect.right-clientRect.left ) - 2*8 - 50, y - 20, 50, 20, m_hWnd, ( HMENU )ID_PROGRESS_PERCENT, g_hInstance, NULL ); m_hWndPercent = hWnd; SendMessage( m_hWndPercent, WM_SETFONT, ( WPARAM )g_hProportionalFont, TRUE ); // progress meter ch = GetSystemMetrics( SM_CYVSCROLL ); cw = ( clientRect.right-clientRect.left ) - 2*8; cx = ( clientRect.left + clientRect.right )/2 - cw/2; cy = y; hWnd = CreateWindowEx( WS_EX_CLIENTEDGE, PROGRESS_CLASS, NULL, WS_VISIBLE|WS_CHILD, cx, cy, cw, ch, m_hWnd, ( HMENU )ID_PROGRESS_METER, g_hInstance, NULL ); m_hWndMeter = hWnd; y = cy+ch; // ensure bar is reset SendMessage( m_hWndMeter, PBM_SETRANGE, 0, 0 ); SendMessage( m_hWndMeter, PBM_SETPOS, 0, 0 ); } else { m_hWndPercent = NULL; m_hWndMeter = NULL; } m_bCancelPressed = false; if ( canCancel ) { ch = 25; cw = 80; cx = ( clientRect.left + clientRect.right )/2 - cw/2; cy = clientRect.bottom - 8 - ch; // cancel button hWnd = CreateWindowEx( 0, WC_BUTTON, "Cancel", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON, cx, cy, cw, ch, m_hWnd, ( HMENU )ID_PROGRESS_CANCEL, g_hInstance, NULL ); m_hWndCancel = hWnd; SendMessage( m_hWndCancel, WM_SETFONT, ( WPARAM )g_hProportionalFont, TRUE ); } // get parent rectangle GetWindowRect( g_hDlgMain, &parentRect ); cx = ( parentRect.left + parentRect.right )/2 - PROGRESS_WIDTH/2; cy = ( parentRect.top + parentRect.bottom )/2 - dialogHeight/2; MoveWindow( m_hWnd, cx, cy, PROGRESS_WIDTH, dialogHeight, FALSE ); ShowWindow( m_hWnd, SHOW_OPENWINDOW ); } //----------------------------------------------------------------------------- // CProgress::~CProgress // //----------------------------------------------------------------------------- CProgress::~CProgress() { if ( !m_hWnd ) return; DestroyWindow( m_hWnd ); m_hWnd = NULL; } //----------------------------------------------------------------------------- // CProgress::CProgress // //----------------------------------------------------------------------------- CProgress::CProgress() { // set up our window class WNDCLASS wndclass; memset( &wndclass, 0, sizeof( wndclass ) ); wndclass.style = 0; wndclass.lpfnWndProc = Progress_WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = sizeof( CProgress* ); wndclass.hInstance = g_hInstance; wndclass.hIcon = g_hIcons[ICON_APPLICATION]; wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndclass.hbrBackground = g_hBackgroundBrush; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "PROGRESSCLASS"; RegisterClass( &wndclass ); m_hWnd = 0; m_bCancelPressed = false; }