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.

661 lines
17 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. wizpage.c
  5. Abstract:
  6. This module contains the function that loads the wizard pages, as well as
  7. the wizard page dialog procedure.
  8. Author:
  9. Bogdan Andreiu (bogdana) 10-Feb-1997
  10. Jason Allor (jasonall) 23-Feb-1998 (took over the project)
  11. Revision History:
  12. 10-Feb-1997 bogdana
  13. First draft.
  14. 20-Feb-1997 bogdana
  15. Added more complex page "negotiation"
  16. --*/
  17. #include "octest.h"
  18. /*++
  19. Routine Description: WizPageDlgProc (2.2)
  20. The wizard page dialog procedure.
  21. Arguments:
  22. Standard dialog procedure parameters.
  23. Return Value:
  24. Standard dialog procedure return value.
  25. --*/
  26. BOOL CALLBACK WizPageDlgProc(IN HWND hwnd,
  27. IN UINT uiMsg,
  28. IN WPARAM wParam,
  29. IN LPARAM lParam)
  30. {
  31. double fn = 2.2;
  32. BOOL bResult;
  33. TCHAR tszText[MAX_MSG_LEN];
  34. PMYWIZPAGE pPage;
  35. static DWORD s_dwCurrentMode = (DWORD)SETUPMODE_TYPICAL;
  36. static DWORD s_dwFutureMode = (DWORD)SETUPMODE_TYPICAL;
  37. static BOOL s_bChangeMode = FALSE;
  38. static BOOL s_bSkipPages = FALSE;
  39. switch (uiMsg)
  40. {
  41. case WM_INITDIALOG:
  42. {
  43. LPCTSTR tszPageType;
  44. pPage = (PMYWIZPAGE)(((LPPROPSHEETPAGE)lParam)+1);
  45. //
  46. // Set up various text controls as an indicator of what
  47. // this page is.
  48. //
  49. SetDlgItemText(hwnd, IDC_COMPONENT, pPage->tszComponentId);
  50. switch (pPage->wpType)
  51. {
  52. case WizPagesWelcome:
  53. tszPageType = TEXT("Welcome");
  54. break;
  55. case WizPagesMode:
  56. tszPageType = TEXT("Mode");
  57. break;
  58. case WizPagesEarly:
  59. tszPageType = TEXT("Early");
  60. break;
  61. case WizPagesPrenet:
  62. tszPageType = TEXT("Prenet");
  63. break;
  64. case WizPagesPostnet:
  65. tszPageType = TEXT("Postnet");
  66. break;
  67. case WizPagesLate:
  68. tszPageType = TEXT("Late");
  69. break;
  70. case WizPagesFinal:
  71. tszPageType = TEXT("Final");
  72. break;
  73. default:
  74. tszPageType = TEXT("(unknown)");
  75. break;
  76. }
  77. SetDlgItemText(hwnd, IDC_PAGE, tszPageType);
  78. _stprintf(tszText, TEXT("(page %u of %u for this component ")
  79. TEXT("and page type)"),
  80. pPage->uiOrdinal, pPage->uiCount);
  81. SetDlgItemText(hwnd, IDC_COUNT, tszText);
  82. }
  83. //
  84. // Set the type for the current page
  85. //
  86. g_wpCurrentPageType = pPage->wpType;
  87. //
  88. // Set the ordinal number for the current page
  89. //
  90. g_uiCurrentPage = pPage->uiOrdinal;
  91. //
  92. // Check if the page count received is identical with the one stored
  93. //
  94. if (pPage->uiCount !=
  95. g_auiPageNumberTable[pPage->wpType - WizPagesWelcome])
  96. {
  97. Log(fn, SEV2, TEXT("Different page types"));
  98. }
  99. bResult = TRUE;
  100. break;
  101. case WM_COMMAND:
  102. switch (LOWORD(wParam))
  103. {
  104. HWND hwndSheet;
  105. case IDC_MINIMAL:
  106. case IDC_CUSTOM:
  107. case IDC_TYPICAL:
  108. case IDC_LAPTOP:
  109. s_dwFutureMode = SetupModeFromButtonId(LOWORD(wParam));
  110. s_bChangeMode = TRUE;
  111. CheckRadioButton(hwnd,
  112. IDC_MINIMAL,
  113. IDC_LAPTOP,
  114. LOWORD(wParam));
  115. break;
  116. case IDC_SKIP_PAGES:
  117. default:
  118. break;
  119. }
  120. bResult = TRUE;
  121. break;
  122. case WM_NOTIFY:
  123. bResult = FALSE;
  124. __ASSERT((g_uiCurrentPage >= 1) &&
  125. (g_uiCurrentPage <= PageNumberTable[g_wpCurrentPageType -
  126. WizPagesWelcome]));
  127. switch (((NMHDR *)lParam)->code)
  128. {
  129. case PSN_SETACTIVE:
  130. //
  131. // Accept activation and set buttons.
  132. //
  133. if ((g_wpCurrentPageType == WizPagesFinal) &&
  134. (g_uiCurrentPage ==
  135. g_auiPageNumberTable[g_wpCurrentPageType -
  136. WizPagesWelcome]))
  137. {
  138. PropSheet_SetWizButtons(GetParent(hwnd),
  139. PSWIZB_BACK | PSWIZB_NEXT);
  140. }
  141. else
  142. {
  143. PropSheet_SetWizButtons(GetParent(hwnd),
  144. PSWIZB_BACK | PSWIZB_NEXT);
  145. }
  146. //
  147. // If it is a mode page, display the current mode
  148. //
  149. if (g_wpCurrentPageType == WizPagesMode)
  150. {
  151. //
  152. // Display the current selected mode
  153. //
  154. s_dwCurrentMode = g_ocrHelperRoutines.GetSetupMode(
  155. g_ocrHelperRoutines.OcManagerContext);
  156. PrintModeInString(tszText, s_dwCurrentMode);
  157. SetDlgItemText(hwnd, IDC_CURRENT_MODE, tszText);
  158. //
  159. // By default, we want no changes
  160. //
  161. s_bChangeMode = FALSE;
  162. }
  163. if (g_wpCurrentPageType == WizPagesMode)
  164. {
  165. CheckRadioButton(hwnd,
  166. IDC_MINIMAL,
  167. IDC_LAPTOP,
  168. ButtonIdFromSetupMode(s_dwCurrentMode));
  169. }
  170. //
  171. // Check the buttons appropiately
  172. //
  173. if (g_wpCurrentPageType == WizPagesWelcome)
  174. {
  175. CheckDlgButton(hwnd, IDC_SKIP_PAGES, s_bSkipPages?1:0);
  176. }
  177. SetDlgItemText(hwnd, IDC_TEST, TEXT(""));
  178. if (s_bSkipPages && (g_uiCurrentPage == 2))
  179. {
  180. SetWindowLong(hwnd, DWL_MSGRESULT, -1);
  181. }
  182. else
  183. {
  184. SetWindowLong(hwnd, DWL_MSGRESULT, 0);
  185. }
  186. bResult = TRUE;
  187. break;
  188. case PSN_APPLY:
  189. SetWindowLong(hwnd, DWL_MSGRESULT, 0);
  190. bResult = TRUE;
  191. break;
  192. case PSN_WIZBACK:
  193. if (g_uiCurrentPage > 1)
  194. {
  195. g_uiCurrentPage--;
  196. }
  197. else
  198. {
  199. if (g_wpCurrentPageType != WizPagesWelcome)
  200. {
  201. g_wpCurrentPageType--;
  202. g_uiCurrentPage =
  203. g_auiPageNumberTable[g_wpCurrentPageType -
  204. WizPagesWelcome];
  205. }
  206. }
  207. if (g_wpCurrentPageType == WizPagesWelcome)
  208. {
  209. //
  210. // Check the state of the "Skip pages"button
  211. //
  212. s_bSkipPages = QueryButtonCheck(hwnd, IDC_SKIP_PAGES);
  213. }
  214. //
  215. // Apply the changes resulted from the dialog box
  216. //
  217. if ((g_wpCurrentPageType == WizPagesMode) && s_bChangeMode)
  218. {
  219. g_ocrHelperRoutines.SetSetupMode(
  220. g_ocrHelperRoutines.OcManagerContext,
  221. s_dwFutureMode);
  222. PrintModeInString(tszText, s_dwFutureMode);
  223. SetDlgItemText(hwnd, IDC_CURRENT_MODE, tszText);
  224. }
  225. SetWindowLong(hwnd, DWL_MSGRESULT, 0);
  226. bResult = TRUE;
  227. break;
  228. case PSN_WIZNEXT:
  229. if (g_uiCurrentPage <
  230. g_auiPageNumberTable[g_wpCurrentPageType -
  231. WizPagesWelcome])
  232. {
  233. g_uiCurrentPage++;
  234. }
  235. else
  236. {
  237. if (g_wpCurrentPageType != WizPagesFinal)
  238. {
  239. g_wpCurrentPageType++;
  240. g_uiCurrentPage = 1;
  241. }
  242. }
  243. if (g_wpCurrentPageType == WizPagesWelcome)
  244. {
  245. //
  246. // Check the state of the "Skip pages"button
  247. //
  248. s_bSkipPages = QueryButtonCheck(hwnd, IDC_SKIP_PAGES);
  249. }
  250. //
  251. // Apply the changes resulted from the dialog box
  252. //
  253. if ((g_wpCurrentPageType == WizPagesMode) && s_bChangeMode)
  254. {
  255. g_ocrHelperRoutines.SetSetupMode(
  256. g_ocrHelperRoutines.OcManagerContext,
  257. s_dwFutureMode);
  258. PrintModeInString(tszText, s_dwFutureMode);
  259. SetDlgItemText(hwnd, IDC_CURRENT_MODE, tszText);
  260. }
  261. SetWindowLong(hwnd, DWL_MSGRESULT, 0);
  262. bResult = TRUE;
  263. break;
  264. case PSN_WIZFINISH:
  265. case PSN_KILLACTIVE:
  266. SetWindowLong(hwnd, DWL_MSGRESULT, 0);
  267. bResult = TRUE;
  268. break;
  269. case PSN_QUERYCANCEL:
  270. {
  271. BOOL bCancel;
  272. bCancel = g_ocrHelperRoutines.ConfirmCancelRoutine(hwnd);
  273. SetWindowLong(hwnd, DWL_MSGRESULT, !bCancel);
  274. bResult = TRUE;
  275. break;
  276. }
  277. default:
  278. break;
  279. }
  280. break;
  281. default:
  282. bResult = FALSE;
  283. break;
  284. }
  285. return bResult;
  286. } // WizPageDlgProc //
  287. /*++
  288. Routine Description: DoPageRequest (2.1)
  289. This routine handles the OC_REQUEST_PAGES interface routine.
  290. For illustrative purposes we return a random number of pages
  291. between 1 and MAX_WIZARD_PAGES, each with some text that indicates which
  292. page type and component is involved.
  293. Arguments:
  294. tszComponentId: supplies id for component.
  295. wpWhichOnes: supplies type of pages fo be supplied.
  296. psrpSetupPages: receives page handles.
  297. ocrHelperRoutines: OC Manager - provided helper routines
  298. Return Value:
  299. Count of pages returned, or -1 if error, in which case SetLastError()
  300. will have been called to set extended error information.
  301. --*/
  302. DWORD DoPageRequest(IN LPCTSTR tszComponentId,
  303. IN WizardPagesType wpWhichOnes,
  304. IN OUT PSETUP_REQUEST_PAGES psrpSetupPages,
  305. IN OCMANAGER_ROUTINES ocrOcManagerHelperRoutines)
  306. {
  307. double fn = 2.1;
  308. UINT uiCount;
  309. UINT uiIndex;
  310. static UINT uiBigNumberOfPages = 0;
  311. TCHAR tszMsg[MAX_MSG_LEN];
  312. PMYWIZPAGE MyPage;
  313. LPPROPSHEETPAGE Page = NULL;
  314. //
  315. // Save the helper routines for further use
  316. //
  317. g_ocrHelperRoutines = ocrOcManagerHelperRoutines;
  318. if (wpWhichOnes == WizPagesFinal)
  319. {
  320. uiCount = 0;
  321. g_auiPageNumberTable[wpWhichOnes - WizPagesWelcome] = uiCount;
  322. return uiCount;
  323. }
  324. //
  325. // For two types of pages, we will "negotiate" with the OC Manager
  326. // the number of pages. We need the second condition because
  327. // otherwise we will "negotiate" forever...
  328. //
  329. if ((wpWhichOnes == WizPagesEarly) || (wpWhichOnes == WizPagesLate))
  330. {
  331. if (uiBigNumberOfPages == 0)
  332. {
  333. //
  334. // First time : we will store the number of pages requested
  335. //
  336. uiBigNumberOfPages = uiCount = psrpSetupPages->MaxPages + 1;
  337. }
  338. else
  339. {
  340. if (uiBigNumberOfPages != psrpSetupPages->MaxPages)
  341. {
  342. //
  343. // We requested a number of pages that was not supplied
  344. // we will log an error
  345. //
  346. Log(fn, SEV2, TEXT("Incorrect number of pages received"));
  347. }
  348. //
  349. // We will lie about the number of pages for the late pages
  350. //
  351. if (wpWhichOnes == WizPagesLate)
  352. {
  353. uiBigNumberOfPages = 0;
  354. uiCount = (rand() % MAX_WIZARD_PAGES) + 1;
  355. }
  356. else
  357. {
  358. //
  359. // The second time, for the Early pages,
  360. // we return InitialSize + 1 (that is BigNumberOfPages)
  361. //
  362. uiCount = uiBigNumberOfPages;
  363. }
  364. }
  365. }
  366. else
  367. {
  368. uiCount = (rand() % MAX_WIZARD_PAGES) + 1;
  369. uiBigNumberOfPages = 0;
  370. }
  371. //
  372. // Fill in the local page table
  373. //
  374. g_auiPageNumberTable[wpWhichOnes - WizPagesWelcome] = uiCount;
  375. //
  376. // Make sure there's enough space in the array OC Manager sent us.
  377. // If not then tell OC Manager that we need more space.
  378. //
  379. if (uiCount > psrpSetupPages->MaxPages)
  380. {
  381. return(uiCount);
  382. }
  383. for (uiIndex = 0; uiIndex < uiCount; uiIndex++)
  384. {
  385. if (Page) __Free(&Page);
  386. //
  387. // The wizard common control allows the app to place private data
  388. // at the end of the buffer containing the property sheet page
  389. // descriptor. We make use of this to remember info we want to
  390. // use to set up text fields when the pages are activated.
  391. //
  392. if (!__Malloc(&Page, sizeof(PROPSHEETPAGE) + sizeof(MYWIZPAGE)))
  393. {
  394. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  395. return((DWORD)(-1));
  396. }
  397. Page->dwSize = sizeof(PROPSHEETPAGE) + sizeof(MYWIZPAGE);
  398. Page->dwFlags = PSP_DEFAULT;
  399. Page->hInstance = g_hDllInstance;
  400. //
  401. // We will use a different template for the Mode and Welcome pages
  402. //
  403. switch (wpWhichOnes)
  404. {
  405. case WizPagesWelcome:
  406. Page->pszTemplate = MAKEINTRESOURCE(IDD_WIZWELCOME);
  407. break;
  408. case WizPagesMode:
  409. Page->pszTemplate = MAKEINTRESOURCE(IDD_WIZMODE);
  410. break;
  411. default:
  412. Page->pszTemplate = MAKEINTRESOURCE(IDD_WIZPAGE);
  413. break;
  414. }
  415. //
  416. // The dialog procedure is the same
  417. //
  418. Page->pfnDlgProc = WizPageDlgProc;
  419. MyPage = (PMYWIZPAGE)(Page + 1);
  420. //
  421. // Fill in the "private" fields
  422. //
  423. MyPage->uiCount = uiCount;
  424. MyPage->uiOrdinal = uiIndex + 1;
  425. MyPage->wpType = wpWhichOnes;
  426. _tcscpy(MyPage->tszComponentId, tszComponentId);
  427. //
  428. // OK, now create the page.
  429. //
  430. psrpSetupPages->Pages[uiIndex] = CreatePropertySheetPage(Page);
  431. if (!psrpSetupPages->Pages[uiIndex])
  432. {
  433. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  434. if (Page) __Free(&Page);
  435. return (DWORD)(-1);
  436. }
  437. }
  438. if (Page) __Free(&Page);
  439. return uiCount;
  440. } // DoPageRequest //
  441. /*++
  442. Routine Description: PrintModeInString
  443. Prints the mode in "readable" string to be further displayed
  444. on the wizard page.
  445. Arguments:
  446. tszString: receives the string.
  447. uiSetupMode: supplies the mode.
  448. Return Value:
  449. None.
  450. ---*/
  451. VOID PrintModeInString(OUT PTCHAR tszString,
  452. IN UINT uiSetupMode)
  453. {
  454. switch (uiSetupMode)
  455. {
  456. case SETUPMODE_MINIMAL:
  457. _stprintf(tszString, TEXT("Current mode is MINIMAL"));
  458. break;
  459. case SETUPMODE_TYPICAL:
  460. _stprintf(tszString, TEXT("Current mode is TYPICAL"));
  461. break;
  462. case SETUPMODE_LAPTOP:
  463. _stprintf(tszString, TEXT("Current mode is LAPTOP"));
  464. break;
  465. case SETUPMODE_CUSTOM:
  466. _stprintf(tszString, TEXT("Current mode is CUSTOM"));
  467. break;
  468. default:
  469. _stprintf(tszString, TEXT("Current mode is <%u>"), uiSetupMode);
  470. break;
  471. }
  472. return;
  473. } // PrintModeInString //
  474. /*++
  475. Routine Description: ButtonIdFromSetupMode
  476. Converts a setup mode to a button id
  477. Arguments:
  478. dwSetupMode: the setup mode to convert
  479. Return Value:
  480. INT: returns button id
  481. ---*/
  482. INT ButtonIdFromSetupMode(IN DWORD dwSetupMode)
  483. {
  484. switch (dwSetupMode)
  485. {
  486. case SETUPMODE_MINIMAL: return IDC_MINIMAL;
  487. case SETUPMODE_LAPTOP: return IDC_LAPTOP;
  488. case SETUPMODE_TYPICAL: return IDC_TYPICAL;
  489. case SETUPMODE_CUSTOM: return IDC_CUSTOM;
  490. default: return IDC_TYPICAL;
  491. }
  492. } // ButtonIdFromSetupMode //
  493. /*++
  494. Routine Description: SetupModeFromButtonid
  495. Converts a button id to a setup mode
  496. Arguments:
  497. iButtonId: the button id to convert
  498. Return Value:
  499. DWORD: returns setup mode
  500. ---*/
  501. DWORD SetupModeFromButtonId(IN INT iButtonId)
  502. {
  503. switch (iButtonId)
  504. {
  505. case IDC_MINIMAL: return SETUPMODE_MINIMAL;
  506. case IDC_LAPTOP: return SETUPMODE_LAPTOP;
  507. case IDC_TYPICAL: return SETUPMODE_TYPICAL;
  508. case IDC_CUSTOM: return SETUPMODE_CUSTOM;
  509. default: return SETUPMODE_TYPICAL;
  510. }
  511. } // SetupModeFromButtonId //