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.

874 lines
20 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1996.
  5. //
  6. // File: wizpage.cxx
  7. //
  8. // Contents: Implementation of wizard page class
  9. //
  10. // History: 4-30-1997 DavidMun Created
  11. //
  12. //---------------------------------------------------------------------------
  13. #include "..\pch\headers.hxx"
  14. #pragma hdrstop
  15. #include "myheaders.hxx"
  16. //
  17. // CWizPage statics
  18. //
  19. ULONG CWizPage::s_cInstances;
  20. HFONT CWizPage::s_hfBigBold;
  21. HFONT CWizPage::s_hfBold;
  22. #ifdef WIZARD95
  23. SDIBitmap CWizPage::s_Splash;
  24. #endif // WIZARD95
  25. #define DEFAULT_LARGE_FONT_SIZE 14
  26. //===========================================================================
  27. //
  28. // CPropPage overrides
  29. //
  30. //===========================================================================
  31. //+--------------------------------------------------------------------------
  32. //
  33. // Member: CWizPage::CWizPage
  34. //
  35. // Synopsis: ctor
  36. //
  37. // Arguments: [szTmplt] - dialog resource for page
  38. // [ptszJobPath] - full path to task object
  39. //
  40. // History: 4-30-1997 DavidMun Created
  41. //
  42. //---------------------------------------------------------------------------
  43. CWizPage::CWizPage(
  44. LPCTSTR szTmplt,
  45. LPTSTR ptszJobPath):
  46. #ifdef WIZARD95
  47. _fActiveWindow(FALSE),
  48. _fPaletteChanged(FALSE),
  49. #endif // WIZARD95
  50. CPropPage(szTmplt, ptszJobPath)
  51. {
  52. InterlockedIncrement((LPLONG) &s_cInstances);
  53. }
  54. //+--------------------------------------------------------------------------
  55. //
  56. // Member: CWizPage::~CWizPage
  57. //
  58. // Synopsis: dtor
  59. //
  60. // History: 4-30-1997 DavidMun Created
  61. //
  62. //---------------------------------------------------------------------------
  63. CWizPage::~CWizPage()
  64. {
  65. //
  66. // If no more instances of this class are active, destroy the gdi stuff
  67. // stored in statics.
  68. //
  69. if (!InterlockedDecrement((LPLONG) &s_cInstances))
  70. {
  71. if (s_hfBigBold)
  72. {
  73. VERIFY(DeleteObject(s_hfBigBold));
  74. s_hfBigBold = NULL;
  75. }
  76. if (s_hfBold)
  77. {
  78. VERIFY(DeleteObject(s_hfBold));
  79. s_hfBold = NULL;
  80. }
  81. #ifdef WIZARD95
  82. _DeleteSplashBitmap();
  83. #endif // WIZARD95
  84. }
  85. }
  86. //+--------------------------------------------------------------------------
  87. //
  88. // Member: CWizPage::DlgProc
  89. //
  90. // Synopsis: Overrides the CPropPage dialog proc for special message
  91. // handling, delegates to it for everything else.
  92. //
  93. // Arguments: standard windows
  94. //
  95. // Returns: standard windows
  96. //
  97. // History: 5-20-1997 DavidMun Created
  98. //
  99. //---------------------------------------------------------------------------
  100. LRESULT
  101. CWizPage::DlgProc(
  102. UINT uMsg,
  103. WPARAM wParam,
  104. LPARAM lParam)
  105. {
  106. LRESULT lr;
  107. if (uMsg == WM_INITDIALOG)
  108. {
  109. m_fInInit = TRUE;
  110. _BaseInit();
  111. //
  112. // Create the gdi objects stored in statics if this is the first
  113. // instance of the class to receive an initdialog.
  114. //
  115. #ifdef WIZARD95
  116. if (!s_Splash.hbmp)
  117. {
  118. _CreateSplashBitmap();
  119. }
  120. #endif // WIZARD95
  121. if(!s_hfBigBold && !s_hfBold)
  122. {
  123. _CreateHeaderFonts();
  124. }
  125. //
  126. // Set the fonts of header strings to bold and large bold
  127. //
  128. _InitHeaderFonts();
  129. //
  130. // Let derived class init the dialog controls
  131. //
  132. lr = _OnInitDialog(lParam);
  133. m_fInInit = FALSE;
  134. }
  135. else if (uMsg == g_msgFindWizard)
  136. {
  137. //
  138. // If this wizard is already focused on the tasks folder indicated
  139. // by lParam, come to the foreground and indicate to the caller
  140. // that another wizard would be a duplicate and shouldn't be opened.
  141. //
  142. if (!lstrcmpi((LPCTSTR) lParam, GetTaskPath()))
  143. {
  144. SetForegroundWindow(GetParent(Hwnd()));
  145. SetWindowLongPtr(Hwnd(), DWLP_MSGRESULT, g_msgFindWizard);
  146. }
  147. lr = TRUE; // indicate we processed message
  148. }
  149. #ifdef WIZARD95
  150. else if (uMsg == WM_PALETTECHANGED && (HWND) wParam != Hwnd())
  151. {
  152. _fPaletteChanged = TRUE;
  153. InvalidateRect(Hwnd(), NULL, FALSE);
  154. }
  155. else if (uMsg == WM_ACTIVATE)
  156. {
  157. _fActiveWindow = LOWORD(wParam) != WA_INACTIVE;
  158. InvalidateRect(Hwnd(), NULL, FALSE);
  159. }
  160. #endif // WIZARD95
  161. else if (uMsg == WM_PAINT)
  162. {
  163. #ifdef WIZARD95
  164. //
  165. // If some other window changed the palette, restore it before
  166. // painting, unless we're merely a background app.
  167. //
  168. if (_fActiveWindow)
  169. {
  170. HDC hdc = GetDC(Hwnd());
  171. if (!SelectPalette(hdc, s_Splash.hPalette, FALSE))
  172. {
  173. DEBUG_OUT_LASTERROR;
  174. }
  175. if (RealizePalette(hdc) == GDI_ERROR)
  176. {
  177. DEBUG_OUT_LASTERROR;
  178. }
  179. _fPaletteChanged = FALSE;
  180. ReleaseDC(Hwnd(), hdc);
  181. }
  182. #endif // WIZARD95
  183. //
  184. // Do any custom painting required (the splash bitmap on first and
  185. // last pages). Returning FALSE will allow the dialog manager to
  186. // process the paint as well.
  187. //
  188. lr = _OnPaint((HDC) wParam);
  189. }
  190. else
  191. {
  192. //
  193. // The message has no special meaning for the wizard; delegate
  194. // to base class so it can dispatch to the appropriate member.
  195. //
  196. lr = CPropPage::DlgProc(uMsg, wParam, lParam);
  197. }
  198. return lr;
  199. }
  200. //+--------------------------------------------------------------------------
  201. //
  202. // Member: CWizPage::_OnNotify
  203. //
  204. // Synopsis: Aggregate the CPropPage WM_NOTIFY handler to provide
  205. // wizard-specific dispatching.
  206. //
  207. // Arguments: standard windows
  208. //
  209. // Returns: standard windows
  210. //
  211. // History: 5-20-1997 DavidMun Created
  212. //
  213. //---------------------------------------------------------------------------
  214. LRESULT
  215. CWizPage::_OnNotify(
  216. UINT uMessage,
  217. UINT uParam,
  218. LPARAM lParam)
  219. {
  220. // TRACE_METHOD(CWizPage, _OnNotify);
  221. LPNMHDR pnmhdr = (LPNMHDR) lParam;
  222. switch (pnmhdr->code)
  223. {
  224. //
  225. // Delegate to base class for notification processing it provides
  226. // which we don't need to override.
  227. //
  228. default:
  229. return CPropPage::_OnNotify(uMessage, uParam, lParam);
  230. //
  231. // Support notifications unique to wizard pages
  232. //
  233. case PSN_WIZBACK:
  234. return _OnWizBack();
  235. case PSN_WIZNEXT:
  236. return _OnWizNext();
  237. case PSN_WIZFINISH:
  238. return _OnWizFinish();
  239. }
  240. return TRUE;
  241. }
  242. //===========================================================================
  243. //
  244. // CWizPage methods
  245. //
  246. //===========================================================================
  247. //+--------------------------------------------------------------------------
  248. //
  249. // Member: CWizPage::_OnPaint
  250. //
  251. // Synopsis: Return FALSE to let dialog manager handle painting.
  252. //
  253. // History: 5-22-1997 DavidMun Created
  254. //
  255. //---------------------------------------------------------------------------
  256. LRESULT
  257. CWizPage::_OnPaint(
  258. HDC hdc)
  259. {
  260. #ifdef WIZARD95
  261. DEBUG_ASSERT(!hdc);
  262. _PaintSplashBitmap();
  263. #endif // WIZARD95
  264. return FALSE;
  265. }
  266. //+--------------------------------------------------------------------------
  267. //
  268. // Member: CWizPage::_OnWizBack
  269. //
  270. // Synopsis: Default handling of PSN_WIZBACK
  271. //
  272. // History: 5-20-1997 DavidMun Created
  273. //
  274. //---------------------------------------------------------------------------
  275. LRESULT
  276. CWizPage::_OnWizBack()
  277. {
  278. TRACE_METHOD(CWizPage, _OnWizBack);
  279. SetWindowLongPtr(Hwnd(), DWLP_MSGRESULT, 0);
  280. return 0;
  281. }
  282. //+--------------------------------------------------------------------------
  283. //
  284. // Member: CWizPage::_OnWizNext
  285. //
  286. // Synopsis: Default handling of PSN_WIZNEXT
  287. //
  288. // History: 5-20-1997 DavidMun Created
  289. //
  290. //---------------------------------------------------------------------------
  291. LRESULT
  292. CWizPage::_OnWizNext()
  293. {
  294. TRACE_METHOD(CWizPage, _OnWizNext);
  295. SetWindowLongPtr(Hwnd(), DWLP_MSGRESULT, 0);
  296. return 0;
  297. }
  298. //+--------------------------------------------------------------------------
  299. //
  300. // Member: CWizPage::_OnWizFinish
  301. //
  302. // Synopsis: Default handling of PSN_WIZFINISH
  303. //
  304. // History: 5-20-1997 DavidMun Created
  305. //
  306. //---------------------------------------------------------------------------
  307. LRESULT
  308. CWizPage::_OnWizFinish()
  309. {
  310. TRACE_METHOD(CWizPage, _OnWizFinish);
  311. SetWindowLongPtr(Hwnd(), DWLP_MSGRESULT, 0);
  312. return 0;
  313. }
  314. //+--------------------------------------------------------------------------
  315. //
  316. // Member: CWizPage::_InitHeaderFonts
  317. //
  318. // Synopsis: Set the font for controls having the BOLDTITLE identifiers.
  319. //
  320. // History: 5-20-1997 DavidMun Created
  321. //
  322. //---------------------------------------------------------------------------
  323. VOID
  324. CWizPage::_InitHeaderFonts()
  325. {
  326. _SetControlFont(s_hfBigBold, IDC_BIGBOLDTITLE);
  327. _SetControlFont(s_hfBold, IDC_BOLDTITLE);
  328. }
  329. //+--------------------------------------------------------------------------
  330. //
  331. // Member: CWizPage::_SetControlFont
  332. //
  333. // Synopsis: Set the font of control [nId] to [hFont]
  334. //
  335. // Arguments: [hFont] - font to use
  336. // [nId] - id of control to set
  337. //
  338. // History: 5-20-1997 DavidMun Created
  339. //
  340. // Notes: Does nothing if control not found or font handle is NULL.
  341. //
  342. //---------------------------------------------------------------------------
  343. VOID
  344. CWizPage::_SetControlFont(
  345. HFONT hFont,
  346. INT nId)
  347. {
  348. if (hFont)
  349. {
  350. HWND hwndControl = _hCtrl(nId);
  351. if (hwndControl)
  352. {
  353. SetWindowFont(hwndControl, hFont, TRUE);
  354. }
  355. }
  356. }
  357. //+--------------------------------------------------------------------------
  358. //
  359. // Member: CWizPage::_CreateHeaderFonts
  360. //
  361. // Synopsis: Create fonts used in header title static text controls.
  362. //
  363. // History: 5-20-1997 DavidMun Stolen from sample wizard97 code
  364. //
  365. //---------------------------------------------------------------------------
  366. VOID
  367. CWizPage::_CreateHeaderFonts()
  368. {
  369. DEBUG_ASSERT(!s_hfBigBold);
  370. DEBUG_ASSERT(!s_hfBold);
  371. //
  372. // Create the fonts we need based on the dialog font
  373. //
  374. NONCLIENTMETRICS ncm;
  375. SecureZeroMemory(&ncm, sizeof(ncm));
  376. ncm.cbSize = sizeof(ncm);
  377. VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0));
  378. LOGFONT lfBigBold = ncm.lfMessageFont;
  379. LOGFONT lfBold = ncm.lfMessageFont;
  380. //
  381. // Create Big Bold Font and Bold Font
  382. //
  383. lfBigBold.lfWeight = FW_BOLD;
  384. lfBold.lfWeight = FW_BOLD;
  385. TCHAR tszFontSizeString[24];
  386. ULONG ulFontSize;
  387. //
  388. // Load size and name from resources, since these may change
  389. // from locale to locale based on the size of the system font, etc.
  390. //
  391. BOOL fOk;
  392. fOk = LoadString(g_hInstance,
  393. IDS_LARGEFONTNAME,
  394. lfBigBold.lfFaceName,
  395. LF_FACESIZE);
  396. if (!fOk)
  397. {
  398. DEBUG_OUT_LASTERROR;
  399. StringCchCopy(lfBigBold.lfFaceName, LF_FACESIZE, TEXT("MS Shell Dlg"));
  400. }
  401. fOk = LoadString(g_hInstance,
  402. IDS_LARGEFONTSIZE,
  403. tszFontSizeString,
  404. ARRAYLEN(tszFontSizeString));
  405. if (fOk)
  406. {
  407. ulFontSize = _tcstoul(tszFontSizeString, NULL, 10);
  408. }
  409. if (!fOk || !ulFontSize)
  410. {
  411. DEBUG_OUT_LASTERROR;
  412. ulFontSize = DEFAULT_LARGE_FONT_SIZE;
  413. }
  414. HDC hdc = GetDC(Hwnd());
  415. if (hdc)
  416. {
  417. //
  418. // See KB article PSS ID Number Q74299,
  419. // "Calculating The Logical Height and Point Size of a Font"
  420. //
  421. lfBigBold.lfHeight = -MulDiv((INT) ulFontSize,
  422. GetDeviceCaps(hdc, LOGPIXELSY),
  423. 72);
  424. s_hfBigBold = CreateFontIndirect(&lfBigBold);
  425. if (!s_hfBigBold)
  426. {
  427. DEBUG_OUT_LASTERROR;
  428. }
  429. s_hfBold = CreateFontIndirect(&lfBold);
  430. if (!s_hfBold)
  431. {
  432. DEBUG_OUT_LASTERROR;
  433. }
  434. ReleaseDC(Hwnd(), hdc);
  435. }
  436. else
  437. {
  438. DEBUG_OUT_LASTERROR;
  439. }
  440. }
  441. #ifdef WIZARD95
  442. //+--------------------------------------------------------------------------
  443. //
  444. // Member: CWizPage::_CreateSplashBitmap
  445. //
  446. // Synopsis: Initialize a memory dc with the bitmap used on the first
  447. // and last pages.
  448. //
  449. // History: 5-22-1997 DavidMun Created
  450. //
  451. //---------------------------------------------------------------------------
  452. VOID
  453. CWizPage::_CreateSplashBitmap()
  454. {
  455. TRACE_METHOD(CWizPage, _CreateSplashBitmap);
  456. DEBUG_ASSERT(!s_Splash.hbmp);
  457. DEBUG_ASSERT(!s_Splash.hdcMem);
  458. DEBUG_ASSERT(!s_Splash.hPalette);
  459. HDC hdc = NULL;
  460. HRESULT hr = E_FAIL;
  461. do
  462. {
  463. s_Splash.hbmp = LoadResourceBitmap(IDB_SPLASH, &s_Splash.hPalette);
  464. if (!s_Splash.hbmp)
  465. {
  466. break;
  467. }
  468. BITMAP bm;
  469. if (!GetObject(s_Splash.hbmp, sizeof(bm), (LPTSTR)&bm))
  470. {
  471. DEBUG_OUT_LASTERROR;
  472. break;
  473. }
  474. s_Splash.Dimensions.cx = bm.bmWidth;
  475. s_Splash.Dimensions.cy = bm.bmHeight;
  476. hdc = GetDC(Hwnd());
  477. if (!hdc)
  478. {
  479. DEBUG_OUT_LASTERROR;
  480. break;
  481. }
  482. s_Splash.hdcMem = CreateCompatibleDC(hdc);
  483. if (!s_Splash.hdcMem)
  484. {
  485. DEBUG_OUT_LASTERROR;
  486. break;
  487. }
  488. if (!SelectPalette(hdc, s_Splash.hPalette, FALSE))
  489. {
  490. DEBUG_OUT_LASTERROR;
  491. break;
  492. }
  493. UINT uiResult = RealizePalette(hdc);
  494. if (uiResult == GDI_ERROR)
  495. {
  496. DEBUG_OUT_LASTERROR;
  497. break;
  498. }
  499. if (!SelectPalette(s_Splash.hdcMem, s_Splash.hPalette, FALSE))
  500. {
  501. DEBUG_OUT_LASTERROR;
  502. break;
  503. }
  504. uiResult = RealizePalette(s_Splash.hdcMem);
  505. if (uiResult == GDI_ERROR)
  506. {
  507. DEBUG_OUT_LASTERROR;
  508. break;
  509. }
  510. s_Splash.hbmpOld = (HBITMAP) SelectObject(s_Splash.hdcMem,
  511. s_Splash.hbmp);
  512. hr = S_OK;
  513. } while (0);
  514. if (hdc)
  515. {
  516. ReleaseDC(Hwnd(), hdc);
  517. }
  518. if (FAILED(hr))
  519. {
  520. _DeleteSplashBitmap();
  521. }
  522. }
  523. //+--------------------------------------------------------------------------
  524. //
  525. // Member: CWizPage::_DeleteSplashBitmap
  526. //
  527. // Synopsis: Free all gdi objects associated with splash bitmap.
  528. //
  529. // History: 5-22-1997 DavidMun Created
  530. //
  531. // Notes: Properly destroys a partly-initialized struct. If the
  532. // struct is already empty, does nothing.
  533. //
  534. //---------------------------------------------------------------------------
  535. VOID
  536. CWizPage::_DeleteSplashBitmap()
  537. {
  538. TRACE_METHOD(CWizPage, _DeleteSplashBitmap);
  539. if (s_Splash.hdcMem)
  540. {
  541. DEBUG_ASSERT(s_Splash.hbmp);
  542. DEBUG_ASSERT(s_Splash.hPalette);
  543. if (s_Splash.hbmpOld)
  544. {
  545. HBITMAP hbmp;
  546. hbmp = (HBITMAP) SelectObject(s_Splash.hdcMem, s_Splash.hbmpOld);
  547. DEBUG_ASSERT(hbmp == s_Splash.hbmp);
  548. s_Splash.hbmpOld = NULL;
  549. VERIFY(DeleteObject(s_Splash.hbmp));
  550. s_Splash.hbmp = NULL;
  551. }
  552. VERIFY(DeleteDC(s_Splash.hdcMem));
  553. VERIFY(DeleteObject(s_Splash.hPalette));
  554. s_Splash.hdcMem = NULL;
  555. s_Splash.hPalette = NULL;
  556. }
  557. else if (s_Splash.hbmp)
  558. {
  559. DEBUG_ASSERT(s_Splash.hPalette);
  560. VERIFY(DeleteObject(s_Splash.hbmp));
  561. VERIFY(DeleteObject(s_Splash.hPalette));
  562. s_Splash.hbmp = NULL;
  563. s_Splash.hPalette = NULL;
  564. }
  565. else
  566. {
  567. DEBUG_ASSERT(!s_Splash.hbmp);
  568. DEBUG_ASSERT(!s_Splash.hPalette);
  569. }
  570. }
  571. //+--------------------------------------------------------------------------
  572. //
  573. // Member: CWizPage::_PaintSplashBitmap
  574. //
  575. // Synopsis: Paint the splash bitmap onto the dialog window.
  576. //
  577. // History: 5-22-1997 DavidMun Created
  578. //
  579. //---------------------------------------------------------------------------
  580. VOID
  581. CWizPage::_PaintSplashBitmap()
  582. {
  583. TRACE_METHOD(CWizPage, _PaintSplashBitmap);
  584. HDC hdc = NULL;
  585. do
  586. {
  587. //
  588. // If an error prevented us from loading & processing the bitmap,
  589. // there's nothing to paint.
  590. //
  591. if (!s_Splash.hdcMem)
  592. {
  593. break;
  594. }
  595. //
  596. // Get the device context of this page's dialog, then blast the
  597. // bitmap onto it.
  598. //
  599. hdc = GetDC(Hwnd());
  600. if (!hdc)
  601. {
  602. DEBUG_OUT_LASTERROR;
  603. break;
  604. }
  605. BOOL fOk = BitBlt(hdc,
  606. 0,
  607. 0,
  608. s_Splash.Dimensions.cx,
  609. s_Splash.Dimensions.cy,
  610. s_Splash.hdcMem,
  611. 0,
  612. 0,
  613. SRCCOPY);
  614. if (!fOk)
  615. {
  616. DEBUG_OUT_LASTERROR;
  617. break;
  618. }
  619. //
  620. // Mark the area containing the bitmap as a valid rect, so the
  621. // dialog manager won't paint over it.
  622. //
  623. RECT rc =
  624. {
  625. 0,
  626. 0,
  627. s_Splash.Dimensions.cx,
  628. s_Splash.Dimensions.cy
  629. };
  630. ValidateRect(Hwnd(), &rc);
  631. } while (0);
  632. if (hdc)
  633. {
  634. ReleaseDC(Hwnd(), hdc);
  635. }
  636. }
  637. #endif // WIZARD95
  638. //+--------------------------------------------------------------------------
  639. //
  640. // Member: CWizPage::_CreatePage
  641. //
  642. // Synopsis: Helper function that optionally loads title and subtitle
  643. // strings, sets appropriate flags, then creates the page.
  644. //
  645. // Arguments: [idsHeaderTitle] - resource id of title, or 0 for none
  646. // [idsHeaderSubTitle] - resource id of subtitle, or 0 for none
  647. // [phPSP] - filled with handle returned by
  648. // CreatePropertySheetPage
  649. //
  650. // Modifies: *[phPSP]
  651. //
  652. // History: 5-01-1997 DavidMun Created
  653. //
  654. //---------------------------------------------------------------------------
  655. VOID
  656. CWizPage::_CreatePage(
  657. ULONG idsHeaderTitle,
  658. ULONG idsHeaderSubTitle,
  659. HPROPSHEETPAGE *phPSP)
  660. {
  661. TCHAR tszHeaderTitle[MAX_TITLE_CCH];
  662. TCHAR tszHeaderSubTitle[MAX_TITLE_CCH];
  663. HRESULT hr;
  664. #ifdef WIZARD97
  665. if (idsHeaderTitle)
  666. {
  667. hr = LoadStr(idsHeaderTitle, tszHeaderTitle, MAX_TITLE_CCH);
  668. if (SUCCEEDED(hr))
  669. {
  670. m_psp.dwFlags |= PSP_USEHEADERTITLE;
  671. }
  672. }
  673. if (idsHeaderSubTitle)
  674. {
  675. hr = LoadStr(idsHeaderSubTitle, tszHeaderSubTitle, MAX_TITLE_CCH);
  676. if (SUCCEEDED(hr))
  677. {
  678. m_psp.dwFlags |= PSP_USEHEADERSUBTITLE;
  679. }
  680. }
  681. m_psp.pszHeaderTitle = tszHeaderTitle;
  682. m_psp.pszHeaderSubTitle = tszHeaderSubTitle;
  683. #endif // WIZARD97
  684. *phPSP = CreatePropertySheetPage(&m_psp);
  685. if (!*phPSP)
  686. {
  687. DEBUG_OUT_LASTERROR;
  688. }
  689. }