Source code of Windows XP (NT5)
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.

1492 lines
44 KiB

  1. /****************************************************************************
  2. Copyright (c) Microsoft Corporation 1997
  3. All rights reserved
  4. ***************************************************************************/
  5. #include "pch.h"
  6. #include <windowsx.h>
  7. #include <prsht.h>
  8. #include <shlobj.h>
  9. #include <setupapi.h>
  10. #include <pshpack2.h>
  11. #include <poppack.h>
  12. #include <commctrl.h> // includes the common control header
  13. #include "setup.h"
  14. DEFINE_MODULE("Dialogs");
  15. #define WIZPAGE_FULL_PAGE_WATERMARK 0x00000001
  16. #define WIZPAGE_SEPARATOR_CREATED 0x00000002
  17. #define SMALL_BUFFER_SIZE 256
  18. #define BITMAP_WIDTH 16
  19. #define BITMAP_HEIGHT 16
  20. #define LG_BITMAP_WIDTH 32
  21. #define LG_BITMAP_HEIGHT 32
  22. //
  23. // Stuff used for watermarking
  24. //
  25. CONST BITMAPINFOHEADER *g_pbihWatermark;
  26. PVOID g_pWatermarkBitmapBits;
  27. HPALETTE g_hWatermarkPalette;
  28. INT g_uWatermarkPaletteColorCount;
  29. WNDPROC g_OldWizardProc;
  30. //
  31. // Enum for SetDialogFont().
  32. //
  33. typedef enum {
  34. DlgFontTitle,
  35. DlgFontBold
  36. } MyDlgFont;
  37. VOID
  38. SetDialogFont(
  39. IN HWND hdlg,
  40. IN UINT ControlId,
  41. IN MyDlgFont WhichFont
  42. )
  43. {
  44. static HFONT BigBoldFont = NULL;
  45. static HFONT BoldFont = NULL;
  46. static HFONT NormalFont = NULL;
  47. HFONT Font;
  48. LOGFONT LogFont;
  49. TCHAR FontSizeString[24];
  50. int FontSize;
  51. HDC hdc;
  52. DWORD dw;
  53. switch(WhichFont) {
  54. case DlgFontTitle:
  55. if(!BigBoldFont) {
  56. if ( Font =
  57. (HFONT) SendDlgItemMessage( hdlg, ControlId, WM_GETFONT, 0, 0) )
  58. {
  59. if ( GetObject( Font, sizeof(LOGFONT), &LogFont) )
  60. {
  61. dw = LoadString( g_hinstance,
  62. IDS_LARGEFONTNAME,
  63. LogFont.lfFaceName,
  64. LF_FACESIZE);
  65. Assert( dw );
  66. LogFont.lfWeight = 700;
  67. FontSize = 15;
  68. if ( hdc = GetDC(hdlg) )
  69. {
  70. LogFont.lfHeight =
  71. 0 - (GetDeviceCaps(hdc,LOGPIXELSY) * FontSize / 72);
  72. BigBoldFont = CreateFontIndirect(&LogFont);
  73. ReleaseDC(hdlg,hdc);
  74. }
  75. }
  76. }
  77. }
  78. Font = BigBoldFont;
  79. break;
  80. case DlgFontBold:
  81. if ( !BoldFont )
  82. {
  83. if ( Font =
  84. (HFONT) SendDlgItemMessage( hdlg, ControlId, WM_GETFONT, 0, 0 ))
  85. {
  86. if ( GetObject( Font, sizeof(LOGFONT), &LogFont ) )
  87. {
  88. LogFont.lfWeight = FW_BOLD;
  89. if ( hdc = GetDC( hdlg ) )
  90. {
  91. BoldFont = CreateFontIndirect( &LogFont );
  92. ReleaseDC( hdlg, hdc );
  93. }
  94. }
  95. }
  96. }
  97. Font = BoldFont;
  98. break;
  99. default:
  100. //
  101. // Nothing to do here.
  102. //
  103. Font = NULL;
  104. break;
  105. }
  106. if( Font )
  107. {
  108. SendDlgItemMessage( hdlg, ControlId, WM_SETFONT, (WPARAM) Font, 0 );
  109. }
  110. }
  111. //
  112. // Paints the watermark.
  113. //
  114. BOOL
  115. PaintWatermark(
  116. IN HWND hdlg,
  117. IN HDC DialogDC,
  118. IN UINT XOffset,
  119. IN UINT YOffset,
  120. IN UINT YHeight )
  121. {
  122. HPALETTE OldPalette;
  123. RECT rect;
  124. int Height;
  125. int Width;
  126. OldPalette = SelectPalette( DialogDC, g_hWatermarkPalette, TRUE );
  127. Width = g_pbihWatermark->biWidth - ( 2 * XOffset );
  128. Height = ( YHeight ? YHeight : g_pbihWatermark->biHeight ) - YOffset;
  129. SetDIBitsToDevice(
  130. DialogDC,
  131. 0,
  132. 0,
  133. Width,
  134. Height,
  135. XOffset,
  136. YHeight ? ( g_pbihWatermark->biHeight - YHeight ) : YHeight,
  137. 0, g_pbihWatermark->biHeight,
  138. g_pWatermarkBitmapBits,
  139. (BITMAPINFO *) g_pbihWatermark,
  140. DIB_RGB_COLORS );
  141. GetClientRect( hdlg, &rect );
  142. if ( Height && Height < rect.bottom )
  143. {
  144. ExcludeClipRect( DialogDC, 0, 0, Width + 2 * XOffset, Height );
  145. return FALSE;
  146. }
  147. return TRUE;
  148. }
  149. //
  150. // Paints the watermark background within an HWND
  151. //
  152. BOOL
  153. PaintBackgroundWithWatermark(
  154. HWND hDlg,
  155. HWND hwnd,
  156. HDC hDC )
  157. {
  158. RECT rc1, rc2;
  159. RECT rcDivider;
  160. HWND hwndDivider = GetDlgItem( hDlg, IDC_DIVIDER );
  161. GetClientRect( GetParent( hDlg ), &rc1 );
  162. MapWindowPoints( GetParent( hDlg ), NULL, (POINT *) &rc1, 2 );
  163. GetClientRect( hwnd, &rc2 );
  164. MapWindowPoints( hwnd, NULL, (POINT *) &rc2, 2 );
  165. if ( hwndDivider )
  166. {
  167. GetClientRect( hwndDivider, &rcDivider );
  168. MapWindowPoints( hwndDivider, GetParent( hDlg ),
  169. (POINT *) &rcDivider, 2 );
  170. }
  171. else
  172. {
  173. rcDivider.top = 0;
  174. }
  175. return PaintWatermark( hwnd, hDC, rc2.left-rc1.left,
  176. rc2.top-rc1.top, rcDivider.top );
  177. }
  178. //
  179. // Check to see if the directory exists. If not, ask the user if we
  180. // should create it.
  181. //
  182. BOOL
  183. CheckDirectory( HWND hDlg, LPTSTR pszPath, BOOL fAllowCreate )
  184. {
  185. BOOL fReturn = FALSE;
  186. WIN32_FILE_ATTRIBUTE_DATA fad;
  187. DWORD dwAttrib = GetFileAttributes( pszPath );
  188. if ( dwAttrib == 0xFFFFffff )
  189. {
  190. if ( ERROR_FILE_NOT_FOUND == GetLastError( ) )
  191. {
  192. if ( fAllowCreate &&
  193. IDYES == MessageBoxFromStrings( hDlg, IDS_CREATEDIRCAPTION, IDS_CREATEDIRTEXT, MB_YESNO ) )
  194. {
  195. g_Options.fCreateDirectory = TRUE;
  196. fReturn = TRUE;
  197. goto Cleanup;
  198. }
  199. else if ( !fAllowCreate )
  200. {
  201. MessageBoxFromStrings( hDlg, IDS_DIRDOESNOTEXISTCAPTION, IDS_DIRDOESNOTEXISTTEXT, MB_OK );
  202. }
  203. }
  204. goto Cleanup;
  205. }
  206. fReturn = TRUE;
  207. Cleanup:
  208. SetWindowLong( hDlg, DWL_MSGRESULT, (fReturn ? 0 : -1 ) );
  209. return fReturn;
  210. }
  211. //
  212. // Adjusts and draws a bitmap transparently in the RECT prc.
  213. //
  214. void DrawBitmap(
  215. HANDLE hBitmap,
  216. LPDRAWITEMSTRUCT lpdis,
  217. LPRECT prc )
  218. {
  219. BITMAP bm;
  220. HDC hDCBitmap;
  221. int dy;
  222. GetObject( hBitmap, sizeof(bm), &bm );
  223. hDCBitmap = CreateCompatibleDC( NULL );
  224. SelectObject( hDCBitmap, hBitmap );
  225. // center the image
  226. dy = 2 + prc->bottom - bm.bmHeight;
  227. StretchBlt( lpdis->hDC, prc->left, prc->top + dy, prc->right, prc->bottom,
  228. hDCBitmap, 0, 0, bm.bmWidth, bm.bmHeight, SRCAND );
  229. DeleteDC( hDCBitmap );
  230. }
  231. //
  232. // Draws a bitmap transparently in reponse to a WM_DRAWITEM
  233. //
  234. void
  235. DrawBitmap(
  236. HANDLE hBitmap,
  237. LPDRAWITEMSTRUCT lpdis )
  238. {
  239. HDC hDCBitmap;
  240. hDCBitmap = CreateCompatibleDC( NULL );
  241. SelectObject( hDCBitmap, hBitmap );
  242. BitBlt( lpdis->hDC, 0, 0, lpdis->rcItem.right, lpdis->rcItem.bottom,
  243. hDCBitmap, 0, 0, SRCAND );
  244. DeleteDC( hDCBitmap );
  245. }
  246. //
  247. // Verifies that the user wanted to cancel setup.
  248. //
  249. BOOL
  250. VerifyCancel( HWND hParent )
  251. {
  252. TCHAR szText[ SMALL_BUFFER_SIZE ];
  253. TCHAR szCaption[ SMALL_BUFFER_SIZE ];
  254. dw = LoadString( g_hinstance, IDS_CANCELCAPTION, szCaption,
  255. ARRAYSIZE( szCaption ));
  256. Assert( dw );
  257. dw = LoadString( g_hinstance, IDS_CANCELTEXT, szText,
  258. ARRAYSIZE( szText ));
  259. Assert( dw );
  260. g_Options.fAbort =
  261. ( IDYES == MessageBoxFromStrings( hParent,
  262. IDS_CANCELCAPTION,
  263. IDS_CANCELTEXT,
  264. MB_YESNO ) );
  265. SetWindowLong( hParent, DWL_MSGRESULT, ( g_Options.fAbort ? 0 : - 1 ) );
  266. return !g_Options.fAbort;
  267. }
  268. //
  269. // Base dialog proc - all unhandled calls are passed here. If they are not
  270. // handled here, then the default dialog proc will handle them.
  271. //
  272. BOOL CALLBACK
  273. BaseDlgProc(
  274. HWND hDlg,
  275. UINT uMsg,
  276. WPARAM wParam,
  277. LPARAM lParam )
  278. {
  279. NMHDR FAR *lpnmhdr;
  280. switch ( uMsg )
  281. {
  282. case WM_INITDIALOG:
  283. SetDialogFont( hDlg, IDC_S_TITLE1, DlgFontTitle );
  284. //SetDialogFont( hDlg, IDC_S_TITLE2, DlgFontTitle );
  285. //SetDialogFont( hDlg, IDC_S_TITLE3, DlgFontTitle );
  286. SetDialogFont( hDlg, IDC_S_BOLD1, DlgFontBold );
  287. SetDialogFont( hDlg, IDC_S_BOLD2, DlgFontBold );
  288. SetDialogFont( hDlg, IDC_S_BOLD3, DlgFontBold );
  289. break;
  290. case WM_DRAWITEM:
  291. if ( LOWORD( wParam ) >= IDC_I_BUTTON1 &&
  292. LOWORD( wParam ) <= IDC_I_BUTTON7 )
  293. DrawBitmap( g_hGraphic, (LPDRAWITEMSTRUCT) lParam );
  294. break;
  295. case WM_PALETTECHANGED:
  296. if ((HWND)wParam != hDlg)
  297. {
  298. InvalidateRect(hDlg, NULL, NULL);
  299. UpdateWindow(hDlg);
  300. }
  301. break;
  302. case WM_ERASEBKGND:
  303. return PaintBackgroundWithWatermark( hDlg, hDlg, (HDC) wParam );
  304. case WM_CTLCOLORSTATIC:
  305. if ( LOWORD( wParam ) == IDC_DIVIDER )
  306. {
  307. return FALSE;
  308. }
  309. else
  310. {
  311. // erase background
  312. PaintBackgroundWithWatermark( hDlg, (HWND) lParam, (HDC) wParam );
  313. // setup transparent mode
  314. SetBkMode( (HDC) wParam, TRANSPARENT );
  315. SetBkColor( (HDC) wParam, GetSysColor( COLOR_3DFACE ) );
  316. return( (BOOL) GetStockObject( HOLLOW_BRUSH ) );
  317. }
  318. break;
  319. default:
  320. return FALSE;
  321. }
  322. return TRUE;
  323. }
  324. //
  325. // "Welcome's" (the first page's) dialog proc.
  326. //
  327. BOOL CALLBACK
  328. WelcomeDlgProc(
  329. HWND hDlg,
  330. UINT uMsg,
  331. WPARAM wParam,
  332. LPARAM lParam )
  333. {
  334. NMHDR FAR *lpnmhdr;
  335. static BOOL fFirstTime = FALSE;
  336. switch ( uMsg )
  337. {
  338. case WM_INITDIALOG:
  339. CenterDialog( GetParent( hDlg ) );
  340. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  341. case WM_NOTIFY:
  342. lpnmhdr = (NMHDR FAR *) lParam;
  343. switch ( lpnmhdr->code )
  344. {
  345. // ignore these
  346. case PSN_KILLACTIVE:
  347. case PSN_WIZNEXT:
  348. case PSN_WIZBACK:
  349. case PSN_RESET:
  350. SetWindowLong( hDlg, DWL_MSGRESULT, FALSE );
  351. break;
  352. case PSN_QUERYCANCEL:
  353. return VerifyCancel( hDlg );
  354. break;
  355. case PSN_SETACTIVE:
  356. PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT );
  357. ClearMessageQueue( );
  358. // eliminate flicker
  359. if ( !fFirstTime )
  360. {
  361. fFirstTime = TRUE;
  362. }
  363. else
  364. {
  365. PostMessage( GetParent(hDlg), WMX_FORCEDREPAINT, 0, NULL );
  366. }
  367. break;
  368. case PSN_HELP:
  369. //
  370. // TODO: Add help
  371. //
  372. break;
  373. default:
  374. AssertMsg( FALSE, "Unhandled PSN message" );
  375. return FALSE;
  376. }
  377. break;
  378. default:
  379. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  380. }
  381. return TRUE;
  382. }
  383. //
  384. // Remote Boot Directory dialog proc.
  385. //
  386. BOOL CALLBACK
  387. RemoteBootDlgProc(
  388. HWND hDlg,
  389. UINT uMsg,
  390. WPARAM wParam,
  391. LPARAM lParam )
  392. {
  393. NMHDR FAR *lpnmhdr;
  394. DWORD dw;
  395. switch ( uMsg )
  396. {
  397. case WM_INITDIALOG:
  398. Edit_SetText( GetDlgItem( hDlg, IDC_E_RBPATH), g_Options.szRemoteBootPath );
  399. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  400. case WM_NOTIFY:
  401. lpnmhdr = (NMHDR FAR *) lParam;
  402. switch ( lpnmhdr->code )
  403. {
  404. // ignore these
  405. case PSN_WIZBACK:
  406. case PSN_KILLACTIVE:
  407. case PSN_RESET:
  408. SetWindowLong( hDlg, DWL_MSGRESULT, FALSE );
  409. break;
  410. case PSN_WIZNEXT:
  411. Edit_GetText( GetDlgItem( hDlg, IDC_E_RBPATH ), g_Options.szRemoteBootPath, ARRAYSIZE( g_Options.szRemoteBootPath ));
  412. g_Options.fCreateDirectory = FALSE;
  413. CheckDirectory( hDlg, g_Options.szRemoteBootPath, TRUE );
  414. break;
  415. case PSN_QUERYCANCEL:
  416. return VerifyCancel( hDlg );
  417. break;
  418. case PSN_SETACTIVE:
  419. if ( g_Options.fError || g_Options.fKnowRBDirectory )
  420. {
  421. SetWindowLong( hDlg, DWL_MSGRESULT, -1 ); // do not show this page
  422. }
  423. else
  424. {
  425. DWORD dwLen = Edit_GetTextLength( GetDlgItem( hDlg, IDC_E_RBPATH) );
  426. PropSheet_SetWizButtons( GetParent( hDlg ),
  427. dwLen ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK );
  428. ClearMessageQueue( );
  429. PostMessage( GetParent(hDlg), WMX_FORCEDREPAINT, 0, (LPARAM) GetDlgItem( hDlg, IDC_DIVIDER ) );
  430. }
  431. break;
  432. case PSN_HELP:
  433. //
  434. // TODO: Add help
  435. //
  436. break;
  437. default:
  438. AssertMsg( FALSE, "Unhandled PSN message" );
  439. return FALSE;
  440. }
  441. break;
  442. case WM_COMMAND:
  443. switch( LOWORD( wParam))
  444. {
  445. case IDC_E_RBPATH:
  446. {
  447. if ( HIWORD(wParam) == EN_CHANGE )
  448. {
  449. DWORD dwLen = Edit_GetTextLength( GetDlgItem( hDlg, IDC_E_RBPATH) );
  450. PropSheet_SetWizButtons( GetParent( hDlg ),
  451. dwLen ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK );
  452. }
  453. }
  454. break;
  455. case IDC_B_BROWSE:
  456. {
  457. TCHAR szTitle[ SMALL_BUFFER_SIZE ];
  458. BROWSEINFO bs;
  459. ZeroMemory( &bs, sizeof(bs) );
  460. bs.hwndOwner = hDlg;
  461. dw = LoadString( g_hinstance, IDS_BROWSECAPTION_RBDIR, szTitle, ARRAYSIZE( szTitle ) );
  462. Assert( dw );
  463. bs.lpszTitle = (LPTSTR) &szTitle;
  464. bs.ulFlags = BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS;
  465. LPITEMIDLIST pidl = SHBrowseForFolder( &bs );
  466. SHGetPathFromIDList( pidl, g_Options.szRemoteBootPath );
  467. Edit_SetText( GetDlgItem( hDlg, IDC_E_RBPATH ), g_Options.szRemoteBootPath );
  468. }
  469. break;
  470. default:
  471. break;
  472. }
  473. break;
  474. default:
  475. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  476. }
  477. return TRUE;
  478. }
  479. //
  480. // OS Name dialog proc.
  481. //
  482. BOOL CALLBACK
  483. OSDlgProc(
  484. HWND hDlg,
  485. UINT uMsg,
  486. WPARAM wParam,
  487. LPARAM lParam )
  488. {
  489. NMHDR FAR *lpnmhdr;
  490. switch ( uMsg )
  491. {
  492. case WM_INITDIALOG:
  493. Edit_SetText( GetDlgItem( hDlg, IDC_E_OSNAME ), g_Options.szName );
  494. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  495. case WM_NOTIFY:
  496. lpnmhdr = (NMHDR FAR *) lParam;
  497. switch ( lpnmhdr->code )
  498. {
  499. // ignore these
  500. case PSN_KILLACTIVE:
  501. case PSN_WIZBACK:
  502. case PSN_RESET:
  503. SetWindowLong( hDlg, DWL_MSGRESULT, FALSE );
  504. break;
  505. case PSN_WIZNEXT:
  506. Edit_GetText( GetDlgItem( hDlg, IDC_E_OSNAME ), g_Options.szName, ARRAYSIZE( g_Options.szName ) );
  507. break;
  508. case PSN_QUERYCANCEL:
  509. return VerifyCancel( hDlg );
  510. break;
  511. case PSN_SETACTIVE:
  512. {
  513. if ( g_Options.fError )
  514. {
  515. SetWindowLong( hDlg, DWL_MSGRESULT, -1 ); // do not show this page
  516. }
  517. DWORD dwLen = Edit_GetTextLength( GetDlgItem( hDlg, IDC_E_OSNAME) );
  518. PropSheet_SetWizButtons( GetParent( hDlg ),
  519. dwLen ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK );
  520. ClearMessageQueue( );
  521. PostMessage( GetParent(hDlg), WMX_FORCEDREPAINT, 0, (LPARAM) GetDlgItem( hDlg, IDC_DIVIDER ) );
  522. }
  523. break;
  524. case PSN_HELP:
  525. //
  526. // TODO: Add help
  527. //
  528. break;
  529. default:
  530. AssertMsg( FALSE, "Unhandled PSN message" );
  531. return FALSE;
  532. }
  533. break;
  534. case WM_COMMAND:
  535. switch( LOWORD( wParam))
  536. {
  537. case IDC_E_OSNAME:
  538. {
  539. if ( HIWORD(wParam) == EN_CHANGE )
  540. {
  541. DWORD dwLen = Edit_GetTextLength( GetDlgItem( hDlg, IDC_E_OSNAME ) );
  542. PropSheet_SetWizButtons( GetParent( hDlg ),
  543. dwLen ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK );
  544. }
  545. }
  546. break;
  547. }
  548. break;
  549. default:
  550. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  551. }
  552. return TRUE;
  553. }
  554. //
  555. // Remote Boot Directory dialog proc.
  556. //
  557. BOOL CALLBACK
  558. SourceDlgProc(
  559. HWND hDlg,
  560. UINT uMsg,
  561. WPARAM wParam,
  562. LPARAM lParam )
  563. {
  564. NMHDR FAR *lpnmhdr;
  565. DWORD dw;
  566. switch ( uMsg )
  567. {
  568. case WM_INITDIALOG:
  569. Edit_SetText( GetDlgItem( hDlg, IDC_E_SOURCEPATH ), g_Options.szSourcePath );
  570. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  571. case WM_NOTIFY:
  572. lpnmhdr = (NMHDR FAR *) lParam;
  573. switch ( lpnmhdr->code )
  574. {
  575. // ignore these
  576. case PSN_KILLACTIVE:
  577. case PSN_WIZBACK:
  578. case PSN_RESET:
  579. SetWindowLong( hDlg, DWL_MSGRESULT, FALSE );
  580. break;
  581. case PSN_WIZNEXT:
  582. {
  583. DWORD dwLen;
  584. Edit_GetText( GetDlgItem( hDlg, IDC_E_SOURCEPATH ), g_Options.szSourcePath, ARRAYSIZE( g_Options.szSourcePath ) );
  585. dwLen = lstrlen( g_Options.szSourcePath ) - 1;
  586. if ( g_Options.szSourcePath[ dwLen ] == TEXT('\\') )
  587. {
  588. g_Options.szSourcePath[ dwLen ] = 0;
  589. }
  590. if ( CheckDirectory( hDlg, g_Options.szSourcePath, FALSE ) )
  591. {
  592. HANDLE hFile;
  593. hFile = OpenLayoutInf( );
  594. if ( hFile == INVALID_HANDLE_VALUE )
  595. {
  596. MessageBoxFromStrings( hDlg, IDS_INVALIDSOURCECAPTION, IDS_INVALIDSOURCETEXT, MB_OK );
  597. SetWindowLong( hDlg, DWL_MSGRESULT, -1 );
  598. }
  599. else
  600. {
  601. SetupCloseInfFile( hFile );
  602. }
  603. }
  604. g_Options.fIntel =
  605. ( ( 0x0003 & Button_GetState( GetDlgItem( hDlg, IDC_C_INTEL ) ) ) ==
  606. BST_CHECKED );
  607. g_Options.fAlpha =
  608. ( ( 0x0003 & Button_GetState( GetDlgItem( hDlg, IDC_C_ALPHA ) ) ) ==
  609. BST_CHECKED );
  610. }
  611. break;
  612. case PSN_QUERYCANCEL:
  613. return VerifyCancel( hDlg );
  614. break;
  615. case PSN_SETACTIVE:
  616. {
  617. PostMessage( GetParent(hDlg), WMX_FORCEDREPAINT, 0, (LPARAM) GetDlgItem( hDlg, IDC_DIVIDER ) );
  618. DWORD dwLen = Edit_GetTextLength( GetDlgItem( hDlg, IDC_E_SOURCEPATH) );
  619. PropSheet_SetWizButtons( GetParent( hDlg ),
  620. dwLen ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK );
  621. ClearMessageQueue( );
  622. }
  623. break;
  624. case PSN_HELP:
  625. //
  626. // TODO: Add help
  627. //
  628. break;
  629. default:
  630. AssertMsg( FALSE, "Unhandled PSN message" );
  631. return FALSE;
  632. }
  633. break;
  634. case WM_COMMAND:
  635. switch( LOWORD( wParam))
  636. {
  637. case IDC_E_SOURCEPATH:
  638. if ( HIWORD(wParam) != EN_CHANGE )
  639. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  640. // fall thru...
  641. case IDC_C_INTEL:
  642. case IDC_C_ALPHA:
  643. {
  644. g_Options.fIntel =
  645. ( ( 0x0003 & Button_GetState( GetDlgItem( hDlg, IDC_C_INTEL ) ) ) ==
  646. BST_CHECKED );
  647. g_Options.fAlpha =
  648. ( ( 0x0003 & Button_GetState( GetDlgItem( hDlg, IDC_C_ALPHA ) ) ) ==
  649. BST_CHECKED );
  650. DWORD dwLen = Edit_GetTextLength( GetDlgItem( hDlg, IDC_E_SOURCEPATH ) );
  651. PropSheet_SetWizButtons( GetParent( hDlg ),
  652. ( dwLen && ( g_Options.fIntel || g_Options.fAlpha )) ?
  653. PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK );
  654. }
  655. break;
  656. case IDC_B_BROWSE:
  657. {
  658. TCHAR szTitle[ SMALL_BUFFER_SIZE ];
  659. BROWSEINFO bs;
  660. ZeroMemory( &bs, sizeof(bs) );
  661. bs.hwndOwner = hDlg;
  662. dw = LoadString( g_hinstance, IDS_BROWSECAPTION_SOURCEDIR, szTitle, ARRAYSIZE( szTitle ) );
  663. Assert( dw );
  664. bs.lpszTitle = (LPTSTR) &szTitle;
  665. bs.ulFlags = BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS;
  666. LPITEMIDLIST pidl = SHBrowseForFolder( &bs );
  667. SHGetPathFromIDList( pidl, g_Options.szSourcePath );
  668. Edit_SetText( GetDlgItem( hDlg, IDC_E_SOURCEPATH ), g_Options.szSourcePath );
  669. }
  670. break;
  671. default:
  672. break;
  673. }
  674. break;
  675. case WM_CTLCOLORSTATIC:
  676. if ( (HWND) lParam != GetDlgItem( hDlg, IDC_C_INTEL ) &&
  677. (HWND) lParam != GetDlgItem( hDlg, IDC_C_ALPHA) )
  678. {
  679. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  680. }
  681. return FALSE;
  682. default:
  683. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  684. }
  685. return TRUE;
  686. }
  687. //
  688. // Information dialog proc.
  689. //
  690. BOOL CALLBACK
  691. InfoDlgProc(
  692. HWND hDlg,
  693. UINT uMsg,
  694. WPARAM wParam,
  695. LPARAM lParam )
  696. {
  697. NMHDR FAR *lpnmhdr;
  698. DWORD dw;
  699. switch ( uMsg )
  700. {
  701. case WM_INITDIALOG:
  702. {
  703. TCHAR szText[ SMALL_BUFFER_SIZE ] = { 0 };
  704. DWORD dwLen = 0;
  705. if ( g_Options.fIntel )
  706. {
  707. dw = LoadString( g_hinstance, IDS_INTEL, szText, ARRAYSIZE( szText ) );
  708. Assert( dw );
  709. if ( g_Options.fAlpha )
  710. {
  711. dwLen = lstrlen( szText );
  712. szText[ dwLen++ ] = TEXT(' ');
  713. dw = LoadString( g_hinstance, IDS_AND, &szText[ dwLen ], ARRAYSIZE( szText ) - dwLen );
  714. Assert( dw );
  715. dwLen = lstrlen( szText );
  716. szText[ dwLen++ ] = TEXT(' ');
  717. }
  718. }
  719. if ( g_Options.fAlpha )
  720. {
  721. dw = LoadString( g_hinstance, IDS_ALPHA, &szText[ dwLen ], ARRAYSIZE( szText ) - dwLen );
  722. Assert( dw );
  723. }
  724. SetDlgItemInt( hDlg, IDC_S_CLIENTS, 70, FALSE );
  725. SetDlgItemText( hDlg, IDC_S_SOURCEPATH, g_Options.szSourcePath );
  726. SetDlgItemText( hDlg, IDC_S_PLATFORM, szText );
  727. SetDlgItemText( hDlg, IDC_S_REMOTEBOOT, g_Options.szRemoteBootPath );
  728. }
  729. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  730. case WM_NOTIFY:
  731. lpnmhdr = (NMHDR FAR *) lParam;
  732. switch ( lpnmhdr->code )
  733. {
  734. // ignore these
  735. case PSN_KILLACTIVE:
  736. case PSN_WIZNEXT:
  737. case PSN_WIZBACK:
  738. case PSN_RESET:
  739. SetWindowLong( hDlg, DWL_MSGRESULT, FALSE );
  740. break;
  741. case PSN_QUERYCANCEL:
  742. return VerifyCancel( hDlg );
  743. break;
  744. case PSN_SETACTIVE:
  745. if ( g_Options.fError )
  746. {
  747. SetWindowLong( hDlg, DWL_MSGRESULT, -1 ); // do not show this page
  748. }
  749. PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT | PSWIZB_BACK);
  750. ClearMessageQueue( );
  751. PostMessage( GetParent(hDlg), WMX_FORCEDREPAINT, 0, (LPARAM) GetDlgItem( hDlg, IDC_DIVIDER ) );
  752. break;
  753. case PSN_HELP:
  754. //
  755. // TODO: Add help
  756. //
  757. break;
  758. default:
  759. AssertMsg( FALSE, "Unhandled PSN message" );
  760. return FALSE;
  761. }
  762. break;
  763. default:
  764. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  765. }
  766. return TRUE;
  767. }
  768. enum { STATE_NOTSTARTED, STATE_STARTED, STATE_DONE, STATE_ERROR };
  769. typedef HRESULT (*PFNOPERATION)( HWND hDlg );
  770. typedef struct {
  771. HANDLE hChecked;
  772. HANDLE hError;
  773. HANDLE hArrow;
  774. HANDLE hFontNormal;
  775. HANDLE hFontBold;
  776. int dwWidth;
  777. int dwHeight;
  778. } SETUPDLGDATA, *LPSETUPDLGDATA;
  779. typedef struct {
  780. UINT uState;
  781. UINT rsrcId;
  782. PFNOPERATION pfn;
  783. TCHAR szText[ SMALL_BUFFER_SIZE ];
  784. } LBITEMDATA, *LPLBITEMDATA;
  785. LBITEMDATA items[] = {
  786. { STATE_NOTSTARTED, IDS_CREATINGDIRECTORYTREE, CreateDirectories, TEXT("") },
  787. { STATE_NOTSTARTED, IDS_COPYINGFILES, CopyFiles, TEXT("") },
  788. { STATE_NOTSTARTED, IDS_UPDATINGREGISTRY, ModifyRegistry, TEXT("") },
  789. { STATE_NOTSTARTED, IDS_STARTING_SERVICES, StartRemoteBootServices, TEXT("") },
  790. { STATE_NOTSTARTED, IDS_CREATINGSHARES, CreateRemoteBootShare, TEXT("") }
  791. };
  792. //
  793. // Setup dialog proc.
  794. //
  795. BOOL CALLBACK
  796. SetupDlgProc(
  797. HWND hDlg,
  798. UINT uMsg,
  799. WPARAM wParam,
  800. LPARAM lParam )
  801. {
  802. static BOOL bDoneFirstPass;
  803. LPSETUPDLGDATA psdd = (LPSETUPDLGDATA) GetWindowLong( hDlg, GWL_USERDATA );
  804. DWORD dw;
  805. switch ( uMsg )
  806. {
  807. case WM_INITDIALOG:
  808. {
  809. BITMAP bm;
  810. // grab the bitmaps
  811. psdd =
  812. (LPSETUPDLGDATA) TraceAlloc( GMEM_FIXED, sizeof(SETUPDLGDATA) );
  813. psdd->hChecked = LoadImage( g_hinstance,
  814. MAKEINTRESOURCE( IDB_CHECK ),
  815. IMAGE_BITMAP,
  816. 0, 0,
  817. LR_DEFAULTSIZE | LR_LOADTRANSPARENT );
  818. DebugMemoryAddHandle( psdd->hChecked );
  819. GetObject( psdd->hChecked, sizeof(bm), &bm );
  820. psdd->dwWidth = bm.bmWidth;
  821. psdd->hError = LoadImage( g_hinstance,
  822. MAKEINTRESOURCE( IDB_X ),
  823. IMAGE_BITMAP,
  824. 0, 0,
  825. LR_DEFAULTSIZE | LR_LOADTRANSPARENT );
  826. DebugMemoryAddHandle( psdd->hError );
  827. GetObject( psdd->hError, sizeof(bm), &bm );
  828. psdd->dwWidth = ( psdd->dwWidth > bm.bmWidth ? psdd->dwWidth : bm.bmWidth );
  829. psdd->hArrow = LoadImage( g_hinstance,
  830. MAKEINTRESOURCE( IDB_ARROW ),
  831. IMAGE_BITMAP,
  832. 0, 0,
  833. LR_DEFAULTSIZE | LR_LOADTRANSPARENT );
  834. DebugMemoryAddHandle( psdd->hArrow );
  835. GetObject( psdd->hArrow, sizeof(bm), &bm );
  836. psdd->dwWidth = ( psdd->dwWidth > bm.bmWidth ?
  837. psdd->dwWidth :
  838. bm.bmWidth );
  839. HWND hwnd = GetDlgItem( hDlg, IDC_L_SETUP );
  840. HFONT hFontOld = (HFONT) SendMessage( hwnd, WM_GETFONT, 0, 0);
  841. if(hFontOld != NULL)
  842. {
  843. LOGFONT lf;
  844. if ( GetObject( hFontOld, sizeof(LOGFONT), (LPSTR) &lf ) )
  845. {
  846. dw = LoadString( g_hinstance,
  847. IDS_LARGEFONTNAME,
  848. lf.lfFaceName,
  849. LF_FACESIZE );
  850. Assert( dw );
  851. lf.lfWidth = 0;
  852. lf.lfWeight = 400;
  853. lf.lfHeight -= 4;
  854. psdd->hFontNormal = CreateFontIndirect(&lf);
  855. DebugMemoryAddHandle( psdd->hFontNormal );
  856. lf.lfWeight = 700;
  857. psdd->hFontBold = CreateFontIndirect(&lf);
  858. DebugMemoryAddHandle( psdd->hFontBold );
  859. }
  860. }
  861. HDC hDC = GetDC( NULL );
  862. HANDLE hOldFont = SelectObject( hDC, psdd->hFontBold );
  863. TEXTMETRIC tm;
  864. GetTextMetrics( hDC, &tm );
  865. psdd->dwHeight = tm.tmHeight + 2;
  866. SelectObject( hDC, hOldFont );
  867. ReleaseDC( NULL, hDC );
  868. ListBox_SetItemHeight( hwnd, -1, psdd->dwHeight );
  869. SetWindowLong( hDlg, GWL_USERDATA, (LONG) psdd );
  870. for( int i = 0; i < ARRAYSIZE(items); i++ )
  871. {
  872. dw = LoadString( g_hinstance,
  873. items[ i ].rsrcId,
  874. items[ i ].szText,
  875. ARRAYSIZE( items[ i ].szText ) );
  876. Assert( dw );
  877. ListBox_AddString( hwnd, &items[ i ] );
  878. }
  879. bDoneFirstPass = FALSE;
  880. }
  881. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  882. case WM_DESTROY:
  883. {
  884. Assert( psdd );
  885. DeleteObject( psdd->hChecked );
  886. DebugMemoryDelete( psdd->hChecked );
  887. DeleteObject( psdd->hError );
  888. DebugMemoryDelete( psdd->hError );
  889. DeleteObject( psdd->hArrow );
  890. DebugMemoryDelete( psdd->hArrow );
  891. DeleteObject( psdd->hFontNormal );
  892. DebugMemoryDelete( psdd->hFontNormal );
  893. DeleteObject( psdd->hFontBold );
  894. DebugMemoryDelete( psdd->hFontBold );
  895. TraceFree( psdd );
  896. SetWindowLong( hDlg, GWL_USERDATA, NULL );
  897. }
  898. break;
  899. case WM_NOTIFY:
  900. {
  901. NMHDR FAR *lpnmhdr = (NMHDR FAR *) lParam;
  902. switch ( lpnmhdr->code )
  903. {
  904. // ignore these
  905. case PSN_KILLACTIVE:
  906. case PSN_WIZNEXT:
  907. case PSN_WIZBACK:
  908. case PSN_RESET:
  909. SetWindowLong( hDlg, DWL_MSGRESULT, FALSE );
  910. break;
  911. case PSN_QUERYCANCEL:
  912. return VerifyCancel( hDlg );
  913. break;
  914. case PSN_SETACTIVE:
  915. if ( g_Options.fError )
  916. {
  917. SetWindowLong( hDlg, DWL_MSGRESULT, -1 ); // do not show this page
  918. }
  919. PropSheet_SetWizButtons( GetParent( hDlg ), 0 );
  920. PostMessage( GetParent(hDlg), WMX_FORCEDREPAINT, 0, (LPARAM) GetDlgItem( hDlg, IDC_DIVIDER ) );
  921. ClearMessageQueue( );
  922. break;
  923. case PSN_HELP:
  924. //
  925. // TODO: Add help
  926. //
  927. break;
  928. default:
  929. //AssertMsg( FALSE, "Unhandled PSN message" );
  930. return FALSE;
  931. }
  932. }
  933. break;
  934. case WM_STARTSETUP:
  935. {
  936. HWND hwnd = GetDlgItem( hDlg, IDC_L_SETUP );
  937. RECT rc;
  938. GetClientRect( hwnd, &rc );
  939. for( int i = 0; i < ARRAYSIZE( items ) && !g_Options.fError; i++ )
  940. {
  941. items[ i ].uState = STATE_STARTED;
  942. InvalidateRect( hwnd, &rc, TRUE );
  943. items[ i ].uState = items[ i ].pfn( hDlg ) ?
  944. STATE_ERROR : // not S_OK
  945. STATE_DONE; // S_OK
  946. InvalidateRect( hwnd, &rc, TRUE );
  947. }
  948. PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_FINISH );
  949. }
  950. break;
  951. case WM_CTLCOLORLISTBOX:
  952. // cheat by changing the message
  953. return BaseDlgProc( hDlg, WM_CTLCOLORSTATIC, wParam, lParam );
  954. case WM_CTLCOLORSTATIC:
  955. if ( (HWND) lParam != GetDlgItem( hDlg, IDC_S_OPERATION ) &&
  956. (HWND) lParam != GetDlgItem( hDlg, IDC_G_OPERATION ) )
  957. {
  958. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  959. }
  960. return FALSE;
  961. case WM_MEASUREITEM:
  962. {
  963. LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT) lParam;
  964. RECT rc;
  965. HWND hwnd = GetDlgItem( hDlg, IDC_L_SETUP );
  966. GetClientRect( hwnd, &rc );
  967. lpmis->itemWidth = rc.right - rc.left;
  968. lpmis->itemHeight = 15;
  969. }
  970. break;
  971. case WM_DRAWITEM:
  972. {
  973. Assert( psdd );
  974. LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT) lParam;
  975. LPLBITEMDATA plbid = (LPLBITEMDATA) lpdis->itemData;
  976. RECT rc = lpdis->rcItem;
  977. HANDLE hOldFont = INVALID_HANDLE_VALUE;
  978. rc.right = rc.bottom = psdd->dwWidth;
  979. switch ( plbid->uState )
  980. {
  981. case STATE_NOTSTARTED:
  982. hOldFont = SelectObject( lpdis->hDC, psdd->hFontNormal );
  983. break;
  984. case STATE_STARTED:
  985. DrawBitmap( psdd->hArrow, lpdis, &rc );
  986. hOldFont = SelectObject( lpdis->hDC, psdd->hFontBold );
  987. break;
  988. case STATE_DONE:
  989. DrawBitmap( psdd->hChecked, lpdis, &rc );
  990. hOldFont = SelectObject( lpdis->hDC, psdd->hFontNormal );
  991. break;
  992. case STATE_ERROR:
  993. DrawBitmap( psdd->hError, lpdis, &rc );
  994. hOldFont = SelectObject( lpdis->hDC, psdd->hFontNormal );
  995. break;
  996. }
  997. rc = lpdis->rcItem;
  998. rc.left += psdd->dwHeight;
  999. DrawText( lpdis->hDC, plbid->szText, -1, &rc, DT_LEFT | DT_VCENTER );
  1000. if ( hOldFont != INVALID_HANDLE_VALUE )
  1001. {
  1002. SelectObject( lpdis->hDC, hOldFont );
  1003. }
  1004. if ( !bDoneFirstPass && lpdis->itemID == ARRAYSIZE( items ) - 1 )
  1005. {
  1006. // delay the message until we have painted at least once.
  1007. bDoneFirstPass = TRUE;
  1008. PostMessage( hDlg, WM_STARTSETUP, 0, 0 );
  1009. }
  1010. }
  1011. break;
  1012. default:
  1013. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  1014. }
  1015. return TRUE;
  1016. }
  1017. //
  1018. // Finish dialog proc
  1019. //
  1020. BOOL CALLBACK
  1021. FinishDlgProc(
  1022. HWND hDlg,
  1023. UINT uMsg,
  1024. WPARAM wParam,
  1025. LPARAM lParam )
  1026. {
  1027. NMHDR FAR *lpnmhdr;
  1028. DWORD dw;
  1029. switch ( uMsg )
  1030. {
  1031. case WM_NOTIFY:
  1032. lpnmhdr = (NMHDR FAR *) lParam;
  1033. switch ( lpnmhdr->code )
  1034. {
  1035. case PSN_SETACTIVE:
  1036. PostMessage( GetParent(hDlg), WMX_FORCEDREPAINT, 0, (LPARAM) GetDlgItem( hDlg, IDC_DIVIDER ) );
  1037. PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_FINISH );
  1038. ClearMessageQueue( );
  1039. if ( g_Options.fError )
  1040. {
  1041. TCHAR szText[ SMALL_BUFFER_SIZE ];
  1042. //dw = LoadString( g_hinstance, IDS_ERROR, szText, ARRAYSIZE( szText ) );
  1043. //Assert( dw );
  1044. //dw = SetWindowText( GetDlgItem( hDlg, IDC_S_FINISH ), szText );
  1045. //Assert( dw );
  1046. dw = LoadString( g_hinstance, IDS_CLOSE, szText, ARRAYSIZE( szText ) );
  1047. Assert( dw );
  1048. PropSheet_SetFinishText( GetParent( hDlg ), szText );
  1049. }
  1050. // fall thru
  1051. // ignore these
  1052. case PSN_KILLACTIVE:
  1053. case PSN_WIZFINISH:
  1054. case PSN_RESET:
  1055. SetWindowLong( hDlg, DWL_MSGRESULT, FALSE );
  1056. break;
  1057. case PSN_HELP:
  1058. //
  1059. // TODO: Add help
  1060. //
  1061. break;
  1062. default:
  1063. AssertMsg( FALSE, "Unhandled PSN message" );
  1064. return FALSE;
  1065. }
  1066. break;
  1067. default:
  1068. return BaseDlgProc( hDlg, uMsg, wParam, lParam );
  1069. }
  1070. return TRUE;
  1071. }
  1072. VOID
  1073. AdjustWatermarkBitmap(
  1074. IN HWND hdlg,
  1075. IN HDC hdc
  1076. )
  1077. {
  1078. static BOOL Adjusted = FALSE;
  1079. RECT rect;
  1080. RECT rect2;
  1081. HWND Separator;
  1082. PVOID Bits;
  1083. HBITMAP hDib;
  1084. HBITMAP hOldBitmap;
  1085. BITMAPINFO *BitmapInfo;
  1086. HDC MemDC;
  1087. int i;
  1088. BOOL b;
  1089. if(Adjusted) {
  1090. return;
  1091. }
  1092. //
  1093. // Determine whether the bitmap needs to be stretched.
  1094. // If the width is within 10 pixels and the height is within 5
  1095. // then we don't worry about stretching.
  1096. //
  1097. // Note that 0x3026 is the identifier of the bottom divider in
  1098. // the template. This is kind of slimy but it works.
  1099. //
  1100. Separator = GetDlgItem(hdlg,0x3026);
  1101. if(!Separator) {
  1102. goto c0;
  1103. }
  1104. GetClientRect(Separator,&rect2);
  1105. MapWindowPoints(Separator,hdlg,(LPPOINT)&rect2,2);
  1106. GetClientRect(hdlg,&rect);
  1107. b = TRUE;
  1108. i = rect.right - g_pbihWatermark->biWidth;
  1109. if((i < -10) || (i > 10)) {
  1110. b = FALSE;
  1111. }
  1112. i = rect2.top - g_pbihWatermark->biHeight;
  1113. if((i < -5) || (i > 5)) {
  1114. b = FALSE;
  1115. }
  1116. if(b) {
  1117. goto c0;
  1118. }
  1119. //
  1120. // Create a copy of the existing bitmap's header structure.
  1121. // We then modify the width and height and leave everything else alone.
  1122. //
  1123. BitmapInfo =
  1124. (LPBITMAPINFO) TraceAlloc(
  1125. GMEM_FIXED,
  1126. g_pbihWatermark->biSize +
  1127. (g_uWatermarkPaletteColorCount * sizeof(RGBQUAD)) );
  1128. if(!BitmapInfo) {
  1129. goto c0;
  1130. }
  1131. CopyMemory(
  1132. BitmapInfo,
  1133. g_pbihWatermark,
  1134. g_pbihWatermark->biSize + (g_uWatermarkPaletteColorCount * sizeof(RGBQUAD))
  1135. );
  1136. BitmapInfo->bmiHeader.biWidth = rect.right + 1;
  1137. BitmapInfo->bmiHeader.biHeight = rect2.top;
  1138. hDib = CreateDIBSection(NULL,BitmapInfo,DIB_RGB_COLORS,&Bits,NULL,0);
  1139. if(!hDib) {
  1140. goto c1;
  1141. }
  1142. //
  1143. // Create a "template" memory DC and select the DIB we created
  1144. // into it. Passing NULL to CreateCompatibleDC creates a DC into which
  1145. // any format bitmap can be selected. We don't want to use the dialog's
  1146. // DC because if the pixel depth of the watermark bitmap differs from
  1147. // the screen, we wouldn't be able to select the dib into the mem dc.
  1148. //
  1149. MemDC = CreateCompatibleDC(NULL);
  1150. if(!MemDC) {
  1151. goto c2;
  1152. }
  1153. hOldBitmap = (HBITMAP) SelectObject(MemDC,hDib);
  1154. if(!hOldBitmap) {
  1155. goto c3;
  1156. }
  1157. //
  1158. // Do the stretch operation from the source bitmap onto
  1159. // the dib.
  1160. //
  1161. SetStretchBltMode(MemDC,COLORONCOLOR);
  1162. i = StretchDIBits(
  1163. MemDC,
  1164. 0,0,
  1165. rect.right+1,
  1166. rect2.top,
  1167. 0,0,
  1168. g_pbihWatermark->biWidth,
  1169. g_pbihWatermark->biHeight,
  1170. g_pWatermarkBitmapBits,
  1171. (BITMAPINFO *)g_pbihWatermark,
  1172. DIB_RGB_COLORS,
  1173. SRCCOPY
  1174. );
  1175. if(i == GDI_ERROR) {
  1176. goto c4;
  1177. }
  1178. //
  1179. // Got everything we need, set up pointers to use new bitmap data.
  1180. //
  1181. g_pWatermarkBitmapBits = Bits;
  1182. g_pbihWatermark = (BITMAPINFOHEADER *)BitmapInfo;
  1183. b = TRUE;
  1184. c4:
  1185. SelectObject(MemDC,hOldBitmap);
  1186. c3:
  1187. DeleteDC(MemDC);
  1188. c2:
  1189. if(!b) {
  1190. DeleteObject(hDib);
  1191. }
  1192. c1:
  1193. if(!b) {
  1194. TraceFree(BitmapInfo);
  1195. }
  1196. DebugMemoryDelete(BitmapInfo); // don't track, we'll leak it on purpose.
  1197. c0:
  1198. Adjusted = TRUE;
  1199. return;
  1200. }
  1201. //
  1202. // Subclass WndProc for the wizard window.
  1203. //
  1204. // We do this so we can draw the watermark background.
  1205. //
  1206. BOOL
  1207. WizardDlgProc(
  1208. IN HWND hdlg,
  1209. IN UINT msg,
  1210. IN WPARAM wParam,
  1211. IN LPARAM lParam
  1212. )
  1213. {
  1214. BOOL b;
  1215. static int iHeight = 0;
  1216. switch(msg) {
  1217. case WM_PALETTECHANGED:
  1218. //
  1219. // If this is our window we need to avoid selecting and realizing
  1220. // because doing so would cause an infinite loop between WM_QUERYNEWPALETTE
  1221. // and WM_PALETTECHANGED.
  1222. //
  1223. if((HWND)wParam == hdlg) {
  1224. return(FALSE);
  1225. }
  1226. //
  1227. // FALL THROUGH
  1228. //
  1229. case WM_QUERYNEWPALETTE:
  1230. {
  1231. HDC hdc;
  1232. HPALETTE pal;
  1233. hdc = GetDC( hdlg );
  1234. pal = SelectPalette( hdc, g_hWatermarkPalette, (msg == WM_PALETTECHANGED) );
  1235. RealizePalette( hdc );
  1236. InvalidateRect( hdlg, NULL, TRUE );
  1237. if( pal )
  1238. {
  1239. SelectPalette( hdc, pal, TRUE );
  1240. }
  1241. ReleaseDC( hdlg, hdc );
  1242. }
  1243. return(TRUE);
  1244. case WM_ERASEBKGND:
  1245. {
  1246. HWND CurrentPage;
  1247. AdjustWatermarkBitmap( hdlg, (HDC)wParam);
  1248. b = PaintWatermark( hdlg, (HDC)wParam, 0, 0, iHeight );
  1249. }
  1250. break;
  1251. case WMX_FORCEDREPAINT:
  1252. {
  1253. HWND hwndDivider = (HWND) lParam;
  1254. // Find where the divider is on this page
  1255. if ( hwndDivider )
  1256. {
  1257. RECT rcDivider;
  1258. GetClientRect( hwndDivider, &rcDivider );
  1259. MapWindowPoints( hwndDivider, hdlg, (POINT *)&rcDivider, 2 );
  1260. iHeight = rcDivider.top;
  1261. }
  1262. else
  1263. {
  1264. iHeight = 0;
  1265. }
  1266. InvalidateRect( hdlg, NULL, TRUE );
  1267. b = TRUE;
  1268. }
  1269. break;
  1270. default:
  1271. {
  1272. b = CallWindowProc( g_OldWizardProc, hdlg, msg, wParam, lParam );
  1273. }
  1274. break;
  1275. }
  1276. return(b);
  1277. }