|
|
/******************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name: progress.cpp
Abstract: This file contains the implementation of CRestoreProgressWindow class and ::CreateRestoreProgressWindow.
Revision History: Seong Kook Khang (SKKhang) 06/20/00 created
******************************************************************************/
#include "stdwin.h"
#include "rstrcore.h"
#include "resource.h"
// Number of change log entries corresponding to one physical progress position.
//#define NUM_INC_PER_POS 5
// Time for each increment of progress bar during snapshot handling (msec.)
//#define TIMER_SNAPSHOT 40
// Position (percent) of progress bar where "restore" stage starts.
#define PROGBAR_POS_RESTORE 20
// Position (percent) of progress bar where "snapshot" stage starts.
#define PROGBAR_POS_SNAPSHOT 90
/////////////////////////////////////////////////////////////////////////////
// CRestoreOperationManager construction / destruction
CRestoreProgressWindow::CRestoreProgressWindow() { m_hWnd = NULL; m_hbmBrand = NULL; m_hFntTitle = NULL; m_cxBar = 0; }
/////////////////////////////////////////////////////////////////////////////
CRestoreProgressWindow::~CRestoreProgressWindow() { Close(); }
/////////////////////////////////////////////////////////////////////////////
// CRestoreProgressWindow - methods
BOOL CRestoreProgressWindow::Create() { TraceFunctEnter("CRestoreProgressWindow::Create"); BOOL fRet = FALSE; HWND hWnd;
hWnd = ::CreateDialogParam( g_hInst, MAKEINTRESOURCE(IDD_PROGRESS), NULL, ExtDlgProc, (LPARAM)this ); if ( hWnd == NULL ) { LPCWSTR cszErr = ::GetSysErrStr(); ErrorTrace(0, "::CreateDialogParam failed - %ls", cszErr); goto Exit; } if ( hWnd != m_hWnd ) { ErrorTrace(0, "Internal mismatch - hWnd=%08X, m_hWnd=%08X", hWnd, m_hWnd); m_hWnd = hWnd; }
::ShowWindow( m_hWnd, SW_SHOW );
fRet = TRUE; Exit: TraceFunctLeave(); return( fRet ); }
/////////////////////////////////////////////////////////////////////////////
BOOL CRestoreProgressWindow::Close() { TraceFunctEnter("CRestoreProgressWindow::Create"); BOOL fRet = FALSE;
if ( m_hWnd != NULL && ::SendMessage( m_hWnd, WM_CLOSE, 0, 0 ) == 0 ) { LPCWSTR cszErr = ::GetSysErrStr(); ErrorTrace(0, "::SendMessage failed - %ls", cszErr); goto Exit; }
m_hWnd = NULL;
if ( m_hbmBrand != NULL ) { ::DeleteObject( m_hbmBrand ); m_hbmBrand = NULL; }
if ( m_hFntTitle != NULL ) { ::DeleteObject( m_hFntTitle ); m_hFntTitle = NULL; }
fRet = TRUE; Exit: TraceFunctLeave(); return( fRet ); }
/////////////////////////////////////////////////////////////////////////////
BOOL CRestoreProgressWindow::Run() { TraceFunctEnter("CRestoreProgressWindow::Run"); MSG msg;
while ( ::GetMessage( &msg, NULL, 0, 0 ) ) { if ( !::IsDialogMessage( m_hWnd, &msg ) ) { ::TranslateMessage( &msg ); ::DispatchMessage( &msg ); } }
TraceFunctLeave(); return( TRUE ); }
/////////////////////////////////////////////////////////////////////////////
BOOL CRestoreProgressWindow::SetStage( DWORD dwStage, DWORD dwBase ) { TraceFunctEnter("CRestoreProgressWindow::SetStage"); BOOL fRet = FALSE; LPCWSTR cszErr; UINT uIdStatus; WCHAR szStatus[MAX_STR];
m_dwStage = dwStage;
switch ( dwStage ) { case RPS_PREPARE : uIdStatus = IDS_PROGRESS_PREPARE; m_dwPosReal = 0; break;
case RPS_RESTORE : uIdStatus = IDS_PROGRESS_RESTORE; m_dwBase = dwBase; m_dwPosReal = PROGBAR_POS_RESTORE * m_cxBar / 100; m_dwPosLog = 0; break;
case RPS_SNAPSHOT : uIdStatus = IDS_PROGRESS_SNAPSHOT; m_dwPosReal = PROGBAR_POS_SNAPSHOT * m_cxBar / 100; break;
default : ErrorTrace(0, "Unknown Stage constant - %u", dwStage ); goto Exit; }
szStatus[0] = L'\0'; if ( ::LoadString( g_hInst, uIdStatus, szStatus, MAX_STR ) == 0 ) { cszErr = ::GetSysErrStr(); ErrorTrace(0, "::LoadString(%u) failed - %ls", uIdStatus, cszErr); // ignore error...
} else if ( !::SetDlgItemText( m_hWnd, IDC_PROGDLG_STATUS, szStatus ) ) { cszErr = ::GetSysErrStr(); ErrorTrace(0, "::SetDlgItemText failed - %ls", cszErr); // ignore error...
}
::SendDlgItemMessage( m_hWnd, IDC_PROGDLG_BAR, PBM_SETPOS, m_dwPosReal, 0 );
fRet = TRUE; Exit: TraceFunctLeave(); return( fRet ); }
/////////////////////////////////////////////////////////////////////////////
BOOL CRestoreProgressWindow::Increment() { TraceFunctEnter("CRestoreProgressWindow::Increment"); BOOL fRet = FALSE; DWORD dwPosNew;
//m_dwPosLog++;
dwPosNew = m_dwPosReal;
switch ( m_dwStage ) { case RPS_PREPARE : //dwPosNew = ( m_dwPosLog / NUM_INC_PER_POS ) % ( m_cxBar + 1 );
break;
case RPS_RESTORE : m_dwPosLog++; if ( m_dwPosLog > m_dwBase ) { ErrorTrace(0, "INTERNAL: m_dwPosLog(%u) is bigger than m_dwBase(%u)", m_dwPosLog, m_dwBase); m_dwPosLog = m_dwBase; } //dwPosNew = ( m_dwPosLog - 1 ) * m_cxBar / m_dwBase + 1;
if (m_dwBase > 0) { dwPosNew = ( m_dwPosLog - 1 ) * m_cxBarReal / m_dwBase + 1 + PROGBAR_POS_RESTORE * m_cxBar / 100; } break;
case RPS_SNAPSHOT : //dwPosNew = m_dwPosLog % ( m_cxBar + 1 );
dwPosNew = m_cxBar; break;
default : ErrorTrace(0, "m_dwStage(%u) is not Prepare or Restore...", m_dwStage); goto Exit; }
if ( dwPosNew != m_dwPosReal ) { m_dwPosReal = dwPosNew; ::SendDlgItemMessage( m_hWnd, IDC_PROGDLG_BAR, PBM_SETPOS, dwPosNew, 0 ); }
fRet = TRUE; Exit: TraceFunctLeave(); return( fRet ); }
/////////////////////////////////////////////////////////////////////////////
BOOL CRestoreProgressWindow::Release() { TraceFunctEnter("CRestoreProgressWindow::Release"); delete this; TraceFunctLeave(); return( TRUE ); }
/////////////////////////////////////////////////////////////////////////////
// CRestoreProgressWindow operations
BOOL CRestoreProgressWindow::Init() { TraceFunctEnter("CRestoreProgressWindow::Init"); BOOL fRet = FALSE; INITCOMMONCONTROLSEX sICC;
sICC.dwSize = sizeof(INITCOMMONCONTROLSEX); sICC.dwICC = ICC_PROGRESS_CLASS; if ( !::InitCommonControlsEx( &sICC ) ) { LPCWSTR cszErr = ::GetSysErrStr(); ErrorTrace(0, "::InitCommonControlsEx failed - %ls", cszErr); goto Exit; }
fRet = TRUE; Exit: TraceFunctLeave(); return( fRet ); }
/////////////////////////////////////////////////////////////////////////////
BOOL CRestoreProgressWindow::LoadAndSetBrandBitmap( HWND hDlg ) { TraceFunctEnter("CRestoreProgressWindow::LoadAndSetBrandBitmap"); BOOL fRet = FALSE; LPCWSTR cszErr; HDC hDC = NULL; int nResIdBmp; HBITMAP hbmBrand; BITMAP bm; HWND hwndBmp; RECT rcCtrl;
hDC = ::CreateCompatibleDC( NULL ); if ( hDC == NULL ) { cszErr = ::GetSysErrStr(); FatalTrace(0, "::CreateCompatibleDC(NULL) failed - %ls", cszErr); goto Exit; } if ( ::GetDeviceCaps( hDC, BITSPIXEL ) > 8 ) nResIdBmp = IDB_PROG_BRAND8; else nResIdBmp = IDB_PROG_BRAND4; ::DeleteDC( hDC );
if ( m_hbmBrand != NULL ) { if ( nResIdBmp == m_nResId ) { // The current bitmap is compatible with new display setting.
fRet = TRUE; goto Exit; }
m_nResId = nResIdBmp; ::DeleteObject( m_hbmBrand ); }
hbmBrand = (HBITMAP)::LoadImage( g_hInst, MAKEINTRESOURCE(nResIdBmp), IMAGE_BITMAP, 0, 0, 0 ); if ( hbmBrand == NULL ) { cszErr = ::GetSysErrStr(); ErrorTrace(0, "::LoadImage(%d) failed - %ls", nResIdBmp, cszErr); goto Exit; } // Get dimension of the bitmap.
::GetObject( hbmBrand, sizeof(bm), &bm ); // Static control does not support RTL layout. Mirror the bitmap if necessary.
if ( ( ::GetWindowLong( hDlg, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL ) != 0 ) { HDC hDCSrc, hDCDst; HBITMAP hbmRTL;
hDC = ::CreateCompatibleDC( NULL ); hDCSrc = ::CreateCompatibleDC( hDC ); hDCDst = ::CreateCompatibleDC( hDC ); hbmRTL = ::CreateBitmapIndirect( &bm ); ::SelectObject( hDCSrc, hbmBrand ); ::SelectObject( hDCDst, hbmRTL ); ::StretchBlt( hDCDst, 0, 0, bm.bmWidth, bm.bmHeight, hDCSrc, bm.bmWidth-1, 0, -bm.bmWidth, bm.bmHeight, SRCCOPY ); ::DeleteDC( hDCDst ); ::DeleteDC( hDCSrc ); ::DeleteDC( hDC ); ::DeleteObject( hbmBrand ); m_hbmBrand = hbmRTL; } else { m_hbmBrand = hbmBrand; }
// Get dimension of the static control.
hwndBmp = ::GetDlgItem( hDlg, IDC_PROGDLG_BITMAP ); ::GetWindowRect( hwndBmp, &rcCtrl ); ::MapWindowPoints( NULL, hDlg, (LPPOINT)&rcCtrl, 2 );
// Set the image.
::SendMessage( hwndBmp, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_hbmBrand ); // Set width of the static control.
::SetWindowPos( hwndBmp, NULL, rcCtrl.left, (rcCtrl.bottom-rcCtrl.top-bm.bmHeight)/2+rcCtrl.top, bm.bmWidth, bm.bmHeight, SWP_NOZORDER );
fRet = TRUE; Exit: TraceFunctLeave(); return( fRet ); }
/////////////////////////////////////////////////////////////////////////////
// CRestoreProgressWindow operations - dialog procedure
INT_PTR CALLBACK CRestoreProgressWindow::ExtDlgProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam ) { TraceFunctEnter("CRestoreProgressWindow::ExtDlgProc"); int nRet = FALSE; CRestoreProgressWindow *pProgWnd;
if ( wMsg == WM_INITDIALOG ) { ::SetWindowLong( hDlg, DWL_USER, lParam ); pProgWnd = (CRestoreProgressWindow*)lParam; } else { pProgWnd = (CRestoreProgressWindow*)::GetWindowLong( hDlg, DWL_USER ); if ( pProgWnd == NULL ) goto Exit; }
nRet = pProgWnd->RPWDlgProc( hDlg, wMsg, wParam, lParam );
Exit: TraceFunctLeave(); return( nRet ); }
/////////////////////////////////////////////////////////////////////////////
int CRestoreProgressWindow::RPWDlgProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam ) { TraceFunctEnter("CRestoreProgressWindow::RPWDlgProc"); int nRet = FALSE; HFONT hFont; LOGFONT lf; HDC hDC; RECT rcClient; UINT uID; HBRUSH hbrTitle;
switch ( wMsg ) { case WM_INITDIALOG : m_hWnd = hDlg;
// Create a large font for branding title.
hFont = (HFONT)::SendDlgItemMessage( hDlg, IDC_PROGDLG_TITLE, WM_GETFONT, 0, 0 ); ::GetObject( hFont, sizeof(lf), &lf ); hDC = ::GetDC( hDlg ); lf.lfHeight = 0 - ( ::GetDeviceCaps( hDC, LOGPIXELSY ) * 12 / 72 ); lf.lfWeight = FW_BOLD; ::ReleaseDC( hDlg, hDC ); m_hFntTitle = ::CreateFontIndirect( &lf ); ::SendDlgItemMessage( hDlg, IDC_PROGDLG_TITLE, WM_SETFONT, (WPARAM)m_hFntTitle, FALSE );
// Load branding bitmap.
LoadAndSetBrandBitmap( hDlg );
// Get width of the progress bar.
::GetClientRect( ::GetDlgItem( hDlg, IDC_PROGDLG_BAR ), &rcClient ); m_cxBar = rcClient.right - rcClient.left; m_cxBarReal = m_cxBar * ( PROGBAR_POS_SNAPSHOT - PROGBAR_POS_RESTORE ) / 100; // Set range of progress bar so it would exactly match with
// real size, and set initial position to 0.
::SendDlgItemMessage( hDlg, IDC_PROGDLG_BAR, PBM_SETRANGE32, 0, m_cxBar ); ::SendDlgItemMessage( hDlg, IDC_PROGDLG_BAR, PBM_SETPOS, 0, 0 );
break;
case WM_CLOSE : if ( !::DestroyWindow( hDlg ) ) { LPCWSTR cszErr = ::GetSysErrStr(); ErrorTrace(0, "::DestroyWindow failed - %ls", cszErr); goto Exit; } ::SetWindowLong( hDlg, DWL_MSGRESULT, 1 ); break;
case WM_CTLCOLORSTATIC : uID = ::GetWindowLong( (HWND)lParam, GWL_ID ); if ( ( uID == IDC_PROGDLG_BITMAP ) || ( uID == IDC_PROGDLG_TITLE ) ) { ::SetBkMode( (HDC)wParam, TRANSPARENT ); hbrTitle = (HBRUSH)::GetStockObject( NULL_BRUSH ); } else hbrTitle = NULL; nRet = (int)hbrTitle; goto Exit;
case WM_DISPLAYCHANGE : LoadAndSetBrandBitmap( hDlg ); break;
case WM_DESTROY : ::PostQuitMessage( 0 ); break;
default: goto Exit; }
nRet = TRUE; Exit: TraceFunctLeave(); return( nRet ); }
/////////////////////////////////////////////////////////////////////////////
//
// CreateRestoreProgressWindow function
//
/////////////////////////////////////////////////////////////////////////////
BOOL CreateRestoreProgressWindow( CRestoreProgressWindow **ppProgWnd ) { TraceFunctEnter("CreateRestoreProgressWindow"); BOOL fRet = FALSE; CRestoreProgressWindow *pProgWnd=NULL;
if ( ppProgWnd == NULL ) { FatalTrace(0, "Invalid parameter, ppProgWnd is NULL."); goto Exit; } *ppProgWnd = NULL;
pProgWnd = new CRestoreProgressWindow; if ( pProgWnd == NULL ) { FatalTrace(0, "Insufficient memory..."); goto Exit; }
if ( !pProgWnd->Init() ) goto Exit;
*ppProgWnd = pProgWnd;
fRet = TRUE; Exit: if ( !fRet ) SAFE_RELEASE(pProgWnd); TraceFunctLeave(); return( fRet ); }
// end of file
|