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.

1377 lines
49 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1994 **
  4. //*********************************************************************
  5. #include "pre.h"
  6. #include "tutor.h"
  7. extern HWND RunSignupWizard(HWND hWndOwner);
  8. extern TCHAR g_szICWStatic[];
  9. extern CICWTutorApp* g_pICWTutorApp;
  10. #define MIN_WIZARD_WIDTH 686 // Size needed for Large fonts
  11. #define MIN_WIZARD_HEIGHT 470 // This is the default fallback
  12. #define MAX_BORDER_HEIGHT 30 // MAX total height of border above and
  13. // below the wizard buttons
  14. #define DEFAULT_TITLE_TOP 10 // Default top/left position for titles
  15. #define DEFAULT_TITLE_LEFT 10
  16. #include "icwextsn.h"
  17. #include "webvwids.h" // Needed to create an instance of the ICW WebView object
  18. INT_PTR CALLBACK SizerDlgProc
  19. (
  20. HWND hDlg,
  21. UINT uMsg,
  22. WPARAM wParam,
  23. LPARAM lParam
  24. )
  25. {
  26. return FALSE;
  27. }
  28. CICWApp::CICWApp
  29. (
  30. void
  31. )
  32. {
  33. HWND hDlgSizer;
  34. RECT rcDlg;
  35. m_haccel = NULL;
  36. // Use Default wizard page placement
  37. m_iWizardTop = -1;
  38. m_iWizardLeft = -1;
  39. m_hTitleFont = NULL;
  40. m_clrTitleFont = (COLORREF)GetSysColor(COLOR_WINDOWTEXT);
  41. m_clrBusyBkGnd = (COLORREF)GetSysColor(COLOR_WINDOW);
  42. m_hbmFirstPageBkgrnd = NULL;
  43. hDlgSizer = CreateDialog(g_hInstance,
  44. MAKEINTRESOURCE(IDD_PAGE_SIZER),
  45. GetDesktopWindow(),
  46. SizerDlgProc);
  47. if (hDlgSizer)
  48. {
  49. GetClientRect(hDlgSizer, &rcDlg);
  50. DestroyWindow(hDlgSizer);
  51. m_wMinWizardWidth = (WORD)RECTWIDTH(rcDlg);
  52. m_wMinWizardHeight = (WORD)RECTHEIGHT(rcDlg);
  53. }
  54. else
  55. {
  56. m_wMinWizardWidth = MIN_WIZARD_WIDTH;
  57. m_wMinWizardHeight = MIN_WIZARD_HEIGHT;
  58. }
  59. }
  60. CICWApp::~CICWApp
  61. (
  62. void
  63. )
  64. {
  65. if (m_hTitleFont)
  66. DeleteObject(m_hTitleFont);
  67. if (m_hbmFirstPageBkgrnd)
  68. DeleteObject(m_hbmFirstPageBkgrnd);
  69. }
  70. // Enumerator proc used to disable the children windows in the
  71. // wizard control
  72. BOOL CALLBACK EnumChildProc
  73. (
  74. HWND hwnd, // handle to child window
  75. LPARAM lParam // application-defined value
  76. )
  77. {
  78. // We are only interested in immediate children of the wizard, but
  79. // not the wizard page DLG, which is a child of the wizard. The
  80. // PropSheet_GetCurrentPagehwnd will return the window handle of the
  81. // current Wizard page, so we can compare against the windows being
  82. // enumerated
  83. if ((hwnd != PropSheet_GetCurrentPageHwnd(gpWizardState->cmnStateData.hWndWizardPages))
  84. && GetParent(hwnd) == (HWND)lParam)
  85. {
  86. // Remove the DEFPUSHBITTON style if the child has it
  87. DWORD dwStyle = GetWindowLong(hwnd,GWL_STYLE);
  88. SendMessage(hwnd,BM_SETSTYLE,dwStyle & (~BS_DEFPUSHBUTTON),0);
  89. // Hide and disable the window
  90. ShowWindow(hwnd, SW_HIDE);
  91. EnableWindow(hwnd, FALSE);
  92. }
  93. return TRUE;
  94. }
  95. BOOL CICWApp::CreateWizardPages
  96. (
  97. HWND hWnd
  98. )
  99. {
  100. DWORD dwStyle;
  101. RECT rcWizardPage;
  102. int iTop = m_iWizardTop;
  103. int iLeft = m_iWizardLeft;
  104. gpWizardState->cmnStateData.bOEMCustom = TRUE;
  105. gpWizardState->cmnStateData.hWndWizardPages = RunSignupWizard(hWnd);
  106. // Parent should control us, so the user can tab out of our property sheet
  107. dwStyle = GetWindowLong(gpWizardState->cmnStateData.hWndWizardPages, GWL_EXSTYLE);
  108. dwStyle = dwStyle | WS_EX_CONTROLPARENT;
  109. SetWindowLong(gpWizardState->cmnStateData.hWndWizardPages, GWL_EXSTYLE, dwStyle);
  110. // Disable the standard Wizard control windows
  111. EnumChildWindows(gpWizardState->cmnStateData.hWndWizardPages,
  112. EnumChildProc,
  113. (LPARAM)gpWizardState->cmnStateData.hWndWizardPages);
  114. // Get the client rectangle of the Wizard page. We will use this
  115. // for the width and height. The top/left corner is either specified
  116. // or computed
  117. m_hWndFirstWizardPage = PropSheet_GetCurrentPageHwnd(gpWizardState->cmnStateData.hWndWizardPages);
  118. // Update the wizard dialog position
  119. GetWindowRect(m_hWndFirstWizardPage, &rcWizardPage);
  120. if (-1 == iTop)
  121. {
  122. // Start out by allowing for the page and the buttons, going from
  123. // the bottom up...
  124. iTop = RECTHEIGHT(m_rcClient) -
  125. RECTHEIGHT(rcWizardPage) -
  126. GetButtonAreaHeight();
  127. // If there is still room, leave a border between the buttons
  128. // and the page
  129. if (iTop > 0)
  130. {
  131. iTop -= m_iBtnBorderHeight/2;
  132. }
  133. // Make sure the top is not in negative space
  134. if (iTop < 0)
  135. iTop = 0;
  136. }
  137. if (-1 == iLeft)
  138. {
  139. if (RECTWIDTH(m_rcClient) > RECTWIDTH(rcWizardPage))
  140. iLeft = (RECTWIDTH(m_rcClient) - RECTWIDTH(rcWizardPage)) / 2;
  141. else
  142. iLeft = 0;
  143. }
  144. MoveWindow(gpWizardState->cmnStateData.hWndWizardPages,
  145. iLeft,
  146. iTop,
  147. RECTWIDTH(rcWizardPage),
  148. RECTHEIGHT(rcWizardPage),
  149. TRUE);
  150. ShowWindow(gpWizardState->cmnStateData.hWndWizardPages, SW_SHOW);
  151. return TRUE;
  152. }
  153. void CICWApp::DisplayHTML( void )
  154. {
  155. if (m_hbmFirstPageBkgrnd)
  156. gpWizardState->pICWWebView->SetHTMLBackgroundBitmap(m_hbmFirstPageBkgrnd, &m_rcHTML);
  157. else
  158. gpWizardState->pICWWebView->SetHTMLBackgroundBitmap(gpWizardState->cmnStateData.hbmBkgrnd, &m_rcHTML);
  159. gpWizardState->pICWWebView->ConnectToWindow(m_hwndHTML, PAGETYPE_BRANDED);
  160. gpWizardState->pICWWebView->DisplayHTML(m_szOEMHTML);
  161. // We are currently displaying the OEM HTML page
  162. m_bOnHTMLIntro = TRUE;
  163. }
  164. BOOL CICWApp::InitAppHTMLWindows
  165. (
  166. HWND hWnd
  167. )
  168. {
  169. // Co-Create the browser object
  170. if (FAILED(CoCreateInstance(CLSID_ICWWEBVIEW,
  171. NULL,
  172. CLSCTX_INPROC_SERVER,
  173. IID_IICWWebView,
  174. (LPVOID *)&gpWizardState->pICWWebView)))
  175. {
  176. return FALSE;
  177. }
  178. m_hwndHTML = CreateWindow(TEXT("WebOC"),
  179. NULL,
  180. WS_VISIBLE | WS_CHILD,
  181. m_rcHTML.left,
  182. m_rcHTML.top,
  183. RECTWIDTH(m_rcHTML),
  184. RECTHEIGHT(m_rcHTML),
  185. hWnd,
  186. NULL,
  187. g_hInstance,
  188. NULL);
  189. ASSERT(gpWizardState->pICWWebView);
  190. DisplayHTML();
  191. return TRUE;
  192. }
  193. // compute that height of the button area.
  194. // The button area height will be the height of the largest button plus
  195. // a border (15 pixels above and below.)
  196. // Additionally, the overall client height - the button area must be <= 354 pixels
  197. // which is the area required for the wizard pages in large font mode.
  198. // We can loose the border if necessary, but we will fail if
  199. // client height - max button is < 354. In this case this function will return -1
  200. int CICWApp::GetButtonAreaHeight
  201. (
  202. void
  203. )
  204. {
  205. RECT rcBtn;
  206. int iWizHeight;
  207. m_iBtnAreaHeight = 0;
  208. // Go Through each button
  209. m_BtnBack.GetClientRect(&rcBtn);
  210. if (RECTHEIGHT(rcBtn) > m_iBtnAreaHeight)
  211. m_iBtnAreaHeight = RECTHEIGHT(rcBtn);
  212. m_BtnNext.GetClientRect(&rcBtn);
  213. if (RECTHEIGHT(rcBtn) > m_iBtnAreaHeight)
  214. m_iBtnAreaHeight = RECTHEIGHT(rcBtn);
  215. m_BtnCancel.GetClientRect(&rcBtn);
  216. if (RECTHEIGHT(rcBtn) > m_iBtnAreaHeight)
  217. m_iBtnAreaHeight = RECTHEIGHT(rcBtn);
  218. m_BtnFinish.GetClientRect(&rcBtn);
  219. if (RECTHEIGHT(rcBtn) > m_iBtnAreaHeight)
  220. m_iBtnAreaHeight = RECTHEIGHT(rcBtn);
  221. m_BtnTutorial.GetClientRect(&rcBtn);
  222. if (RECTHEIGHT(rcBtn) > m_iBtnAreaHeight)
  223. m_iBtnAreaHeight = RECTHEIGHT(rcBtn);
  224. // See if there is enough room for the buttons.
  225. iWizHeight = RECTHEIGHT(m_rcClient) - m_iBtnAreaHeight;
  226. if ( iWizHeight < m_wMinWizardHeight)
  227. return -1;
  228. // Compute the border height.
  229. m_iBtnBorderHeight = iWizHeight - m_wMinWizardHeight;
  230. if (m_iBtnBorderHeight > MAX_BORDER_HEIGHT)
  231. m_iBtnBorderHeight = MAX_BORDER_HEIGHT;
  232. // Add the border height to the ret value
  233. m_iBtnAreaHeight += m_iBtnBorderHeight;
  234. return (m_iBtnAreaHeight);
  235. }
  236. BOOL CICWApp::InitAppButtons
  237. (
  238. HWND hWnd
  239. )
  240. {
  241. int iTopOfButtons;
  242. TCHAR szButtonText[MAX_BUTTON_TITLE];
  243. iTopOfButtons = RECTHEIGHT(m_rcClient) - GetButtonAreaHeight();
  244. iTopOfButtons += m_iBtnBorderHeight/2;
  245. // Setup the Back button
  246. LoadString(g_hInstance, IDS_BACK, szButtonText, MAX_BUTTON_TITLE);
  247. m_BtnBack.SetButtonText(szButtonText);
  248. m_BtnBack.SetYPos(iTopOfButtons);
  249. m_BtnBack.CreateButtonWindow(hWnd, IDC_BACK);
  250. // Setup the Next button
  251. LoadString(g_hInstance, IDS_NEXT, szButtonText, MAX_BUTTON_TITLE);
  252. m_BtnNext.SetButtonText(szButtonText);
  253. m_BtnNext.SetYPos(iTopOfButtons);
  254. m_BtnNext.CreateButtonWindow(hWnd, IDC_NEXT);
  255. // Setup the Cancel button
  256. LoadString(g_hInstance, IDS_CANCEL, szButtonText, MAX_BUTTON_TITLE);
  257. m_BtnCancel.SetButtonText(szButtonText);
  258. m_BtnCancel.SetYPos(iTopOfButtons);
  259. m_BtnCancel.CreateButtonWindow(hWnd, IDC_CANCEL);
  260. // Setup the Finish button
  261. LoadString(g_hInstance, IDS_FINISH, szButtonText, MAX_BUTTON_TITLE);
  262. m_BtnFinish.SetButtonText(szButtonText);
  263. m_BtnFinish.SetYPos(iTopOfButtons);
  264. m_BtnFinish.CreateButtonWindow(hWnd, IDC_FINISH);
  265. m_BtnFinish.Show(SW_HIDE);
  266. m_BtnFinish.Enable(FALSE);
  267. // Setup the Tutorial button
  268. LoadString(g_hInstance, IDS_TUTORIAL, szButtonText, MAX_BUTTON_TITLE);
  269. m_BtnTutorial.SetButtonText(szButtonText);
  270. m_BtnTutorial.SetYPos(iTopOfButtons);
  271. m_BtnTutorial.CreateButtonWindow(hWnd, IDC_TUTORIAL);
  272. // Disable the back button by default, since we are initially on the first
  273. // page
  274. m_BtnBack.Enable(FALSE);
  275. return TRUE;
  276. }
  277. void CICWApp::SetWizButtons
  278. (
  279. HWND hDlg,
  280. LPARAM lParam
  281. )
  282. {
  283. BOOL bEnabled;
  284. bEnabled = (lParam & PSWIZB_BACK) != 0;
  285. m_BtnBack.Enable(bEnabled);
  286. // Enable/Disable the IDD_NEXT button, and Next gets shown by default
  287. // bEnabled remembers whether hwndShow should be enabled or not
  288. bEnabled = (lParam & PSWIZB_NEXT) != 0;
  289. m_BtnNext.Show(SW_SHOW);
  290. m_BtnNext.Enable(bEnabled);
  291. // Hide/Disable Finish (this is the default case, and can be overridden below)
  292. m_BtnFinish.Show(SW_HIDE);
  293. m_BtnFinish.Enable(FALSE);
  294. // Enable/Disable Show/Hide the IDD_FINISH button
  295. if (lParam & (PSWIZB_FINISH | PSWIZB_DISABLEDFINISH))
  296. {
  297. bEnabled = (lParam & PSWIZB_FINISH) != 0;
  298. m_BtnFinish.Show(SW_SHOW);
  299. m_BtnFinish.Enable(bEnabled);
  300. m_BtnNext.Show(SW_HIDE);
  301. m_BtnNext.Enable(FALSE);
  302. }
  303. }
  304. BOOL CICWApp::CheckButtonFocus
  305. (
  306. void
  307. )
  308. {
  309. int i;
  310. HWND hwndFocus = GetFocus();
  311. BOOL bRet = FALSE;
  312. const CICWButton *Btnids[5] = { &m_BtnBack,
  313. &m_BtnNext,
  314. &m_BtnFinish,
  315. &m_BtnCancel,
  316. &m_BtnTutorial };
  317. for (i = 0; i < ARRAYSIZE(Btnids); i++)
  318. {
  319. if (hwndFocus == Btnids[i]->m_hWndButton)
  320. {
  321. bRet = TRUE;
  322. break;
  323. }
  324. }
  325. return bRet;
  326. }
  327. // Determine if any of the ICW buttons have focus, and cycle focus through
  328. // appropriatly.
  329. BOOL CICWApp::CycleButtonFocus
  330. (
  331. BOOL bForward
  332. )
  333. {
  334. int i, x;
  335. HWND hwndFocus = GetFocus();
  336. BOOL bFocusSet = FALSE;
  337. BOOL bWrapped = FALSE;
  338. const CICWButton *Btnids[5] = { &m_BtnBack,
  339. &m_BtnNext,
  340. &m_BtnFinish,
  341. &m_BtnCancel,
  342. &m_BtnTutorial };
  343. for (i = 0; i < ARRAYSIZE(Btnids); i++)
  344. {
  345. if (hwndFocus == Btnids[i]->m_hWndButton)
  346. {
  347. // Find the next button that can take focus starting with
  348. // the next button in the list
  349. if (bForward)
  350. {
  351. for (x = i + 1; x < ARRAYSIZE(Btnids); x++)
  352. {
  353. if ((GetWindowLong(Btnids[x]->m_hWndButton, GWL_STYLE) & WS_VISIBLE) &&
  354. IsWindowEnabled(Btnids[x]->m_hWndButton))
  355. {
  356. SetFocus(Btnids[x]->m_hWndButton);
  357. bFocusSet = TRUE;
  358. break;
  359. }
  360. }
  361. if (!bFocusSet)
  362. {
  363. // Wrap around to the the beginning of the button order
  364. bWrapped = TRUE;
  365. for (x = 0; x < i; x++)
  366. {
  367. if ((GetWindowLong(Btnids[x]->m_hWndButton, GWL_STYLE) & WS_VISIBLE) &&
  368. IsWindowEnabled(Btnids[x]->m_hWndButton))
  369. {
  370. bFocusSet = TRUE;
  371. SetFocus(Btnids[x]->m_hWndButton);
  372. break;
  373. }
  374. }
  375. }
  376. }
  377. else
  378. {
  379. for (x = i - 1; x >= 0; x--)
  380. {
  381. if ((GetWindowLong(Btnids[x]->m_hWndButton, GWL_STYLE) & WS_VISIBLE) &&
  382. IsWindowEnabled(Btnids[x]->m_hWndButton))
  383. {
  384. SetFocus(Btnids[x]->m_hWndButton);
  385. bFocusSet = TRUE;
  386. break;
  387. }
  388. }
  389. if (!bFocusSet)
  390. {
  391. bWrapped = TRUE;
  392. // Wrap around to the the end of the button order
  393. for (x = ARRAYSIZE(Btnids) - 1; x > i; x--)
  394. {
  395. if ((GetWindowLong(Btnids[x]->m_hWndButton, GWL_STYLE) & WS_VISIBLE) &&
  396. IsWindowEnabled(Btnids[x]->m_hWndButton))
  397. {
  398. bFocusSet = TRUE;
  399. SetFocus(Btnids[x]->m_hWndButton);
  400. break;
  401. }
  402. }
  403. }
  404. }
  405. }
  406. }
  407. // If focus is not on the buttons, and was not set, then set it to the first/last
  408. // button
  409. if (!bFocusSet)
  410. {
  411. if (bForward)
  412. {
  413. // Start at the beginning
  414. for (x = 0; x < ARRAYSIZE(Btnids); x++)
  415. {
  416. if ((GetWindowLong(Btnids[x]->m_hWndButton, GWL_STYLE) & WS_VISIBLE) &&
  417. IsWindowEnabled(Btnids[x]->m_hWndButton))
  418. {
  419. SetFocus(Btnids[x]->m_hWndButton);
  420. break;
  421. }
  422. }
  423. }
  424. else
  425. {
  426. // Start at the beginning
  427. for (x = ARRAYSIZE(Btnids) - 1; x >= 0; x--)
  428. {
  429. if ((GetWindowLong(Btnids[x]->m_hWndButton, GWL_STYLE) & WS_VISIBLE) &&
  430. IsWindowEnabled(Btnids[x]->m_hWndButton))
  431. {
  432. SetFocus(Btnids[x]->m_hWndButton);
  433. break;
  434. }
  435. }
  436. }
  437. }
  438. return bWrapped;
  439. }
  440. BOOL CICWApp::InitWizAppWindow
  441. (
  442. HWND hWnd
  443. )
  444. {
  445. if (!InitAppHTMLWindows(hWnd))
  446. return FALSE;
  447. if (!InitAppButtons(hWnd))
  448. return FALSE;
  449. // Setup the window that will display the page titles
  450. m_hwndTitle = CreateWindow(g_szICWStatic,
  451. NULL,
  452. WS_VISIBLE | WS_CHILD,
  453. m_rcTitle.left,
  454. m_rcTitle.top,
  455. RECTWIDTH(m_rcTitle),
  456. RECTHEIGHT(m_rcTitle),
  457. hWnd,
  458. NULL,
  459. g_hInstance,
  460. NULL);
  461. if (NULL == m_hwndTitle)
  462. return FALSE;
  463. SendMessage(m_hwndTitle, WM_SETFONT, (WPARAM)m_hTitleFont, 0l);
  464. ShowWindow(m_hwndTitle, SW_HIDE);
  465. return TRUE;
  466. }
  467. HWND GetControl
  468. (
  469. int iCtlId
  470. )
  471. {
  472. HWND hWndCtrl = NULL;
  473. // We should never call GetControl unless we translate a wizard page accelerator
  474. // which implies that hWndWizardPages must be set
  475. Assert(gpWizardState->cmnStateData.hWndWizardPages);
  476. HWND hWndPage = PropSheet_GetCurrentPageHwnd(gpWizardState->cmnStateData.hWndWizardPages);
  477. hWndCtrl = GetDlgItem(hWndPage, iCtlId);
  478. // If the control exist, but is not visible, or not enabled, then return NULL
  479. if (hWndCtrl &&
  480. (!(GetWindowLong(hWndCtrl, GWL_STYLE) & WS_VISIBLE) ||
  481. !IsWindowEnabled(hWndCtrl)))
  482. {
  483. hWndCtrl = NULL;
  484. }
  485. return hWndCtrl;
  486. }
  487. #define MAX_CHILDREN 100 // Reasonable number of children to search
  488. HWND GetNestedControl
  489. (
  490. int iCtlId
  491. )
  492. {
  493. HWND hWndCtrl = NULL;
  494. WORD wCnt = 0;
  495. // We should never call GetControl unless we translate a wizard page accelerator
  496. // which implies that hWndWizardPages must be set
  497. Assert(gpWizardState->cmnStateData.hWndWizardPages);
  498. HWND hWndPage = PropSheet_GetCurrentPageHwnd(gpWizardState->cmnStateData.hWndWizardPages);
  499. HWND hWndNested = GetWindow(hWndPage, GW_CHILD);
  500. // Search for the child window of the current page that contains the
  501. // dialog controls
  502. do
  503. {
  504. wCnt++; // Prevent infinite looping.
  505. if (NULL != (hWndCtrl = GetDlgItem(hWndNested, iCtlId)))
  506. break; // Found it!!!
  507. }while ((wCnt < MAX_CHILDREN) &&
  508. (NULL != (hWndNested = GetWindow(hWndNested, GW_HWNDNEXT))));
  509. // If the control exist, but is not visible, or not enabled, then return NULL
  510. if (hWndCtrl &&
  511. (!(GetWindowLong(hWndCtrl, GWL_STYLE) & WS_VISIBLE) ||
  512. !IsWindowEnabled(hWndCtrl)))
  513. {
  514. hWndCtrl = NULL;
  515. }
  516. return hWndCtrl;
  517. }
  518. LRESULT CALLBACK CICWApp::ICWAppWndProc
  519. (
  520. HWND hWnd,
  521. UINT uMessage,
  522. WPARAM wParam,
  523. LPARAM lParam
  524. )
  525. {
  526. LPCREATESTRUCT lpcs;
  527. LRESULT lRet = 0l;
  528. CICWApp *pICWApp = (CICWApp *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  529. HICON hIcon;
  530. switch (uMessage)
  531. {
  532. case WM_CREATE:
  533. lpcs = (LPCREATESTRUCT) lParam;
  534. // Get the Class instance pointer for this window
  535. pICWApp = (CICWApp *) lpcs->lpCreateParams;
  536. SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pICWApp);
  537. if (!pICWApp->InitWizAppWindow(hWnd))
  538. lRet = -1;
  539. hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICWCONN1_ICON));
  540. SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
  541. SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
  542. break;
  543. case WM_CTLCOLORBTN:
  544. case WM_CTLCOLORSTATIC:
  545. {
  546. // See if the control is an ES_READONLY style edit box, and if
  547. // so then don't make it transparent
  548. if (!(GetWindowLong((HWND)lParam, GWL_STYLE) & ES_READONLY))
  549. {
  550. HDC hdc = (HDC)wParam;
  551. // If this is the animation control, then set the color to the
  552. // animation control solid color
  553. if (ID_BUSY_ANIMATION_WINDOW == GetWindowLong((HWND)lParam, GWL_ID))
  554. {
  555. SetBkColor(hdc, pICWApp->m_clrBusyBkGnd);
  556. }
  557. SetBkMode(hdc, TRANSPARENT);
  558. lRet = (LRESULT) GetStockObject(NULL_BRUSH);
  559. // If this is the Title control, set the color
  560. if ( pICWApp->m_hwndTitle == (HWND)lParam)
  561. {
  562. SetTextColor(hdc, pICWApp->m_clrTitleFont);
  563. }
  564. }
  565. break;
  566. }
  567. case WM_DRAWITEM:
  568. {
  569. LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
  570. CICWButton *pBtn;
  571. POINT pt;
  572. pt.x = lpdis->rcItem.left;
  573. pt.y = lpdis->rcItem.top;
  574. switch (wParam)
  575. {
  576. case IDC_BACK:
  577. pBtn = &pICWApp->m_BtnBack;
  578. break;
  579. case IDC_NEXT:
  580. pBtn = &pICWApp->m_BtnNext;
  581. break;
  582. case IDC_FINISH:
  583. pBtn = &pICWApp->m_BtnFinish;
  584. break;
  585. case IDC_CANCEL:
  586. pBtn = &pICWApp->m_BtnCancel;
  587. break;
  588. case IDC_TUTORIAL:
  589. pBtn = &pICWApp->m_BtnTutorial;
  590. break;
  591. }
  592. pBtn->DrawButton(lpdis->hDC,
  593. lpdis->itemState,
  594. &pt);
  595. break;
  596. }
  597. case WM_ERASEBKGND:
  598. {
  599. // Fill in the App Window's update rect with the background bitmap
  600. FillWindowWithAppBackground(hWnd, (HDC)wParam);
  601. lRet = 1L;
  602. break;
  603. }
  604. case WM_CLOSE:
  605. {
  606. if (MsgBox(hWnd,IDS_QUERYCANCEL,
  607. MB_ICONQUESTION,MB_YESNO |
  608. MB_DEFBUTTON2) == IDYES)
  609. {
  610. DestroyWindow(hWnd);
  611. }
  612. break;
  613. }
  614. case WM_DESTROY:
  615. PostQuitMessage(0);
  616. break;
  617. // Set the wizard page title
  618. case WUM_SETTITLE:
  619. {
  620. TCHAR szTitle[MAX_RES_LEN];
  621. if (wParam)
  622. {
  623. LoadString((HINSTANCE)wParam, LOWORD(lParam), szTitle, MAX_RES_LEN);
  624. SetWindowText(pICWApp->m_hwndTitle, szTitle);
  625. }
  626. else
  627. {
  628. SetWindowText(pICWApp->m_hwndTitle, (LPTSTR)lParam);
  629. }
  630. break;
  631. }
  632. case WM_COMMAND:
  633. {
  634. int iCtlId = GET_WM_COMMAND_ID(wParam, lParam);
  635. HWND hWndCtrl;
  636. switch (iCtlId)
  637. {
  638. case IDC_BACK:
  639. if ((GetWindowLong(pICWApp->m_BtnBack.m_hWndButton, GWL_STYLE) & WS_VISIBLE) &&
  640. IsWindowEnabled(pICWApp->m_BtnBack.m_hWndButton))
  641. {
  642. if (pICWApp->m_hWndFirstWizardPage == PropSheet_GetCurrentPageHwnd(gpWizardState->cmnStateData.hWndWizardPages))
  643. {
  644. // Hide the wizard pages
  645. ShowWindow(gpWizardState->cmnStateData.hWndWizardPages, SW_HIDE);
  646. ShowWindow(pICWApp->m_hwndTitle, SW_HIDE);
  647. // Show and re-display the HTML page
  648. pICWApp->DisplayHTML();
  649. ShowWindow(pICWApp->m_hwndHTML, SW_SHOW);
  650. pICWApp->m_bOnHTMLIntro = TRUE;
  651. // Show the tutorial button
  652. pICWApp->m_BtnTutorial.Show(SW_SHOW);
  653. pICWApp->m_BtnTutorial.Enable(TRUE);
  654. // Disable the Back button
  655. pICWApp->m_BtnBack.Enable(FALSE);
  656. }
  657. else
  658. {
  659. // Go to the previous page
  660. PropSheet_PressButton(gpWizardState->cmnStateData.hWndWizardPages,PSBTN_BACK);
  661. }
  662. }
  663. else
  664. {
  665. MessageBeep(0);
  666. }
  667. break;
  668. case IDC_NEXT:
  669. if ((GetWindowLong(pICWApp->m_BtnNext.m_hWndButton, GWL_STYLE) & WS_VISIBLE) &&
  670. IsWindowEnabled(pICWApp->m_BtnNext.m_hWndButton))
  671. {
  672. if (pICWApp->m_bOnHTMLIntro)
  673. {
  674. // Hide the HTML window
  675. ShowWindow(pICWApp->m_hwndHTML, SW_HIDE);
  676. pICWApp->m_bOnHTMLIntro = FALSE;
  677. // Hide the tutorial button
  678. pICWApp->m_BtnTutorial.Show(SW_HIDE);
  679. pICWApp->m_BtnTutorial.Enable(FALSE);
  680. // Show the Title window
  681. ShowWindow(pICWApp->m_hwndTitle, SW_SHOW);
  682. // Create and Show, or just show the Wizard pages
  683. if (!gpWizardState->cmnStateData.hWndWizardPages)
  684. pICWApp->CreateWizardPages(hWnd);
  685. else
  686. ShowWindow(gpWizardState->cmnStateData.hWndWizardPages, SW_SHOW);
  687. // Enable the Back button
  688. pICWApp->m_BtnBack.Enable(TRUE);
  689. }
  690. else
  691. {
  692. // Go to the Next page
  693. PropSheet_PressButton(gpWizardState->cmnStateData.hWndWizardPages,PSBTN_NEXT);
  694. }
  695. }
  696. else
  697. {
  698. MessageBeep(0);
  699. }
  700. break;
  701. case IDC_FINISH:
  702. if ((GetWindowLong(pICWApp->m_BtnFinish.m_hWndButton, GWL_STYLE) & WS_VISIBLE) &&
  703. IsWindowEnabled(pICWApp->m_BtnFinish.m_hWndButton))
  704. {
  705. if (pICWApp->m_bOnHTMLIntro)
  706. {
  707. DestroyWindow(hWnd);
  708. }
  709. else
  710. {
  711. // Go to the Next page
  712. PropSheet_PressButton(gpWizardState->cmnStateData.hWndWizardPages,PSBTN_FINISH);
  713. }
  714. }
  715. else
  716. {
  717. MessageBeep(0);
  718. }
  719. break;
  720. case IDC_CANCEL:
  721. if ((GetWindowLong(pICWApp->m_BtnCancel.m_hWndButton, GWL_STYLE) & WS_VISIBLE) &&
  722. IsWindowEnabled(pICWApp->m_BtnCancel.m_hWndButton))
  723. {
  724. if (pICWApp->m_bOnHTMLIntro)
  725. {
  726. if (MsgBox(hWnd,IDS_QUERYCANCEL,
  727. MB_ICONQUESTION,MB_YESNO |
  728. MB_DEFBUTTON2) == IDYES)
  729. {
  730. DestroyWindow(hWnd);
  731. }
  732. }
  733. else
  734. {
  735. PropSheet_PressButton(gpWizardState->cmnStateData.hWndWizardPages,PSBTN_CANCEL);
  736. }
  737. }
  738. else
  739. {
  740. MessageBeep(0);
  741. }
  742. break;
  743. #ifndef ICWDEBUG
  744. case IDC_TUTORIAL:
  745. {
  746. // If the Tutorial button is enabled/Visible then run
  747. // the tutorial
  748. if ((GetWindowLong(pICWApp->m_BtnTutorial.m_hWndButton, GWL_STYLE) & WS_VISIBLE) &&
  749. IsWindowEnabled(pICWApp->m_BtnTutorial.m_hWndButton))
  750. {
  751. g_pICWTutorApp->LaunchTutorApp();
  752. }
  753. else
  754. {
  755. MessageBeep(0);
  756. }
  757. break;
  758. }
  759. #endif
  760. case ID_NEXT_FIELD:
  761. {
  762. if (pICWApp->m_bOnHTMLIntro)
  763. {
  764. pICWApp->CycleButtonFocus(TRUE);
  765. }
  766. else
  767. {
  768. HWND hWndFocus = GetFocus();
  769. HWND hWndTabItem;
  770. HWND hWndFirstTabItem;
  771. HWND hWndPage = PropSheet_GetCurrentPageHwnd(gpWizardState->cmnStateData.hWndWizardPages);
  772. BOOL bButtonsHaveFocus = pICWApp->CheckButtonFocus();
  773. hWndFirstTabItem = GetNextDlgTabItem(hWndPage,
  774. NULL,
  775. FALSE);
  776. // If we are on the last item in the tab order, cycle
  777. // focus to the buttons
  778. hWndTabItem = GetNextDlgTabItem(hWndPage, hWndFirstTabItem, TRUE);
  779. if ((hWndFocus == hWndTabItem) ||
  780. IsChild(hWndTabItem, hWndFocus))
  781. {
  782. pICWApp->CycleButtonFocus(TRUE);
  783. }
  784. else
  785. {
  786. if (bButtonsHaveFocus)
  787. {
  788. // Cycle the button focus. If the focus
  789. // wraps, this function will fail
  790. if (pICWApp->CycleButtonFocus(TRUE))
  791. {
  792. // Set focus to the First item in the tab order
  793. SetFocus(hWndFirstTabItem);
  794. }
  795. }
  796. else
  797. {
  798. // Set focus to the next item in the tab order
  799. SetFocus(GetNextDlgTabItem(hWndPage,
  800. hWndFocus,
  801. FALSE));
  802. }
  803. }
  804. }
  805. break;
  806. }
  807. case ID_PREV_FIELD:
  808. if (pICWApp->m_bOnHTMLIntro)
  809. {
  810. pICWApp->CycleButtonFocus(FALSE);
  811. }
  812. else
  813. {
  814. HWND hWndFocus = GetFocus();
  815. HWND hWndFirstTabItem;
  816. HWND hWndPage = PropSheet_GetCurrentPageHwnd(gpWizardState->cmnStateData.hWndWizardPages);
  817. BOOL bButtonsHaveFocus = pICWApp->CheckButtonFocus();
  818. hWndFirstTabItem = GetNextDlgTabItem(hWndPage,
  819. NULL,
  820. FALSE);
  821. // If we are on the first item in the tab order, cycle
  822. // focus to the buttons
  823. if ((hWndFocus == hWndFirstTabItem) ||
  824. IsChild(hWndFirstTabItem, hWndFocus))
  825. {
  826. pICWApp->CycleButtonFocus(FALSE);
  827. }
  828. else
  829. {
  830. if (bButtonsHaveFocus)
  831. {
  832. // Cycle the button focus. If the focus
  833. // wraps, this function will fail
  834. if (pICWApp->CycleButtonFocus(FALSE))
  835. {
  836. // Set focus to the last item in the tab order
  837. SetFocus(GetNextDlgTabItem(hWndPage, hWndFirstTabItem, TRUE));
  838. }
  839. }
  840. else
  841. {
  842. // Set focus to the prev item in the tab order
  843. SetFocus(GetNextDlgTabItem(hWndPage,
  844. hWndFocus,
  845. TRUE));
  846. }
  847. }
  848. }
  849. break;
  850. // Radio button group
  851. case IDC_RUNNEW:
  852. case IDC_RUNAUTO:
  853. case IDC_ICWMAN:
  854. {
  855. if (NULL != (hWndCtrl = GetControl(iCtlId)))
  856. {
  857. CheckRadioButton(PropSheet_GetCurrentPageHwnd(gpWizardState->cmnStateData.hWndWizardPages),
  858. IDC_RUNNEW,
  859. IDC_ICWMAN,
  860. iCtlId);
  861. SetFocus(hWndCtrl);
  862. }
  863. else
  864. {
  865. MessageBeep(0);
  866. }
  867. break;
  868. }
  869. // Check box. Needs to be toggled
  870. case IDC_CHECK_BROWSING:
  871. if (NULL != (hWndCtrl = GetControl(iCtlId)))
  872. {
  873. // Toggle the button check state
  874. if (BST_CHECKED == Button_GetCheck(hWndCtrl))
  875. Button_SetCheck(hWndCtrl, BST_UNCHECKED);
  876. else
  877. Button_SetCheck(hWndCtrl, BST_CHECKED);
  878. SetFocus(hWndCtrl);
  879. }
  880. else
  881. MessageBeep(0);
  882. break;
  883. // Pushbutton type controls
  884. case IDC_OEMOFFER_MORE:
  885. case IDC_DIALERR_PROPERTIES:
  886. case IDC_ISPDATA_TOSSAVE:
  887. case IDC_CHANGE_NUMBER:
  888. case IDC_DIALING_PROPERTIES:
  889. case IDC_DIAL_HELP:
  890. if (NULL != (hWndCtrl = GetControl(iCtlId)))
  891. {
  892. HWND hWndFocus = GetFocus();
  893. SendMessage(hWndCtrl, BM_CLICK, 0, 0l);
  894. SetFocus(hWndFocus);
  895. }
  896. else
  897. MessageBeep(0);
  898. break;
  899. // Edit Text and drop down controls. Need to be selected and focused
  900. case IDC_DIAL_FROM:
  901. case IDC_DIALERR_PHONENUMBER:
  902. case IDC_DIALERR_MODEM:
  903. case IDC_BILLINGOPT_HTML:
  904. case IDC_PAYMENTTYPE:
  905. case IDC_ISPMARKETING:
  906. case IDC_ISPLIST:
  907. if (NULL != (hWndCtrl = GetControl(iCtlId)))
  908. {
  909. Edit_SetSel(hWndCtrl, 0, -1);
  910. SetFocus(hWndCtrl);
  911. }
  912. else
  913. MessageBeep(0);
  914. break;
  915. // Nested controls
  916. case IDC_USERINFO_FIRSTNAME:
  917. case IDC_USERINFO_LASTNAME:
  918. case IDC_USERINFO_COMPANYNAME:
  919. case IDC_USERINFO_ADDRESS1:
  920. case IDC_USERINFO_ADDRESS2:
  921. case IDC_USERINFO_CITY:
  922. case IDC_USERINFO_STATE:
  923. case IDC_USERINFO_ZIP:
  924. case IDC_USERINFO_PHONE:
  925. case IDC_USERINFO_FE_NAME:
  926. case IDC_PAYMENT_CCNUMBER:
  927. case IDC_PAYMENT_EXPIREMONTH:
  928. case IDC_PAYMENT_EXPIREYEAR:
  929. case IDC_PAYMENT_CCNAME:
  930. case IDC_PAYMENT_CCADDRESS:
  931. case IDC_PAYMENT_CCZIP:
  932. case IDC_PAYMENT_IVADDRESS1:
  933. case IDC_PAYMENT_IVADDRESS2:
  934. case IDC_PAYMENT_IVCITY:
  935. case IDC_PAYMENT_IVSTATE:
  936. case IDC_PAYMENT_IVZIP:
  937. case IDC_PAYMENT_PHONEIV_BILLNAME:
  938. case IDC_PAYMENT_PHONEIV_ACCNUM:
  939. if (NULL != (hWndCtrl = GetNestedControl(iCtlId)))
  940. {
  941. Edit_SetSel(hWndCtrl, 0, -1);
  942. SetFocus(hWndCtrl);
  943. }
  944. else
  945. MessageBeep(0);
  946. break;
  947. // Radio button select group
  948. case IDC_ISPDATA_TOSACCEPT:
  949. case IDC_ISPDATA_TOSDECLINE:
  950. if (NULL != (hWndCtrl = GetControl(iCtlId)))
  951. {
  952. CheckRadioButton(PropSheet_GetCurrentPageHwnd(gpWizardState->cmnStateData.hWndWizardPages),
  953. IDC_ISPDATA_TOSACCEPT,
  954. IDC_ISPDATA_TOSDECLINE,
  955. iCtlId);
  956. // simulate a button click, so the right WM_COMMAND
  957. // gets to the isppage proc
  958. SendMessage(hWndCtrl, BM_CLICK, 0, 0l);
  959. SetFocus(hWndCtrl);
  960. }
  961. else
  962. {
  963. MessageBeep(0);
  964. }
  965. break;
  966. default:
  967. break;
  968. }
  969. lRet = 1L;
  970. break;
  971. } // WM_COMMAND
  972. default:
  973. return DefWindowProc(hWnd, uMessage, wParam, lParam);
  974. }
  975. return lRet;
  976. }
  977. void CICWApp::CenterWindow
  978. (
  979. void
  980. )
  981. {
  982. RECT rcScreen; // Screen rect
  983. RECT rcApp; // window rect
  984. int nLeft, nTop; // Top-left coordinates
  985. // Get frame window client rect in screen coordinates
  986. rcScreen.top = rcScreen.left = 0;
  987. rcScreen.right = GetSystemMetrics(SM_CXFULLSCREEN);
  988. rcScreen.bottom = GetSystemMetrics(SM_CYFULLSCREEN);
  989. // Determine the top-left point for the window to be centered
  990. GetWindowRect(m_hWndApp, &rcApp);
  991. nLeft = rcScreen.left + ((RECTWIDTH(rcScreen) - RECTWIDTH(rcApp)) / 2);
  992. nTop = rcScreen.top + ((RECTHEIGHT(rcScreen) - RECTHEIGHT(rcApp)) / 2);
  993. if (nLeft < 0)
  994. nLeft = 0;
  995. if (nTop < 0)
  996. nTop = 0;
  997. // Place the dialog
  998. MoveWindow(m_hWndApp, nLeft, nTop, RECTWIDTH(rcApp), RECTHEIGHT(rcApp), TRUE);
  999. return;
  1000. }
  1001. HRESULT CICWApp::Initialize
  1002. (
  1003. void
  1004. )
  1005. {
  1006. HRESULT hr = S_OK;
  1007. // Create the Application Window
  1008. WNDCLASSEX wc;
  1009. //Register the Application window class
  1010. ZeroMemory (&wc, sizeof(WNDCLASSEX));
  1011. wc.style = CS_GLOBALCLASS;
  1012. wc.cbSize = sizeof(wc);
  1013. wc.lpszClassName = TEXT("ICWApp");
  1014. wc.hInstance = g_hInstance;
  1015. wc.lpfnWndProc = ICWAppWndProc;
  1016. wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  1017. wc.lpszMenuName = NULL;
  1018. RegisterClassEx (&wc);
  1019. // Compute the HTML rectangle area based on the OEM customizations
  1020. // that have been previously applied
  1021. m_rcHTML.left = 0;
  1022. m_rcHTML.top = 0;
  1023. m_rcHTML.right = m_rcClient.right;
  1024. m_rcHTML.bottom = m_rcClient.bottom - m_iBtnAreaHeight;
  1025. // Load the accelerator table
  1026. m_haccel = LoadAccelerators(g_hInstance, MAKEINTRESOURCE(IDA_ACCEL));
  1027. // Create the Application Window
  1028. m_hWndApp = CreateWindow( TEXT("ICWApp"),
  1029. m_szAppTitle,
  1030. WS_BORDER | WS_CAPTION | WS_SYSMENU,
  1031. CW_USEDEFAULT,
  1032. CW_USEDEFAULT,
  1033. RECTWIDTH(m_rcClient) +
  1034. 2*GetSystemMetrics(SM_CXFIXEDFRAME),
  1035. RECTHEIGHT(m_rcClient) +
  1036. GetSystemMetrics(SM_CYCAPTION) +
  1037. 2*GetSystemMetrics(SM_CYFIXEDFRAME),
  1038. NULL,
  1039. NULL,
  1040. g_hInstance,
  1041. (LPVOID) this);
  1042. if (m_hWndApp)
  1043. {
  1044. gpWizardState->cmnStateData.hWndApp = m_hWndApp;
  1045. // Center the Window
  1046. CenterWindow();
  1047. // Show the window and paint its contents.
  1048. ShowWindow(m_hWndApp, SW_SHOW);
  1049. UpdateWindow(m_hWndApp);
  1050. }
  1051. else
  1052. {
  1053. hr = E_FAIL;
  1054. }
  1055. return hr;
  1056. }
  1057. HRESULT CICWApp::SetBackgroundBitmap
  1058. (
  1059. LPTSTR lpszBkgrndBmp
  1060. )
  1061. {
  1062. BITMAP bmInfo;
  1063. HRESULT hr = E_FAIL;
  1064. // Load the Background Bitmap
  1065. if (NULL != (gpWizardState->cmnStateData.hbmBkgrnd = (HBITMAP)LoadImage(g_hInstance,
  1066. lpszBkgrndBmp,
  1067. IMAGE_BITMAP,
  1068. 0,
  1069. 0,
  1070. LR_LOADFROMFILE)))
  1071. {
  1072. GetObject(gpWizardState->cmnStateData.hbmBkgrnd, sizeof(BITMAP), (LPVOID) &bmInfo);
  1073. // Compute some usefull Rectangles.
  1074. // The client will be the size of the background bitmap
  1075. m_rcClient.left = 0;
  1076. m_rcClient.top = 0;
  1077. m_rcClient.right = bmInfo.bmWidth;
  1078. m_rcClient.bottom = bmInfo.bmHeight;
  1079. hr = S_OK;
  1080. }
  1081. return hr;
  1082. }
  1083. HRESULT CICWApp::SetFirstPageBackgroundBitmap
  1084. (
  1085. LPTSTR lpszBkgrndBmp
  1086. )
  1087. {
  1088. BITMAP bmInfo;
  1089. HRESULT hr = E_FAIL;
  1090. // Load the Background Bitmap
  1091. if (NULL != (m_hbmFirstPageBkgrnd = (HBITMAP)LoadImage(g_hInstance,
  1092. lpszBkgrndBmp,
  1093. IMAGE_BITMAP,
  1094. 0,
  1095. 0,
  1096. LR_LOADFROMFILE)))
  1097. {
  1098. GetObject(m_hbmFirstPageBkgrnd, sizeof(BITMAP), (LPVOID) &bmInfo);
  1099. // Make sure the bitmap is the same size as the main one
  1100. if ((RECTWIDTH(m_rcClient) == bmInfo.bmWidth) &&
  1101. (RECTHEIGHT(m_rcClient) == bmInfo.bmHeight))
  1102. {
  1103. hr = S_OK;
  1104. }
  1105. }
  1106. return hr;
  1107. }
  1108. HRESULT CICWApp::SetTitleParams
  1109. (
  1110. int iTitleTop,
  1111. int iTitleLeft,
  1112. LPTSTR lpszFontFace,
  1113. long lFontPts,
  1114. long lFontWeight,
  1115. COLORREF clrFont
  1116. )
  1117. {
  1118. LOGFONT lfTitle;
  1119. HFONT hOldFont;
  1120. TEXTMETRIC tm;
  1121. HDC hdc;
  1122. // Fill in the log font for the title
  1123. lfTitle.lfHeight = -MulDiv(lFontPts, GetDeviceCaps(GetDC(NULL), LOGPIXELSY), 72);
  1124. lfTitle.lfWidth = 0;
  1125. lfTitle.lfEscapement = 0;
  1126. lfTitle.lfOrientation = 0;
  1127. lfTitle.lfWeight = lFontWeight;
  1128. lfTitle.lfItalic = FALSE;
  1129. lfTitle.lfUnderline = FALSE;
  1130. lfTitle.lfStrikeOut = FALSE;
  1131. lfTitle.lfCharSet = DEFAULT_CHARSET;
  1132. lfTitle.lfOutPrecision = OUT_DEFAULT_PRECIS;
  1133. lfTitle.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  1134. lfTitle.lfQuality = DEFAULT_QUALITY;
  1135. lfTitle.lfPitchAndFamily = VARIABLE_PITCH | FF_DONTCARE;
  1136. lstrcpy(lfTitle.lfFaceName, lpszFontFace);
  1137. if (NULL == (m_hTitleFont = CreateFontIndirect(&lfTitle)))
  1138. return E_FAIL;
  1139. // Compute the area for the title
  1140. if (-1 != iTitleTop)
  1141. m_rcTitle.top = iTitleTop;
  1142. else
  1143. m_rcTitle.top = DEFAULT_TITLE_TOP;
  1144. if (-1 != iTitleLeft)
  1145. m_rcTitle.left = iTitleLeft;
  1146. else
  1147. m_rcTitle.left = DEFAULT_TITLE_LEFT;
  1148. // The right side will be the width of the client, minus the left border
  1149. m_rcTitle.right = RECTWIDTH(m_rcClient) - m_rcTitle.left;
  1150. // The bottom will be the top plus the char height for the font
  1151. if (NULL != (hdc = GetDC(NULL)))
  1152. {
  1153. hOldFont = (HFONT)SelectObject(hdc, m_hTitleFont);
  1154. GetTextMetrics(hdc, &tm);
  1155. SelectObject(hdc, hOldFont);
  1156. ReleaseDC(NULL, hdc);
  1157. }
  1158. else
  1159. {
  1160. return E_FAIL;
  1161. }
  1162. m_rcTitle.bottom = m_rcTitle.top + tm.tmHeight;
  1163. // Set the font color
  1164. m_clrTitleFont = clrFont;
  1165. return S_OK;
  1166. }
  1167. HRESULT CICWApp::SetWizardWindowTop
  1168. (
  1169. int iTop
  1170. )
  1171. {
  1172. m_iWizardTop = iTop;
  1173. // If default positioning is not selected, then ensure the ICW wizard
  1174. // page will fit
  1175. if (-1 != iTop)
  1176. {
  1177. if ((m_iWizardTop + m_wMinWizardHeight) > (RECTHEIGHT(m_rcClient) - m_iBtnAreaHeight))
  1178. return E_FAIL;
  1179. }
  1180. return S_OK;
  1181. }
  1182. HRESULT CICWApp::SetWizardWindowLeft
  1183. (
  1184. int iLeft
  1185. )
  1186. {
  1187. m_iWizardLeft = iLeft;
  1188. if (-1 != iLeft)
  1189. {
  1190. if ((iLeft + m_wMinWizardWidth) > RECTWIDTH(m_rcClient))
  1191. return E_FAIL;
  1192. }
  1193. return S_OK;
  1194. }