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.

1202 lines
24 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. wizard.cpp
  5. Abstract:
  6. Enhanced dialog and IIS Wizard pages, including
  7. support for Wizard '97
  8. Author:
  9. Ronald Meijer (ronaldm)
  10. Project:
  11. Internet Services Manager
  12. Revision History:
  13. --*/
  14. //
  15. // Include Files
  16. //
  17. #include "stdafx.h"
  18. #include "comprop.h"
  19. BOOL
  20. CreateSpecialDialogFont(
  21. IN CWnd * pDlg,
  22. IN OUT CFont * pfontSpecial,
  23. IN LONG lfOffsetWeight, OPTIONAL
  24. IN LONG lfOffsetHeight, OPTIONAL
  25. IN LONG lfOffsetWidth, OPTIONAL
  26. IN BOOL fItalic, OPTIONAL
  27. IN BOOL fUnderline OPTIONAL
  28. )
  29. /*++
  30. Routine Description:
  31. From the dialog font, create special effects font.
  32. Arguments:
  33. CWnd * pDlg : Pointer to dialog
  34. CFont * pfontSpecial: Font object to be created.
  35. LONG lfOffsetWeight : Change in font weight
  36. LONG lfOffsetHeight : Value to add to height (will autonegate for truetype)
  37. LONG lfOffsetWidth : Value to add to width (ignored for truetype)
  38. BOOL fItalic : If true, reverses italic
  39. BOOL fUnderline : If true, reverses underline
  40. Return Value:
  41. TRUE for success, FALSE for failure.
  42. --*/
  43. {
  44. ASSERT(pDlg != NULL);
  45. ASSERT(pfontSpecial != NULL); // Font must be allocated
  46. ASSERT((HFONT)(*pfontSpecial) == NULL); // But not yet created
  47. if (pDlg && pfontSpecial)
  48. {
  49. //
  50. // Use dialog font as basis.
  51. //
  52. CFont * pfontDlg = pDlg->GetFont();
  53. ASSERT(pfontDlg != NULL);
  54. if (pfontDlg)
  55. {
  56. LOGFONT lf;
  57. if (pfontDlg->GetLogFont(&lf))
  58. {
  59. lf.lfWeight += lfOffsetWeight;
  60. if (lf.lfHeight < 0)
  61. {
  62. //
  63. // truetype font, ignore widths
  64. //
  65. lf.lfHeight -= lfOffsetHeight;
  66. ASSERT(lf.lfWidth == 0);
  67. }
  68. else
  69. {
  70. //
  71. // Non-true type font
  72. //
  73. lf.lfHeight += lfOffsetHeight;
  74. lf.lfWidth += lfOffsetWidth;
  75. }
  76. if (fItalic)
  77. {
  78. lf.lfItalic = !lf.lfItalic;
  79. }
  80. if (fUnderline)
  81. {
  82. lf.lfUnderline = !lf.lfUnderline;
  83. }
  84. return pfontSpecial->CreateFontIndirect(&lf);
  85. }
  86. }
  87. }
  88. return FALSE;
  89. }
  90. void
  91. ApplyFontToControls(
  92. IN CWnd * pdlg,
  93. IN CFont * pfont,
  94. IN UINT nFirst,
  95. IN UINT nLast
  96. )
  97. /*++
  98. Routine Description:
  99. Helper function to apply a font to a range of controls in a dialog.
  100. Arguments:
  101. CWnd * pdlg : Pointer to dialog
  102. CFont * pfont : Font to apply
  103. UINT nFirst : First control ID
  104. UINT nLast : Last control ID (Not all need exist)
  105. Return Value:
  106. None
  107. Notes:
  108. The control IDs are expected to exist sequentially. That is,
  109. the first id in the range nFirst to nLast that doesn't exist
  110. will break the loop.
  111. ---*/
  112. {
  113. ASSERT((HFONT)(*pfont) != NULL);
  114. ASSERT(nFirst <= nLast);
  115. CWnd * pCtl;
  116. for (UINT n = nFirst; n <= nLast; ++n)
  117. {
  118. pCtl = pdlg->GetDlgItem(n);
  119. if (!pCtl)
  120. {
  121. break;
  122. }
  123. pCtl->SetFont(pfont);
  124. }
  125. }
  126. IMPLEMENT_DYNCREATE(CEmphasizedDialog, CDialog)
  127. //
  128. // Message Map
  129. //
  130. BEGIN_MESSAGE_MAP(CEmphasizedDialog, CDialog)
  131. ON_WM_DESTROY()
  132. END_MESSAGE_MAP()
  133. //
  134. // Message Handlers
  135. //
  136. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  137. BOOL
  138. CEmphasizedDialog::OnInitDialog()
  139. /*++
  140. Routine Description:
  141. WM_INITDIALOG handler.
  142. Arguments:
  143. None
  144. Return:
  145. TRUE unless a control has received focus.
  146. --*/
  147. {
  148. BOOL bReturn = CDialog::OnInitDialog();
  149. if (CreateSpecialDialogFont(this, &m_fontBold))
  150. {
  151. //
  152. // Apply bold font
  153. //
  154. ApplyFontToControls(this, &m_fontBold, IDC_ED_BOLD1, IDC_ED_BOLD5);
  155. }
  156. return bReturn;
  157. }
  158. void
  159. CEmphasizedDialog::OnDestroy()
  160. /*++
  161. Routine Description:
  162. Cleanup internal structures
  163. Arguments:
  164. None
  165. Return Value:
  166. None
  167. --*/
  168. {
  169. m_fontBold.DeleteObject();
  170. CDialog::OnDestroy();
  171. }
  172. IMPLEMENT_DYNCREATE(CIISWizardSheet, CPropertySheet)
  173. //
  174. // Static Initialization
  175. //
  176. const int CIISWizardSheet::s_cnBoldDeltaFont = +500;
  177. const int CIISWizardSheet::s_cnBoldDeltaHeight = +8;
  178. const int CIISWizardSheet::s_cnBoldDeltaWidth = +3;
  179. CIISWizardSheet::CIISWizardSheet(
  180. IN UINT nWelcomeBitmap,
  181. IN UINT nHeaderBitmap,
  182. IN COLORREF rgbForeColor,
  183. IN COLORREF rgbBkColor
  184. )
  185. /*++
  186. Routine Description:
  187. Wizard sheet constructor. Specifying a welcome bitmap
  188. make the sheet wizard '97 compliant.
  189. Arguments:
  190. UINT nWelcomeBitmap : Resource ID of welcome bitmap
  191. UINT nHeaderBitmap : Resource ID of header bitmap
  192. Return Value:
  193. N/A
  194. --*/
  195. : CPropertySheet()
  196. {
  197. m_psh.dwFlags &= ~(PSH_HASHELP);
  198. SetWizardMode();
  199. m_rgbWindow = GetSysColor(COLOR_WINDOW);
  200. m_rgbWindowText = GetSysColor(COLOR_WINDOWTEXT);
  201. if (nWelcomeBitmap)
  202. {
  203. //
  204. // Load bitmaps, replacing colours.
  205. //
  206. COLORMAP crMap[2];
  207. crMap[0].from = rgbBkColor;
  208. crMap[0].to = m_rgbWindow;
  209. crMap[1].from = rgbForeColor;
  210. crMap[1].to = m_rgbWindowText;
  211. //
  212. // Half tone the foreground colour
  213. //
  214. if (m_rgbWindowText == RGB(0,0,0))
  215. {
  216. BYTE bRed, bGreen, bBlue;
  217. bRed = GetRValue(m_rgbWindowText);
  218. bGreen = GetGValue(m_rgbWindowText);
  219. bBlue = GetBValue(m_rgbWindowText);
  220. crMap[1].to = RGB( ((255 - bRed) * 2 / 3), ((255 - bGreen) * 2 / 3), ((255 - bBlue) * 2 / 3) );
  221. }
  222. else
  223. {
  224. crMap[1].to = m_rgbWindowText;
  225. }
  226. VERIFY(m_bmpWelcome.LoadBitmap(nWelcomeBitmap));
  227. m_bmpWelcome.GetBitmap(&m_bmWelcomeInfo);
  228. /*
  229. VERIFY(m_bmpHeader.LoadMappedBitmap(
  230. nHeaderBitmap,
  231. 0,
  232. crMap,
  233. ARRAY_SIZE(crMap)
  234. ));
  235. */
  236. VERIFY(m_bmpHeader.LoadMappedBitmap(nHeaderBitmap));
  237. m_bmpHeader.GetBitmap(&m_bmHeaderInfo);
  238. m_psh.dwFlags |= PSH_WIZARD_LITE;
  239. }
  240. }
  241. void
  242. CIISWizardSheet::EnableButton(
  243. IN int nID,
  244. IN BOOL fEnable OPTIONAL
  245. )
  246. /*++
  247. Routine Description:
  248. Enable/disable sheet button
  249. Arguments:
  250. int nID : Button ID (IDCANCEL, etc)
  251. BOOL fEnable : TRUE to enable, FALSE to disable
  252. Return Value:
  253. None
  254. --*/
  255. {
  256. CWnd * pButton = GetDlgItem(nID);
  257. if (pButton)
  258. {
  259. pButton->EnableWindow(fEnable);
  260. }
  261. }
  262. //
  263. // Message Map
  264. //
  265. BEGIN_MESSAGE_MAP(CIISWizardSheet, CPropertySheet)
  266. ON_WM_DESTROY()
  267. END_MESSAGE_MAP()
  268. //
  269. // Message Handlers
  270. //
  271. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  272. BOOL
  273. CIISWizardSheet::OnInitDialog()
  274. /*++
  275. Routine Description:
  276. WM_INITDIALOG handler. Resize the sheet to the proper
  277. size, and set up some basic information
  278. Arguments:
  279. None
  280. Return:
  281. TRUE unless a control has received focus.
  282. --*/
  283. {
  284. if (IsWizard97())
  285. {
  286. //
  287. // Create special fonts.
  288. //
  289. // Title font is same size as dialog, but bold
  290. // Welcome font is much bolder (+500), and 3 sizes larger.
  291. // Specifying a +1 in width increase is on the unlikely chance
  292. // that the dialog font is not true-type.
  293. //
  294. VERIFY(CreateSpecialDialogFont(this, &m_fontTitle));
  295. VERIFY(CreateSpecialDialogFont(
  296. this,
  297. &m_fontWelcome,
  298. s_cnBoldDeltaFont,
  299. s_cnBoldDeltaHeight,
  300. s_cnBoldDeltaWidth
  301. ));
  302. }
  303. //
  304. // Load default brush (transparent brush);
  305. //
  306. VERIFY(m_brBkgnd = (HBRUSH)GetStockObject(HOLLOW_BRUSH));
  307. //
  308. // Create the window brush
  309. //
  310. VERIFY(m_brWindow.CreateSolidBrush(m_rgbWindow));
  311. BOOL bResult = CPropertySheet::OnInitDialog();
  312. if (IsWizard97())
  313. {
  314. //
  315. // Get temporary DC for dialog - Will be released in dc destructor
  316. //
  317. CClientDC dc(this);
  318. //
  319. // Create compatible memory DCs using the dialogs DC
  320. //
  321. VERIFY(m_dcMemWelcome.CreateCompatibleDC(&dc));
  322. VERIFY(m_dcMemHeader.CreateCompatibleDC(&dc));
  323. //
  324. // Save state to be restored later.
  325. //
  326. CBitmap * pbmpOldWelcome,
  327. * pbmpOldHeader;
  328. VERIFY(pbmpOldWelcome = m_dcMemWelcome.SelectObject(&m_bmpWelcome));
  329. VERIFY(m_hbmpOldWelcome = (HBITMAP)pbmpOldWelcome->GetSafeHandle());
  330. VERIFY(pbmpOldHeader = m_dcMemHeader.SelectObject(&m_bmpHeader));
  331. VERIFY(m_hbmpOldHeader = (HBITMAP)pbmpOldHeader->GetSafeHandle());
  332. }
  333. return bResult;
  334. }
  335. void
  336. CIISWizardSheet::OnDestroy()
  337. /*++
  338. Routine Description:
  339. Cleanup internal structures
  340. Arguments:
  341. None
  342. Return Value:
  343. None
  344. --*/
  345. {
  346. CPropertySheet::OnDestroy();
  347. if (IsWizard97())
  348. {
  349. //
  350. // Restore memory DCs
  351. //
  352. ASSERT(m_hbmpOldWelcome != NULL);
  353. ASSERT(m_hbmpOldHeader != NULL);
  354. VERIFY(m_dcMemWelcome.SelectObject(
  355. CBitmap::FromHandle(m_hbmpOldWelcome)
  356. ));
  357. VERIFY(m_dcMemHeader.SelectObject(
  358. CBitmap::FromHandle(m_hbmpOldHeader)
  359. ));
  360. //
  361. // Clean up the bitmaps
  362. //
  363. m_bmpWelcome.DeleteObject();
  364. m_bmpHeader.DeleteObject();
  365. m_brWindow.DeleteObject();
  366. //
  367. // Destructors will take care of the rest.
  368. //
  369. }
  370. }
  371. void
  372. CIISWizardSheet::WinHelp(
  373. IN DWORD dwData,
  374. IN UINT nCmd
  375. )
  376. /*++
  377. Routine Description:
  378. 'Help' handler. Implemented to ensure no response for F1,
  379. instead of the bogus "Topic not found" error.
  380. Arguments:
  381. DWORD dwData : Help data
  382. UINT nCmd : Help command
  383. Return Value:
  384. None
  385. --*/
  386. {
  387. //
  388. // Eat the help command
  389. //
  390. }
  391. IMPLEMENT_DYNCREATE(CIISWizardPage, CPropertyPage)
  392. //
  393. // Margin for header bitmap
  394. //
  395. const int CIISWizardPage::s_cnHeaderOffset = 2;
  396. CIISWizardPage::CIISWizardPage(
  397. IN UINT nIDTemplate, OPTIONAL
  398. IN UINT nIDCaption, OPTIONAL
  399. IN BOOL fHeaderPage, OPTIONAL
  400. IN UINT nIDHeaderTitle, OPTIONAL
  401. IN UINT nIDSubHeaderTitle OPTIONAL
  402. )
  403. /*++
  404. Routine Description:
  405. Header wizard page
  406. Arguments:
  407. UINT nIDTemplate : Resource template
  408. UINT nIDCaption : caption ID
  409. BOOL fHeaderPage : TRUE for header page, FALSE for welcome page
  410. UINT nIDHeaderTitle : Header title
  411. UINT nIDSubHeaderTitle : Subheader title.
  412. Return Value:
  413. N/A
  414. --*/
  415. : CPropertyPage(nIDTemplate, nIDCaption),
  416. m_strTitle(),
  417. m_strSubTitle(),
  418. m_rcFillArea(0, 0, 0, 0),
  419. m_ptOrigin(0, 0),
  420. m_fUseHeader(fHeaderPage)
  421. {
  422. m_psp.dwFlags &= ~(PSP_HASHELP); // No Help
  423. if (nIDHeaderTitle)
  424. {
  425. ASSERT(IsHeaderPage());
  426. VERIFY(m_strTitle.LoadString(nIDHeaderTitle));
  427. }
  428. if (nIDSubHeaderTitle)
  429. {
  430. ASSERT(IsHeaderPage());
  431. VERIFY(m_strSubTitle.LoadString(nIDSubHeaderTitle));
  432. }
  433. m_psp.dwFlags |= PSP_HIDEHEADER; // Wizard97
  434. }
  435. BOOL
  436. CIISWizardPage::ValidateString(
  437. IN CEdit & edit,
  438. OUT CString & str,
  439. IN int nMin,
  440. IN int nMax
  441. )
  442. /*++
  443. Routine Description:
  444. Since normal 'DoDataExchange' validation happens on every entrance
  445. and exit of a property page, it's not well suited to wizards. This
  446. function is to be called on 'next' only to do validation.
  447. Arguments:
  448. CEdit & edit : Edit box where the string is to be gotten from
  449. CString & str : String to be validated
  450. int nMin : Minimum length
  451. int nMax : Maximum length
  452. Return Value:
  453. TRUE if the string is within the limits, FALSE otherwise.
  454. --*/
  455. {
  456. ASSERT(nMin <= nMax);
  457. UINT nID;
  458. TCHAR szT[33];
  459. edit.GetWindowText(str);
  460. if (str.GetLength() < nMin)
  461. {
  462. nID = IDS_DDX_MINIMUM;
  463. ::wsprintf(szT, _T("%d"), nMin);
  464. }
  465. else if (str.GetLength() > nMax)
  466. {
  467. nID = AFX_IDP_PARSE_STRING_SIZE;
  468. ::wsprintf(szT, _T("%d"), nMax);
  469. }
  470. else
  471. {
  472. //
  473. // Passes both our tests, it's ok.
  474. //
  475. return TRUE;
  476. }
  477. //
  478. // Highlight and puke
  479. //
  480. edit.SetSel(0,-1);
  481. edit.SetFocus();
  482. CString prompt;
  483. ::AfxFormatString1(prompt, nID, szT);
  484. ::AfxMessageBox(prompt, MB_ICONEXCLAMATION, nID);
  485. return FALSE;
  486. }
  487. //
  488. // Message Map
  489. //
  490. BEGIN_MESSAGE_MAP(CIISWizardPage, CPropertyPage)
  491. ON_WM_CTLCOLOR()
  492. ON_WM_ERASEBKGND()
  493. END_MESSAGE_MAP()
  494. //
  495. // Message Handlers
  496. //
  497. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  498. HBRUSH
  499. CIISWizardPage::OnCtlColor(
  500. IN CDC * pDC,
  501. IN CWnd * pWnd,
  502. IN UINT nCtlColor
  503. )
  504. /*++
  505. Routine Description:
  506. Handle control colour. Ensure a true transparent
  507. background colouring.
  508. Arguments:
  509. CDC * pDC : Device context
  510. CWnd * pWnd : Pointer to window
  511. UINT nCtlColor : Ctrl type ID
  512. Return Value:
  513. Handle to brush to be used for background painting
  514. --*/
  515. {
  516. if (IsWizard97())
  517. {
  518. switch (nCtlColor)
  519. {
  520. case CTLCOLOR_BTN:
  521. case CTLCOLOR_STATIC:
  522. //case CTLCOLOR_EDIT:
  523. //case CTLCOLOR_LISTBOX:
  524. //case CTLCOLOR_SCROLLBAR:
  525. case CTLCOLOR_DLG:
  526. //
  527. // Have text and controls be painted smoothly over bitmap
  528. // without using default background colour
  529. //
  530. pDC->SetBkMode(TRANSPARENT);
  531. pDC->SetTextColor(QueryWindowTextColor());
  532. return GetBackgroundBrush();
  533. }
  534. }
  535. //
  536. // Default processing...
  537. //
  538. return CPropertyPage::OnCtlColor(pDC, pWnd, nCtlColor);
  539. }
  540. BOOL
  541. CIISWizardPage::OnEraseBkgnd(
  542. IN CDC * pDC
  543. )
  544. /*++
  545. Routine Description:
  546. Handle erasing the background colour of the dialog
  547. Arguments:
  548. CDC * pDC : Device context
  549. Return Value:
  550. TRUE if no further works needs to be done.
  551. FALSE otherwise.
  552. --*/
  553. {
  554. if (IsWizard97())
  555. {
  556. //
  557. // Cache height/width of the fill area, and compute
  558. // the origin of the destination bitmap.
  559. //
  560. if (m_rcFillArea.Width() == 0)
  561. {
  562. //
  563. // Not yet cached, compute values
  564. //
  565. CRect rcClient;
  566. GetClientRect(&rcClient);
  567. if (IsHeaderPage())
  568. {
  569. //
  570. // Fill the upper rectangle above
  571. // the divider
  572. //
  573. CWnd * pDiv = GetDlgItem(IDC_STATIC_WZ_HEADER_DIVIDER);
  574. ASSERT(pDiv != NULL);
  575. if (pDiv != NULL)
  576. {
  577. m_rcFillArea = rcClient;
  578. GetDlgCtlRect(m_hWnd, pDiv->m_hWnd, &rcClient);
  579. m_rcFillArea.bottom = rcClient.top;
  580. //
  581. // Figure out a place for the bitmap
  582. // to go. If any coordinate is negative,
  583. // the bitmap will not be displayed
  584. //
  585. TRACEEOLID(
  586. "Fill area : " << m_rcFillArea.Height()
  587. << "x" << m_rcFillArea.Width()
  588. );
  589. TRACEEOLID(
  590. "Bitmap size: " << QueryBitmapHeight()
  591. << "x" << QueryBitmapWidth()
  592. );
  593. ASSERT(m_rcFillArea.Width() >= QueryBitmapWidth());
  594. ASSERT(m_rcFillArea.Height() >= QueryBitmapHeight());
  595. //
  596. // Find a place for the header box properly offset from the
  597. // margins
  598. //
  599. m_ptOrigin.y =
  600. (m_rcFillArea.Height() - QueryBitmapHeight() + 1) / 2;
  601. m_ptOrigin.x = m_rcFillArea.Width()
  602. - QueryBitmapWidth()
  603. + 1
  604. - (__max(s_cnHeaderOffset, m_ptOrigin.y));
  605. }
  606. }
  607. else
  608. {
  609. //
  610. // Fill the entire client are
  611. //
  612. m_rcFillArea = rcClient;
  613. }
  614. }
  615. //
  616. // Fill background colour with window colour
  617. //
  618. pDC->FillRect(&m_rcFillArea, GetWindowBrush());
  619. //
  620. // Draw the background picture if there's room.
  621. //
  622. if (m_ptOrigin.x >= 0 && m_ptOrigin.y >= 0)
  623. {
  624. pDC->BitBlt(
  625. m_ptOrigin.x,
  626. m_ptOrigin.y,
  627. QueryBitmapWidth() - 1,
  628. QueryBitmapHeight() - 1,
  629. GetBitmapMemDC(),
  630. 0,
  631. 0,
  632. SRCCOPY
  633. );
  634. }
  635. /*
  636. //
  637. // Scale bitmap appropriately -- looks grainy
  638. //
  639. int nHeight = rc.Height();
  640. double dDelta = (double)nHeight / (double)(QueryBitmapHeight() - 1);
  641. int nWidth = (int)((double)(QueryBitmapWidth() - 1) * dDelta);
  642. pDC->StretchBlt(
  643. 0,
  644. 0,
  645. nWidth,
  646. nHeight,
  647. GetBitmapMemDC(),
  648. 0,
  649. 0,
  650. QueryBitmapWidth() - 1,
  651. QueryBitmapHeight() - 1,
  652. SRCCOPY
  653. );
  654. */
  655. //
  656. // No more background painting needed
  657. //
  658. return TRUE;
  659. }
  660. //
  661. // No background images of any kind
  662. //
  663. return CPropertyPage::OnEraseBkgnd(pDC);
  664. }
  665. BOOL
  666. CIISWizardPage::OnInitDialog()
  667. /*++
  668. Routine Description:
  669. Handle WM_INITIDIALOG. Load the appropriate
  670. bitmaps, and create the brushes and fonts as needed.
  671. Arguments:
  672. None
  673. Return Value:
  674. TRUE unless a control has received initial focus
  675. --*/
  676. {
  677. CPropertyPage::OnInitDialog();
  678. //
  679. // Fake the WIZARD97 look
  680. //
  681. if (IsWizard97())
  682. {
  683. if (IsHeaderPage())
  684. {
  685. CWnd * pCtlTitle = GetDlgItem(IDC_STATIC_WZ_TITLE);
  686. CWnd * pCtlSubTitle = GetDlgItem(IDC_STATIC_WZ_SUBTITLE);
  687. ASSERT(pCtlTitle);
  688. ASSERT(pCtlSubTitle);
  689. if (pCtlTitle)
  690. {
  691. pCtlTitle->SetFont(GetSpecialFont());
  692. if (!m_strTitle.IsEmpty())
  693. {
  694. pCtlTitle->SetWindowText(m_strTitle);
  695. }
  696. }
  697. if (pCtlSubTitle && !m_strSubTitle.IsEmpty())
  698. {
  699. pCtlSubTitle->SetWindowText(m_strSubTitle);
  700. }
  701. }
  702. else
  703. {
  704. CWnd * pCtl = GetDlgItem(IDC_STATIC_WZ_WELCOME);
  705. ASSERT(pCtl != NULL);
  706. if (pCtl)
  707. {
  708. pCtl->SetFont(GetSpecialFont());
  709. }
  710. }
  711. //
  712. // Apply fonts
  713. //
  714. ApplyFontToControls(this, GetBoldFont(), IDC_ED_BOLD1, IDC_ED_BOLD5);
  715. }
  716. return TRUE;
  717. }
  718. //
  719. // CIISWizardBookEnd page
  720. //
  721. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  722. IMPLEMENT_DYNCREATE(CIISWizardBookEnd, CIISWizardPage)
  723. CIISWizardBookEnd::CIISWizardBookEnd(
  724. IN HRESULT * phResult,
  725. IN UINT nIDWelcomeTxtSuccess,
  726. IN UINT nIDWelcomeTxtFailure,
  727. IN UINT nIDCaption, OPTIONAL
  728. IN UINT nIDBodyTxtSuccess, OPTIONAL
  729. IN UINT nIDBodyTxtFailure, OPTIONAL
  730. IN UINT nIDClickTxt, OPTIONAL
  731. IN UINT nIDTemplate OPTIONAL
  732. )
  733. /*++
  734. Routine Description:
  735. Constructor for success/failure page
  736. Arguments:
  737. HRESULT * phResult : Address of result code
  738. UINT nIDWelcomeTxtSuccess : Success message
  739. UINT nIDWelcomeTxtFailure : Failure message
  740. UINT nIDCaption : Template caption
  741. UINT nIDBodyTxtSuccess : Body text for success
  742. UINT nIDBodyTxtFailure : Body text for success
  743. UINT nIDClickTxt : Click message
  744. UINT nIDTemplate : Dialog template
  745. Return Value:
  746. N/A
  747. --*/
  748. : CIISWizardPage(
  749. nIDTemplate ? nIDTemplate : CIISWizardBookEnd::IDD,
  750. nIDCaption
  751. ),
  752. m_phResult(phResult),
  753. m_strWelcomeSuccess(),
  754. m_strWelcomeFailure(),
  755. m_strBodySuccess(),
  756. m_strBodyFailure(),
  757. m_strClick()
  758. {
  759. ASSERT(m_phResult != NULL); // Must know success/failure
  760. VERIFY(m_strWelcomeSuccess.LoadString(nIDWelcomeTxtSuccess));
  761. VERIFY(m_strWelcomeFailure.LoadString(nIDWelcomeTxtFailure));
  762. VERIFY(m_strClick.LoadString(nIDClickTxt ? nIDClickTxt : IDS_WIZ_FINISH));
  763. if (nIDBodyTxtSuccess)
  764. {
  765. VERIFY(m_strBodySuccess.LoadString(nIDBodyTxtSuccess));
  766. }
  767. if (nIDBodyTxtFailure)
  768. {
  769. VERIFY(m_strBodyFailure.LoadString(nIDBodyTxtFailure));
  770. }
  771. else
  772. {
  773. //
  774. // Error text only by default
  775. //
  776. m_strBodyFailure = _T("%h");
  777. }
  778. }
  779. CIISWizardBookEnd::CIISWizardBookEnd(
  780. IN UINT nIDWelcomeTxt,
  781. IN UINT nIDCaption, OPTIONAL
  782. IN UINT nIDBodyTxt,
  783. IN UINT nIDClickTxt, OPTIONAL
  784. IN UINT nIDTemplate
  785. )
  786. /*++
  787. Routine Description:
  788. Constructor for welcome page
  789. Arguments:
  790. UINT nIDWelcomeTxt : Welcome message
  791. UINT nIDCaption : Template
  792. UINT nIDBodyTxt : Body text
  793. UINT nIDClickTxt : Click message
  794. UINT nIDTemplate : Dialog template
  795. Return Value:
  796. N/A
  797. --*/
  798. : CIISWizardPage(
  799. nIDTemplate ? nIDTemplate : CIISWizardBookEnd::IDD,
  800. nIDCaption
  801. ),
  802. m_phResult(NULL),
  803. m_strWelcomeSuccess(),
  804. m_strWelcomeFailure(),
  805. m_strBodySuccess(),
  806. m_strBodyFailure(),
  807. m_strClick()
  808. {
  809. VERIFY(m_strWelcomeSuccess.LoadString(nIDWelcomeTxt));
  810. if (nIDBodyTxt)
  811. {
  812. VERIFY(m_strBodySuccess.LoadString(nIDBodyTxt));
  813. }
  814. VERIFY(m_strClick.LoadString(nIDClickTxt ? nIDClickTxt : IDS_WIZ_NEXT));
  815. }
  816. //
  817. // Message Map
  818. //
  819. BEGIN_MESSAGE_MAP(CIISWizardBookEnd, CIISWizardPage)
  820. //{{AFX_MSG_MAP(CIISWizardBookEnd)
  821. //}}AFX_MSG_MAP
  822. END_MESSAGE_MAP()
  823. BOOL
  824. CIISWizardBookEnd::OnSetActive()
  825. /*++
  826. Routine Description:
  827. Activation handler
  828. Arguments:
  829. None
  830. Return Value:
  831. TRUE to display the page, FALSE otherwise.
  832. --*/
  833. {
  834. if (IsWelcomePage())
  835. {
  836. GetDlgItem(IDC_STATIC_WZ_WELCOME)->SetWindowText(m_strWelcomeSuccess);
  837. GetDlgItem(IDC_STATIC_WZ_BODY)->SetWindowText(m_strBodySuccess);
  838. }
  839. else
  840. {
  841. CError err(*m_phResult);
  842. GetDlgItem(IDC_STATIC_WZ_WELCOME)->SetWindowText(
  843. err.Succeeded() ? m_strWelcomeSuccess : m_strWelcomeFailure
  844. );
  845. //
  846. // Build body text string and expand error messages
  847. //
  848. CString strBody = err.Succeeded() ? m_strBodySuccess : m_strBodyFailure;
  849. err.TextFromHRESULTExpand(strBody);
  850. GetDlgItem(IDC_STATIC_WZ_BODY)->SetWindowText(strBody);
  851. }
  852. DWORD dwFlags = IsWelcomePage() ? PSWIZB_NEXT : PSWIZB_FINISH;
  853. SetWizardButtons(dwFlags);
  854. return CIISWizardPage::OnSetActive();
  855. }
  856. BOOL
  857. CIISWizardBookEnd::OnInitDialog()
  858. /*++
  859. Routine Description:
  860. WM_INITDIALOG handler. Initialize the dialog.
  861. Arguments:
  862. None.
  863. Return Value:
  864. TRUE if no focus is to be set automatically, FALSE if the focus
  865. is already set.
  866. --*/
  867. {
  868. CIISWizardPage::OnInitDialog();
  869. //
  870. // Make the "Click 'foo' to continue" message bold as well.
  871. //
  872. ApplyFontToControls(this, GetBoldFont(), IDC_STATIC_WZ_CLICK, IDC_STATIC_WZ_CLICK);
  873. GetDlgItem(IDC_STATIC_WZ_CLICK)->SetWindowText(m_strClick);
  874. //
  875. // Remove Cancel Button on the completion page only.
  876. //
  877. EnableSheetButton(IDCANCEL, IsWelcomePage());
  878. return TRUE;
  879. }