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.

546 lines
14 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. progress.cpp
  5. Abstract:
  6. This file contains the implementation of CRestoreProgressWindow class and
  7. ::CreateRestoreProgressWindow.
  8. Revision History:
  9. Seong Kook Khang (SKKhang) 06/20/00
  10. created
  11. ******************************************************************************/
  12. #include "stdwin.h"
  13. #include "rstrcore.h"
  14. #include "resource.h"
  15. // Number of change log entries corresponding to one physical progress position.
  16. //#define NUM_INC_PER_POS 5
  17. // Time for each increment of progress bar during snapshot handling (msec.)
  18. //#define TIMER_SNAPSHOT 40
  19. // Position (percent) of progress bar where "restore" stage starts.
  20. #define PROGBAR_POS_RESTORE 20
  21. // Position (percent) of progress bar where "snapshot" stage starts.
  22. #define PROGBAR_POS_SNAPSHOT 90
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CRestoreOperationManager construction / destruction
  25. CRestoreProgressWindow::CRestoreProgressWindow()
  26. {
  27. m_hWnd = NULL;
  28. m_hbmBrand = NULL;
  29. m_hFntTitle = NULL;
  30. m_cxBar = 0;
  31. }
  32. /////////////////////////////////////////////////////////////////////////////
  33. CRestoreProgressWindow::~CRestoreProgressWindow()
  34. {
  35. Close();
  36. }
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CRestoreProgressWindow - methods
  39. BOOL
  40. CRestoreProgressWindow::Create()
  41. {
  42. TraceFunctEnter("CRestoreProgressWindow::Create");
  43. BOOL fRet = FALSE;
  44. HWND hWnd;
  45. hWnd = ::CreateDialogParam( g_hInst, MAKEINTRESOURCE(IDD_PROGRESS), NULL, ExtDlgProc, (LPARAM)this );
  46. if ( hWnd == NULL )
  47. {
  48. LPCWSTR cszErr = ::GetSysErrStr();
  49. ErrorTrace(0, "::CreateDialogParam failed - %ls", cszErr);
  50. goto Exit;
  51. }
  52. if ( hWnd != m_hWnd )
  53. {
  54. ErrorTrace(0, "Internal mismatch - hWnd=%08X, m_hWnd=%08X", hWnd, m_hWnd);
  55. m_hWnd = hWnd;
  56. }
  57. ::ShowWindow( m_hWnd, SW_SHOW );
  58. fRet = TRUE;
  59. Exit:
  60. TraceFunctLeave();
  61. return( fRet );
  62. }
  63. /////////////////////////////////////////////////////////////////////////////
  64. BOOL
  65. CRestoreProgressWindow::Close()
  66. {
  67. TraceFunctEnter("CRestoreProgressWindow::Create");
  68. BOOL fRet = FALSE;
  69. if ( m_hWnd != NULL && ::SendMessage( m_hWnd, WM_CLOSE, 0, 0 ) == 0 )
  70. {
  71. LPCWSTR cszErr = ::GetSysErrStr();
  72. ErrorTrace(0, "::SendMessage failed - %ls", cszErr);
  73. goto Exit;
  74. }
  75. m_hWnd = NULL;
  76. if ( m_hbmBrand != NULL )
  77. {
  78. ::DeleteObject( m_hbmBrand );
  79. m_hbmBrand = NULL;
  80. }
  81. if ( m_hFntTitle != NULL )
  82. {
  83. ::DeleteObject( m_hFntTitle );
  84. m_hFntTitle = NULL;
  85. }
  86. fRet = TRUE;
  87. Exit:
  88. TraceFunctLeave();
  89. return( fRet );
  90. }
  91. /////////////////////////////////////////////////////////////////////////////
  92. BOOL
  93. CRestoreProgressWindow::Run()
  94. {
  95. TraceFunctEnter("CRestoreProgressWindow::Run");
  96. MSG msg;
  97. while ( ::GetMessage( &msg, NULL, 0, 0 ) )
  98. {
  99. if ( !::IsDialogMessage( m_hWnd, &msg ) )
  100. {
  101. ::TranslateMessage( &msg );
  102. ::DispatchMessage( &msg );
  103. }
  104. }
  105. TraceFunctLeave();
  106. return( TRUE );
  107. }
  108. /////////////////////////////////////////////////////////////////////////////
  109. BOOL
  110. CRestoreProgressWindow::SetStage( DWORD dwStage, DWORD dwBase )
  111. {
  112. TraceFunctEnter("CRestoreProgressWindow::SetStage");
  113. BOOL fRet = FALSE;
  114. LPCWSTR cszErr;
  115. UINT uIdStatus;
  116. WCHAR szStatus[MAX_STR];
  117. m_dwStage = dwStage;
  118. switch ( dwStage )
  119. {
  120. case RPS_PREPARE :
  121. uIdStatus = IDS_PROGRESS_PREPARE;
  122. m_dwPosReal = 0;
  123. break;
  124. case RPS_RESTORE :
  125. uIdStatus = IDS_PROGRESS_RESTORE;
  126. m_dwBase = dwBase;
  127. m_dwPosReal = PROGBAR_POS_RESTORE * m_cxBar / 100;
  128. m_dwPosLog = 0;
  129. break;
  130. case RPS_SNAPSHOT :
  131. uIdStatus = IDS_PROGRESS_SNAPSHOT;
  132. m_dwPosReal = PROGBAR_POS_SNAPSHOT * m_cxBar / 100;
  133. break;
  134. default :
  135. ErrorTrace(0, "Unknown Stage constant - %u", dwStage );
  136. goto Exit;
  137. }
  138. szStatus[0] = L'\0';
  139. if ( ::LoadString( g_hInst, uIdStatus, szStatus, MAX_STR ) == 0 )
  140. {
  141. cszErr = ::GetSysErrStr();
  142. ErrorTrace(0, "::LoadString(%u) failed - %ls", uIdStatus, cszErr);
  143. // ignore error...
  144. }
  145. else if ( !::SetDlgItemText( m_hWnd, IDC_PROGDLG_STATUS, szStatus ) )
  146. {
  147. cszErr = ::GetSysErrStr();
  148. ErrorTrace(0, "::SetDlgItemText failed - %ls", cszErr);
  149. // ignore error...
  150. }
  151. ::SendDlgItemMessage( m_hWnd, IDC_PROGDLG_BAR, PBM_SETPOS, m_dwPosReal, 0 );
  152. fRet = TRUE;
  153. Exit:
  154. TraceFunctLeave();
  155. return( fRet );
  156. }
  157. /////////////////////////////////////////////////////////////////////////////
  158. BOOL
  159. CRestoreProgressWindow::Increment()
  160. {
  161. TraceFunctEnter("CRestoreProgressWindow::Increment");
  162. BOOL fRet = FALSE;
  163. DWORD dwPosNew;
  164. //m_dwPosLog++;
  165. dwPosNew = m_dwPosReal;
  166. switch ( m_dwStage )
  167. {
  168. case RPS_PREPARE :
  169. //dwPosNew = ( m_dwPosLog / NUM_INC_PER_POS ) % ( m_cxBar + 1 );
  170. break;
  171. case RPS_RESTORE :
  172. m_dwPosLog++;
  173. if ( m_dwPosLog > m_dwBase )
  174. {
  175. ErrorTrace(0, "INTERNAL: m_dwPosLog(%u) is bigger than m_dwBase(%u)", m_dwPosLog, m_dwBase);
  176. m_dwPosLog = m_dwBase;
  177. }
  178. //dwPosNew = ( m_dwPosLog - 1 ) * m_cxBar / m_dwBase + 1;
  179. if (m_dwBase > 0)
  180. {
  181. dwPosNew = ( m_dwPosLog - 1 ) * m_cxBarReal / m_dwBase + 1 +
  182. PROGBAR_POS_RESTORE * m_cxBar / 100;
  183. }
  184. break;
  185. case RPS_SNAPSHOT :
  186. //dwPosNew = m_dwPosLog % ( m_cxBar + 1 );
  187. dwPosNew = m_cxBar;
  188. break;
  189. default :
  190. ErrorTrace(0, "m_dwStage(%u) is not Prepare or Restore...", m_dwStage);
  191. goto Exit;
  192. }
  193. if ( dwPosNew != m_dwPosReal )
  194. {
  195. m_dwPosReal = dwPosNew;
  196. ::SendDlgItemMessage( m_hWnd, IDC_PROGDLG_BAR, PBM_SETPOS, dwPosNew, 0 );
  197. }
  198. fRet = TRUE;
  199. Exit:
  200. TraceFunctLeave();
  201. return( fRet );
  202. }
  203. /////////////////////////////////////////////////////////////////////////////
  204. BOOL
  205. CRestoreProgressWindow::Release()
  206. {
  207. TraceFunctEnter("CRestoreProgressWindow::Release");
  208. delete this;
  209. TraceFunctLeave();
  210. return( TRUE );
  211. }
  212. /////////////////////////////////////////////////////////////////////////////
  213. // CRestoreProgressWindow operations
  214. BOOL
  215. CRestoreProgressWindow::Init()
  216. {
  217. TraceFunctEnter("CRestoreProgressWindow::Init");
  218. BOOL fRet = FALSE;
  219. INITCOMMONCONTROLSEX sICC;
  220. sICC.dwSize = sizeof(INITCOMMONCONTROLSEX);
  221. sICC.dwICC = ICC_PROGRESS_CLASS;
  222. if ( !::InitCommonControlsEx( &sICC ) )
  223. {
  224. LPCWSTR cszErr = ::GetSysErrStr();
  225. ErrorTrace(0, "::InitCommonControlsEx failed - %ls", cszErr);
  226. goto Exit;
  227. }
  228. fRet = TRUE;
  229. Exit:
  230. TraceFunctLeave();
  231. return( fRet );
  232. }
  233. /////////////////////////////////////////////////////////////////////////////
  234. BOOL
  235. CRestoreProgressWindow::LoadAndSetBrandBitmap( HWND hDlg )
  236. {
  237. TraceFunctEnter("CRestoreProgressWindow::LoadAndSetBrandBitmap");
  238. BOOL fRet = FALSE;
  239. LPCWSTR cszErr;
  240. HDC hDC = NULL;
  241. int nResIdBmp;
  242. HBITMAP hbmBrand;
  243. BITMAP bm;
  244. HWND hwndBmp;
  245. RECT rcCtrl;
  246. hDC = ::CreateCompatibleDC( NULL );
  247. if ( hDC == NULL )
  248. {
  249. cszErr = ::GetSysErrStr();
  250. FatalTrace(0, "::CreateCompatibleDC(NULL) failed - %ls", cszErr);
  251. goto Exit;
  252. }
  253. if ( ::GetDeviceCaps( hDC, BITSPIXEL ) > 8 )
  254. nResIdBmp = IDB_PROG_BRAND8;
  255. else
  256. nResIdBmp = IDB_PROG_BRAND4;
  257. ::DeleteDC( hDC );
  258. if ( m_hbmBrand != NULL )
  259. {
  260. if ( nResIdBmp == m_nResId )
  261. {
  262. // The current bitmap is compatible with new display setting.
  263. fRet = TRUE;
  264. goto Exit;
  265. }
  266. m_nResId = nResIdBmp;
  267. ::DeleteObject( m_hbmBrand );
  268. }
  269. hbmBrand = (HBITMAP)::LoadImage( g_hInst, MAKEINTRESOURCE(nResIdBmp),
  270. IMAGE_BITMAP, 0, 0, 0 );
  271. if ( hbmBrand == NULL )
  272. {
  273. cszErr = ::GetSysErrStr();
  274. ErrorTrace(0, "::LoadImage(%d) failed - %ls", nResIdBmp, cszErr);
  275. goto Exit;
  276. }
  277. // Get dimension of the bitmap.
  278. ::GetObject( hbmBrand, sizeof(bm), &bm );
  279. // Static control does not support RTL layout. Mirror the bitmap if necessary.
  280. if ( ( ::GetWindowLong( hDlg, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL ) != 0 )
  281. {
  282. HDC hDCSrc, hDCDst;
  283. HBITMAP hbmRTL;
  284. hDC = ::CreateCompatibleDC( NULL );
  285. hDCSrc = ::CreateCompatibleDC( hDC );
  286. hDCDst = ::CreateCompatibleDC( hDC );
  287. hbmRTL = ::CreateBitmapIndirect( &bm );
  288. ::SelectObject( hDCSrc, hbmBrand );
  289. ::SelectObject( hDCDst, hbmRTL );
  290. ::StretchBlt( hDCDst, 0, 0, bm.bmWidth, bm.bmHeight,
  291. hDCSrc, bm.bmWidth-1, 0, -bm.bmWidth, bm.bmHeight,
  292. SRCCOPY );
  293. ::DeleteDC( hDCDst );
  294. ::DeleteDC( hDCSrc );
  295. ::DeleteDC( hDC );
  296. ::DeleteObject( hbmBrand );
  297. m_hbmBrand = hbmRTL;
  298. }
  299. else
  300. {
  301. m_hbmBrand = hbmBrand;
  302. }
  303. // Get dimension of the static control.
  304. hwndBmp = ::GetDlgItem( hDlg, IDC_PROGDLG_BITMAP );
  305. ::GetWindowRect( hwndBmp, &rcCtrl );
  306. ::MapWindowPoints( NULL, hDlg, (LPPOINT)&rcCtrl, 2 );
  307. // Set the image.
  308. ::SendMessage( hwndBmp, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_hbmBrand );
  309. // Set width of the static control.
  310. ::SetWindowPos( hwndBmp, NULL,
  311. rcCtrl.left,
  312. (rcCtrl.bottom-rcCtrl.top-bm.bmHeight)/2+rcCtrl.top,
  313. bm.bmWidth,
  314. bm.bmHeight,
  315. SWP_NOZORDER );
  316. fRet = TRUE;
  317. Exit:
  318. TraceFunctLeave();
  319. return( fRet );
  320. }
  321. /////////////////////////////////////////////////////////////////////////////
  322. // CRestoreProgressWindow operations - dialog procedure
  323. INT_PTR CALLBACK
  324. CRestoreProgressWindow::ExtDlgProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam )
  325. {
  326. TraceFunctEnter("CRestoreProgressWindow::ExtDlgProc");
  327. int nRet = FALSE;
  328. CRestoreProgressWindow *pProgWnd;
  329. if ( wMsg == WM_INITDIALOG )
  330. {
  331. ::SetWindowLong( hDlg, DWL_USER, lParam );
  332. pProgWnd = (CRestoreProgressWindow*)lParam;
  333. }
  334. else
  335. {
  336. pProgWnd = (CRestoreProgressWindow*)::GetWindowLong( hDlg, DWL_USER );
  337. if ( pProgWnd == NULL )
  338. goto Exit;
  339. }
  340. nRet = pProgWnd->RPWDlgProc( hDlg, wMsg, wParam, lParam );
  341. Exit:
  342. TraceFunctLeave();
  343. return( nRet );
  344. }
  345. /////////////////////////////////////////////////////////////////////////////
  346. int
  347. CRestoreProgressWindow::RPWDlgProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam )
  348. {
  349. TraceFunctEnter("CRestoreProgressWindow::RPWDlgProc");
  350. int nRet = FALSE;
  351. HFONT hFont;
  352. LOGFONT lf;
  353. HDC hDC;
  354. RECT rcClient;
  355. UINT uID;
  356. HBRUSH hbrTitle;
  357. switch ( wMsg )
  358. {
  359. case WM_INITDIALOG :
  360. m_hWnd = hDlg;
  361. // Create a large font for branding title.
  362. hFont = (HFONT)::SendDlgItemMessage( hDlg, IDC_PROGDLG_TITLE, WM_GETFONT, 0, 0 );
  363. ::GetObject( hFont, sizeof(lf), &lf );
  364. hDC = ::GetDC( hDlg );
  365. lf.lfHeight = 0 - ( ::GetDeviceCaps( hDC, LOGPIXELSY ) * 12 / 72 );
  366. lf.lfWeight = FW_BOLD;
  367. ::ReleaseDC( hDlg, hDC );
  368. m_hFntTitle = ::CreateFontIndirect( &lf );
  369. ::SendDlgItemMessage( hDlg, IDC_PROGDLG_TITLE, WM_SETFONT, (WPARAM)m_hFntTitle, FALSE );
  370. // Load branding bitmap.
  371. LoadAndSetBrandBitmap( hDlg );
  372. // Get width of the progress bar.
  373. ::GetClientRect( ::GetDlgItem( hDlg, IDC_PROGDLG_BAR ), &rcClient );
  374. m_cxBar = rcClient.right - rcClient.left;
  375. m_cxBarReal = m_cxBar * ( PROGBAR_POS_SNAPSHOT - PROGBAR_POS_RESTORE ) / 100;
  376. // Set range of progress bar so it would exactly match with
  377. // real size, and set initial position to 0.
  378. ::SendDlgItemMessage( hDlg, IDC_PROGDLG_BAR, PBM_SETRANGE32, 0, m_cxBar );
  379. ::SendDlgItemMessage( hDlg, IDC_PROGDLG_BAR, PBM_SETPOS, 0, 0 );
  380. break;
  381. case WM_CLOSE :
  382. if ( !::DestroyWindow( hDlg ) )
  383. {
  384. LPCWSTR cszErr = ::GetSysErrStr();
  385. ErrorTrace(0, "::DestroyWindow failed - %ls", cszErr);
  386. goto Exit;
  387. }
  388. ::SetWindowLong( hDlg, DWL_MSGRESULT, 1 );
  389. break;
  390. case WM_CTLCOLORSTATIC :
  391. uID = ::GetWindowLong( (HWND)lParam, GWL_ID );
  392. if ( ( uID == IDC_PROGDLG_BITMAP ) || ( uID == IDC_PROGDLG_TITLE ) )
  393. {
  394. ::SetBkMode( (HDC)wParam, TRANSPARENT );
  395. hbrTitle = (HBRUSH)::GetStockObject( NULL_BRUSH );
  396. }
  397. else
  398. hbrTitle = NULL;
  399. nRet = (int)hbrTitle;
  400. goto Exit;
  401. case WM_DISPLAYCHANGE :
  402. LoadAndSetBrandBitmap( hDlg );
  403. break;
  404. case WM_DESTROY :
  405. ::PostQuitMessage( 0 );
  406. break;
  407. default:
  408. goto Exit;
  409. }
  410. nRet = TRUE;
  411. Exit:
  412. TraceFunctLeave();
  413. return( nRet );
  414. }
  415. /////////////////////////////////////////////////////////////////////////////
  416. //
  417. // CreateRestoreProgressWindow function
  418. //
  419. /////////////////////////////////////////////////////////////////////////////
  420. BOOL
  421. CreateRestoreProgressWindow( CRestoreProgressWindow **ppProgWnd )
  422. {
  423. TraceFunctEnter("CreateRestoreProgressWindow");
  424. BOOL fRet = FALSE;
  425. CRestoreProgressWindow *pProgWnd=NULL;
  426. if ( ppProgWnd == NULL )
  427. {
  428. FatalTrace(0, "Invalid parameter, ppProgWnd is NULL.");
  429. goto Exit;
  430. }
  431. *ppProgWnd = NULL;
  432. pProgWnd = new CRestoreProgressWindow;
  433. if ( pProgWnd == NULL )
  434. {
  435. FatalTrace(0, "Insufficient memory...");
  436. goto Exit;
  437. }
  438. if ( !pProgWnd->Init() )
  439. goto Exit;
  440. *ppProgWnd = pProgWnd;
  441. fRet = TRUE;
  442. Exit:
  443. if ( !fRet )
  444. SAFE_RELEASE(pProgWnd);
  445. TraceFunctLeave();
  446. return( fRet );
  447. }
  448. // end of file