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.

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