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.

745 lines
23 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include <shlobj.h>
  4. #include <shlobjp.h>
  5. #include "ncatlui.h"
  6. #include "ncnetcon.h"
  7. #include "ncreg.h"
  8. #include "ncui.h"
  9. #include "resource.h"
  10. #include "shortcut.h"
  11. #include "wizard.h"
  12. #include "htmlhelp.h"
  13. #include "wgenericpage.h"
  14. static const WCHAR c_szHomenetWizDLL[] = L"hnetwiz.dll";
  15. static const CHAR c_szfnHomeNetWizardRunDll[] = "HomeNetWizardRunDll";
  16. static const WCHAR c_szMSNPath[] = L"\\MSN\\MSNCoreFiles\\msn6.exe";
  17. static const WCHAR c_szMigrationWiz[] = L"\\usmt\\migwiz.exe";
  18. static const DWORD c_dwStartupmsForExternalApps = 500;
  19. static const WCHAR c_szOnlineServiceEnglish[] = L"Online Services";
  20. CGenericFinishPage::IDDLIST CGenericFinishPage::m_dwIddList;
  21. typedef void APIENTRY FNHomeNetWizardRunDll(HWND hwndStub, HINSTANCE hAppInstance, LPSTR pszCmdLine, int nCmdShow);
  22. //
  23. // Function: RunHomeNetWizard
  24. //
  25. // Purpose: Thread to execute the Network Setup Wizard
  26. //
  27. // Parameters:
  28. // lpParameter [in] - Reserved - must be NULL
  29. //
  30. // Returns: HRESULT converted to DWORD
  31. //
  32. // Author: deon 12 April 2001
  33. //
  34. DWORD CALLBACK RunHomeNetWizard(PVOID lpParameter)
  35. {
  36. HRESULT hrExitCode = S_OK;
  37. __try
  38. {
  39. HMODULE hModHomeNet = LoadLibrary(c_szHomenetWizDLL);
  40. if (hModHomeNet)
  41. {
  42. FNHomeNetWizardRunDll *pfnHomeNewWizardRunDll = reinterpret_cast<FNHomeNetWizardRunDll *>(GetProcAddress(hModHomeNet, c_szfnHomeNetWizardRunDll));
  43. if (pfnHomeNewWizardRunDll)
  44. {
  45. pfnHomeNewWizardRunDll(NULL, _Module.GetModuleInstance(), NULL, 0);
  46. }
  47. else
  48. {
  49. hrExitCode = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  50. }
  51. FreeLibrary(hModHomeNet);
  52. }
  53. else
  54. {
  55. hrExitCode = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  56. }
  57. }
  58. __except (EXCEPTION_EXECUTE_HANDLER)
  59. {
  60. hrExitCode = HRESULT_FROM_WIN32(GetLastError());
  61. if (SUCCEEDED(hrExitCode))
  62. {
  63. hrExitCode = E_FAIL;
  64. }
  65. }
  66. return static_cast<DWORD>(hrExitCode);
  67. }
  68. BOOL fIsMSNPresent()
  69. {
  70. BOOL bRet = TRUE;
  71. WCHAR szExecutePath[MAX_PATH+1];
  72. HRESULT hr = SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, szExecutePath);
  73. if (SUCCEEDED(hr))
  74. {
  75. WCHAR szPath[MAX_PATH+1];
  76. DwFormatString(L"%1!s!%2!s!", szPath, celems(szPath), szExecutePath, c_szMSNPath);
  77. DWORD dwRet = GetFileAttributes(szPath);
  78. if (0xFFFFFFFF != dwRet)
  79. {
  80. hr = S_OK;
  81. }
  82. else
  83. {
  84. bRet = FALSE;
  85. }
  86. }
  87. return bRet;
  88. }
  89. //
  90. // Function: ShellExecuteFromCSIDL
  91. //
  92. // Purpose: Execute a command on this computer based on a CSIDL
  93. //
  94. // Parameters:
  95. // hwndParent [in] - Handle of parent, or NULL for Desktop
  96. // nFolder [in] - CSIDL of base path
  97. // szCommand [in] - Command to be appended to CSIDL
  98. // fIsFolder [in] - Open a folder?
  99. // dwSleepTime [in] - Time to sleep after execute or 0 for none
  100. //
  101. // Returns: HRESULT
  102. //
  103. // Author: deon 12 April 2001
  104. //
  105. HRESULT ShellExecuteFromCSIDL(HWND hWndParent, int nFolder, LPCWSTR szCommand, BOOL fIsFolder, DWORD dwSleepTime)
  106. {
  107. HRESULT hr = S_OK;
  108. WCHAR szExecutePath[MAX_PATH+1];
  109. hr = SHGetFolderPath(NULL, nFolder, NULL, SHGFP_TYPE_CURRENT, szExecutePath);
  110. if (SUCCEEDED(hr))
  111. {
  112. if (NULL == hWndParent)
  113. {
  114. hWndParent = GetDesktopWindow();
  115. }
  116. wcsncat(szExecutePath, szCommand, MAX_PATH);
  117. if (fIsFolder)
  118. {
  119. // Make sure path points to a folder and not some or other virus
  120. DWORD dwRet = GetFileAttributes(szExecutePath);
  121. if ( (0xFFFFFFFF != dwRet) &&
  122. (FILE_ATTRIBUTE_DIRECTORY & dwRet) )
  123. {
  124. hr = S_OK;
  125. }
  126. else
  127. {
  128. hr = E_FAIL;
  129. }
  130. }
  131. if (SUCCEEDED(hr))
  132. {
  133. // Execute the file / folder
  134. if (::ShellExecute(hWndParent, NULL, szExecutePath, NULL, NULL, SW_SHOWNORMAL) <= reinterpret_cast<HINSTANCE>(32))
  135. {
  136. hr = E_FAIL;
  137. }
  138. else
  139. {
  140. hr = S_OK;
  141. if (dwSleepTime)
  142. {
  143. Sleep(dwSleepTime); // Give time to startup
  144. }
  145. }
  146. }
  147. if (FAILED(hr))
  148. {
  149. NcMsgBox(_Module.GetResourceInstance(),
  150. NULL,
  151. IDS_WIZARD_CAPTION,
  152. IDS_ERR_COULD_NOT_OPEN_DIR,
  153. MB_OK | MB_ICONERROR,
  154. szExecutePath);
  155. }
  156. }
  157. else
  158. {
  159. NcMsgBox(_Module.GetResourceInstance(),
  160. NULL,
  161. IDS_WIZARD_CAPTION,
  162. IDS_ERR_COULD_NOT_OPEN_DIR,
  163. MB_OK | MB_ICONERROR,
  164. szCommand);
  165. }
  166. return hr;
  167. }
  168. //
  169. // Function: CGenericFinishPage::OnCGenericFinishPagePageNext
  170. //
  171. // Purpose: Handle the pressing of the Next button
  172. //
  173. // Parameters: hwndDlg [IN] - Handle to the CGenericFinishPage dialog
  174. //
  175. // Returns: BOOL, TRUE
  176. //
  177. BOOL CGenericFinishPage::OnCGenericFinishPagePageNext(HWND hwndDlg)
  178. {
  179. TraceFileFunc(ttidWizard);
  180. HCURSOR hOldCursor = NULL;
  181. INetConnection * pConn = NULL;
  182. // Retrieve the CWizard instance from the dialog
  183. CWizard * pWizard =
  184. reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
  185. Assert(NULL != pWizard);
  186. HRESULT hr = S_OK;
  187. switch (m_dwMyIDD)
  188. {
  189. case IDD_FinishOtherWays:
  190. {
  191. if (IsDlgButtonChecked(hwndDlg, CHK_SETUP_MSN) &&
  192. (fIsMSNPresent()) )
  193. {
  194. hr = ShellExecuteFromCSIDL(NULL, CSIDL_PROGRAM_FILES, c_szMSNPath, FALSE, c_dwStartupmsForExternalApps);
  195. }
  196. else if (fIsMSNPresent() || IsDlgButtonChecked(hwndDlg, CHK_SELECTOTHER))
  197. {
  198. WCHAR szPath[MAX_PATH+1];
  199. // As per RAID: 450478.
  200. // If we are running on a MUI platform and the user is logged in a non-primary
  201. // language (IOW: not English), the UserDefaultUILanguage will be different from the
  202. // SystemDefaultUILanguage
  203. if (GetUserDefaultUILanguage() != GetSystemDefaultUILanguage())
  204. {
  205. // Use the English name instead, since on the MUI platform
  206. // the folder name wil be in English.
  207. //
  208. // ISSUE: This will cause the caption of the folder to appear in English
  209. // for a non-Enlish user.
  210. DwFormatString(L"\\%1!s!", szPath, celems(szPath), c_szOnlineServiceEnglish);
  211. }
  212. else
  213. {
  214. DwFormatString(L"\\%1!s!", szPath, celems(szPath), SzLoadIds(IDS_OnlineServices));
  215. }
  216. hr = ShellExecuteFromCSIDL(NULL, CSIDL_PROGRAM_FILES, szPath, TRUE, c_dwStartupmsForExternalApps);
  217. }
  218. }
  219. break;
  220. case IDD_FinishNetworkSetupWizard:
  221. {
  222. Assert(S_OK == HrShouldHaveHomeNetWizard());
  223. DWORD dwThreadId;
  224. HANDLE hHomeNetThread = CreateThread(NULL, STACK_SIZE_COMPACT, RunHomeNetWizard, NULL, 0, &dwThreadId);
  225. if (NULL != hHomeNetThread)
  226. {
  227. HRESULT hrExitCode = S_OK;
  228. ShowWindow(GetParent(hwndDlg), SW_HIDE);
  229. WaitForSingleObject(hHomeNetThread, INFINITE);
  230. GetExitCodeThread(hHomeNetThread, reinterpret_cast<LPDWORD>(&hrExitCode));
  231. if (S_OK == hrExitCode) // user finished the wizard
  232. {
  233. #ifdef DBG
  234. // Make sure we don't leave the window open & hidden
  235. ShowWindow(GetParent(hwndDlg), SW_SHOW);
  236. #endif
  237. // Go to close page
  238. ::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  239. PostMessage(GetParent(hwndDlg), PSM_SETCURSEL, 0, (LPARAM)pWizard->GetPageHandle(IDD_Exit));
  240. }
  241. else if (S_FALSE == hrExitCode) // user pressed back button
  242. {
  243. ShowWindow(GetParent(hwndDlg), SW_SHOW);
  244. }
  245. else
  246. {
  247. ShowWindow(GetParent(hwndDlg), SW_SHOW);
  248. }
  249. CloseHandle(hHomeNetThread);
  250. }
  251. }
  252. default:
  253. break;
  254. }
  255. if (SUCCEEDED(hr))
  256. {
  257. PostMessage(GetParent(hwndDlg), PSM_SETCURSEL, 0, (LPARAM)pWizard->GetPageHandle(IDD_Exit));
  258. }
  259. else
  260. {
  261. PostMessage(GetParent(hwndDlg), PSM_SETCURSEL, 0, (LPARAM)pWizard->GetPageHandle(m_dwMyIDD));
  262. }
  263. return TRUE;
  264. }
  265. //
  266. // Function: CGenericFinishPage::OnCGenericFinishPagePageBack
  267. //
  268. // Purpose: Handle the BACK notification on the CGenericFinishPage page
  269. //
  270. // Parameters: hwndDlg [IN] - Handle to the CGenericFinishPage dialog
  271. //
  272. // Returns: BOOL, TRUE
  273. //
  274. BOOL CGenericFinishPage::OnCGenericFinishPagePageBack(HWND hwndDlg)
  275. {
  276. TraceFileFunc(ttidWizard);
  277. UINT nCnt = 0;
  278. HPROPSHEETPAGE hPage = NULL;
  279. // Retrieve the CWizard instance from the dialog
  280. CWizard * pWizard =
  281. reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
  282. Assert(NULL != pWizard);
  283. DWORD iddOrigin = pWizard->GetPageOrigin(m_dwMyIDD, NULL);
  284. if (iddOrigin)
  285. {
  286. ::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, iddOrigin);
  287. }
  288. return TRUE;
  289. }
  290. //
  291. // Function: OnCGenericFinishPagePageActivate
  292. //
  293. // Purpose: Handle the page activation
  294. //
  295. // Parameters: hwndDlg [IN] - Handle to the CGenericFinishPage dialog
  296. //
  297. // Returns: BOOL, TRUE
  298. //
  299. BOOL CGenericFinishPage::OnCGenericFinishPagePageActivate(HWND hwndDlg)
  300. {
  301. TraceFileFunc(ttidWizard);
  302. HRESULT hr;
  303. CWizard* pWizard =
  304. reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
  305. Assert(NULL != pWizard);
  306. TraceTag(ttidWizard, "Entering generic page...");
  307. if (IsPostInstall(pWizard))
  308. {
  309. LPARAM lFlags = PSWIZB_BACK | PSWIZB_FINISH;
  310. PropSheet_SetWizButtons(GetParent(hwndDlg), lFlags);
  311. }
  312. ::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0);
  313. if (fIsMSNPresent())
  314. {
  315. ShowWindow(GetDlgItem(hwndDlg, IDC_SELECT_ISP_FINISH) , SW_HIDE);
  316. ShowWindow(GetDlgItem(hwndDlg, CHK_SETUP_MSN) , SW_SHOW);
  317. ShowWindow(GetDlgItem(hwndDlg, IDC_SELECT_MSN_ISP) , SW_SHOW);
  318. ShowWindow(GetDlgItem(hwndDlg, IDC_CLOSE_CHOICE_FINISH) , SW_SHOW);
  319. ShowWindow(GetDlgItem(hwndDlg, CHK_SELECTOTHER), SW_SHOW);
  320. }
  321. else
  322. {
  323. ShowWindow(GetDlgItem(hwndDlg, IDC_SELECT_ISP_FINISH) , SW_SHOW);
  324. ShowWindow(GetDlgItem(hwndDlg, CHK_SETUP_MSN) , SW_HIDE);
  325. ShowWindow(GetDlgItem(hwndDlg, IDC_SELECT_MSN_ISP) , SW_HIDE);
  326. ShowWindow(GetDlgItem(hwndDlg, IDC_CLOSE_CHOICE_FINISH) , SW_HIDE);
  327. ShowWindow(GetDlgItem(hwndDlg, CHK_SELECTOTHER), SW_HIDE);
  328. CheckDlgButton(hwndDlg, CHK_SELECTOTHER, BST_CHECKED);
  329. }
  330. return TRUE;
  331. }
  332. // ***************************************************************************
  333. //
  334. // Function: OnCGenericFinishPageInitDialog
  335. //
  336. // Purpose: Handle WM_INITDIALOG message
  337. //
  338. // Parameters: hwndDlg [IN] - Handle to the CGenericFinishPage dialog
  339. // lParam [IN] - LPARAM value from the WM_INITDIALOG message
  340. //
  341. // Returns: FALSE - Accept default control activation
  342. //
  343. BOOL CGenericFinishPage::OnCGenericFinishPageInitDialog(HWND hwndDlg, LPARAM lParam)
  344. {
  345. TraceFileFunc(ttidWizard);
  346. // Initialize our pointers to property sheet info.
  347. PROPSHEETPAGE* psp = (PROPSHEETPAGE*)lParam;
  348. Assert(psp->lParam);
  349. ::SetWindowLongPtr(hwndDlg, DWLP_USER, psp->lParam);
  350. CWizard * pWizard = reinterpret_cast<CWizard *>(psp->lParam);
  351. Assert(NULL != pWizard);
  352. SetupFonts(hwndDlg, &m_hBoldFont, TRUE);
  353. if (NULL != m_hBoldFont)
  354. {
  355. HWND hwndCtl = GetDlgItem(hwndDlg, IDC_WELCOME_CAPTION);
  356. if (hwndCtl)
  357. {
  358. SetWindowFont(hwndCtl, m_hBoldFont, TRUE);
  359. }
  360. }
  361. switch (m_dwMyIDD)
  362. {
  363. case IDD_FinishOtherWays:
  364. {
  365. INT nrgChks[] = {CHK_SETUP_MSN, CHK_SELECTOTHER};
  366. // Find the top most enabled radio button
  367. for (int nIdx = 0; nIdx < celems(nrgChks); nIdx++)
  368. {
  369. if (IsWindowEnabled(GetDlgItem(hwndDlg, nrgChks[nIdx])))
  370. {
  371. CheckRadioButton(hwndDlg, CHK_SETUP_MSN, CHK_SELECTOTHER, nrgChks[nIdx]);
  372. break;
  373. }
  374. }
  375. }
  376. break;
  377. default:
  378. break;
  379. }
  380. return FALSE; // Accept default control focus
  381. }
  382. BOOL CGenericFinishPage::CGenericFinishPagePageOnClick(HWND hwndDlg, UINT idFrom)
  383. {
  384. BOOL fRet = TRUE;
  385. switch (idFrom)
  386. {
  387. case IDC_ST_AUTOCONFIGLINK:
  388. {
  389. HRESULT hr = ShellExecuteFromCSIDL(hwndDlg, CSIDL_SYSTEM, c_szMigrationWiz, FALSE, 0);
  390. if (FAILED(hr))
  391. {
  392. fRet= FALSE;
  393. }
  394. }
  395. break;
  396. case IDC_ST_DSL_HELPLINK:
  397. // HtmlHelp(hwndDlg, L"netcfg.chm::/howto_highspeed_repair.htm", HH_DISPLAY_TOPIC, 0);
  398. ShellExecute(NULL, NULL, L"HELPCTR.EXE", L" -url hcp://services/subsite?node=TopLevelBucket_4/Hardware&topic=ms-its%3A%25HELP_LOCATION%25%5Cnetcfg.chm%3A%3A/howto_highspeed_repair.htm", NULL, SW_SHOWNORMAL);
  399. break;
  400. case IDC_ST_INTERNETLINK:
  401. // HtmlHelp(hwndDlg, L"netcfg.chm::/i_client.htm", HH_DISPLAY_TOPIC, 0);
  402. ShellExecute(NULL, NULL, L"HELPCTR.EXE", L" -url hcp://services/subsite?node=TopLevelBucket_4/Hardware&topic=ms-its%3A%25HELP_LOCATION%25%5Cnetcfg.chm%3A%3A/i_client.htm", NULL, SW_SHOWNORMAL);
  403. break;
  404. default:
  405. AssertSz(FALSE, "Unexpected notify message");
  406. }
  407. return fRet;
  408. }
  409. //
  410. // Function: CGenericFinishPage::CreateCGenericFinishPagePage
  411. //
  412. // Purpose: To determine if the CGenericFinishPage page needs to be shown, and to
  413. // to create the page if requested. Note the CGenericFinishPage page is
  414. // responsible for initial installs also.
  415. //
  416. // Parameters: idd [IN] - IDD of dialog
  417. // pWizard [IN] - Ptr to a Wizard instance
  418. // pData [IN] - Context data to describe the world in
  419. // which the Wizard will be run
  420. // fCountOnly [IN] - If True, only the maximum number of
  421. // pages this routine will create need
  422. // be determined.
  423. // pnPages [IN] - Increment by the number of pages
  424. // to create/created
  425. //
  426. // Returns: HRESULT, S_OK on success
  427. //
  428. HRESULT CGenericFinishPage::HrCreateCGenericFinishPagePage(DWORD idd, CWizard *pWizard, PINTERNAL_SETUP_DATA pData, BOOL fCountOnly, UINT *pnPages)
  429. {
  430. TraceFileFunc(ttidWizard);
  431. CGenericFinishPage *pCGenericFinishPage = new CGenericFinishPage;
  432. if (!pCGenericFinishPage)
  433. {
  434. return E_OUTOFMEMORY;
  435. }
  436. pCGenericFinishPage->m_dwMyIDD = idd;
  437. HRESULT hr = S_OK;
  438. if (IsPostInstall(pWizard) && ( ! pWizard->FProcessLanPages()))
  439. {
  440. (*pnPages)++;
  441. // If not only counting, create and register the page
  442. if ( ! fCountOnly)
  443. {
  444. LinkWindow_RegisterClass();
  445. HPROPSHEETPAGE hpsp;
  446. PROPSHEETPAGE psp;
  447. ZeroMemory(&psp, sizeof(PROPSHEETPAGE));
  448. TraceTag(ttidWizard, "Creating CGenericFinishPage Page for IID %d", idd);
  449. psp.dwSize = sizeof( PROPSHEETPAGE );
  450. psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
  451. psp.hInstance = _Module.GetResourceInstance();
  452. psp.pszTemplate = MAKEINTRESOURCE( idd );
  453. psp.hIcon = NULL;
  454. psp.pfnDlgProc = CGenericFinishPage::dlgprocCGenericFinishPage;
  455. psp.lParam = reinterpret_cast<LPARAM>(pWizard);
  456. hpsp = CreatePropertySheetPage( &psp );
  457. if (hpsp)
  458. {
  459. pWizard->RegisterPage(idd, hpsp,
  460. CGenericFinishPage::CGenericFinishPagePageCleanup, idd);
  461. m_dwIddList[idd] = pCGenericFinishPage;
  462. }
  463. else
  464. {
  465. hr = E_OUTOFMEMORY;
  466. }
  467. }
  468. }
  469. TraceHr(ttidWizard, FAL, hr, FALSE, "HrCreateCGenericFinishPagePage");
  470. return hr;
  471. }
  472. //
  473. // Function: CGenericFinishPage::AppendCGenericFinishPagePage
  474. //
  475. // Purpose: Add the CGenericFinishPage page, if it was created, to the set of pages
  476. // that will be displayed.
  477. //
  478. // Parameters: idd [IN] - IDD of the dialog - should be created with HrCreateCGenericFinishPagePage first.
  479. // pWizard [IN] - Ptr to Wizard Instance
  480. // pahpsp [IN,OUT] - Array of pages to add our page to
  481. // pcPages [IN,OUT] - Count of pages in pahpsp
  482. //
  483. // Returns: Nothing
  484. //
  485. VOID CGenericFinishPage::AppendCGenericFinishPagePage(DWORD idd, CWizard *pWizard, HPROPSHEETPAGE* pahpsp, UINT *pcPages)
  486. {
  487. TraceFileFunc(ttidWizard);
  488. if (IsPostInstall(pWizard) && ( ! pWizard->FProcessLanPages()))
  489. {
  490. HPROPSHEETPAGE hPage = pWizard->GetPageHandle(idd);
  491. Assert(hPage);
  492. pahpsp[*pcPages] = hPage;
  493. (*pcPages)++;
  494. }
  495. }
  496. //
  497. // Function: CGenericFinishPage::dlgproCGenericFinishPage
  498. //
  499. // Purpose: Dialog Procedure for the CGenericFinishPage wizard page
  500. //
  501. // Parameters: standard dlgproc parameters
  502. //
  503. // Returns: INT_PTR
  504. //
  505. INT_PTR CALLBACK CGenericFinishPage::dlgprocCGenericFinishPage( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  506. {
  507. TraceFileFunc(ttidWizard);
  508. BOOL frt = FALSE;
  509. CGenericFinishPage *pCGenericFinishPage = NULL;
  510. // Can't do a GetCGenericFinishPageFromHWND over here, since it will recurse & stack overflow.
  511. switch (uMsg)
  512. {
  513. case WM_INITDIALOG:
  514. {
  515. PROPSHEETPAGE *pPropSheetPage = reinterpret_cast<PROPSHEETPAGE *>(lParam);
  516. if (FAILED(GetCGenericFinishPageFromIDD(MAKERESOURCEINT(pPropSheetPage->pszTemplate), &pCGenericFinishPage)))
  517. {
  518. return FALSE;
  519. }
  520. frt = pCGenericFinishPage->OnCGenericFinishPageInitDialog(hwndDlg, lParam);
  521. }
  522. break;
  523. case WM_NOTIFY:
  524. {
  525. LPNMHDR pnmh = (LPNMHDR)lParam;
  526. switch (pnmh->code)
  527. {
  528. case NM_CLICK:
  529. if (FAILED(GetCGenericFinishPageFromHWND(hwndDlg, &pCGenericFinishPage)))
  530. {
  531. return FALSE;
  532. }
  533. frt = pCGenericFinishPage->CGenericFinishPagePageOnClick(hwndDlg, pnmh->idFrom);
  534. break;
  535. // propsheet notification
  536. case PSN_HELP:
  537. break;
  538. case PSN_SETACTIVE:
  539. if (FAILED(GetCGenericFinishPageFromHWND(hwndDlg, &pCGenericFinishPage)))
  540. {
  541. return FALSE;
  542. }
  543. frt = pCGenericFinishPage->OnCGenericFinishPagePageActivate(hwndDlg);
  544. break;
  545. case PSN_APPLY:
  546. break;
  547. case PSN_KILLACTIVE:
  548. break;
  549. case PSN_RESET:
  550. break;
  551. case PSN_WIZBACK:
  552. if (FAILED(GetCGenericFinishPageFromHWND(hwndDlg, &pCGenericFinishPage)))
  553. {
  554. return FALSE;
  555. }
  556. frt = pCGenericFinishPage->OnCGenericFinishPagePageBack(hwndDlg);
  557. break;
  558. case PSN_WIZFINISH:
  559. if (FAILED(GetCGenericFinishPageFromHWND(hwndDlg, &pCGenericFinishPage)))
  560. {
  561. return FALSE;
  562. }
  563. frt = pCGenericFinishPage->OnCGenericFinishPagePageNext(hwndDlg);
  564. break;
  565. case PSN_WIZNEXT:
  566. if (FAILED(GetCGenericFinishPageFromHWND(hwndDlg, &pCGenericFinishPage)))
  567. {
  568. return FALSE;
  569. }
  570. frt = pCGenericFinishPage->OnCGenericFinishPagePageNext(hwndDlg);
  571. break;
  572. default:
  573. break;
  574. }
  575. }
  576. break;
  577. default:
  578. break;
  579. }
  580. return( frt );
  581. }
  582. //
  583. // Function: CGenericFinishPage::CGenericFinishPagePageCleanup
  584. //
  585. // Purpose: As a callback function to allow any page allocated memory
  586. // to be cleaned up, after the page will no longer be accessed.
  587. //
  588. // Parameters: pWizard [IN] - The wizard against which the page called
  589. // register page
  590. // lParam [IN] - The lParam supplied in the RegisterPage call
  591. //
  592. // Returns: nothing
  593. //
  594. VOID CGenericFinishPage::CGenericFinishPagePageCleanup(CWizard *pWizard, LPARAM lParam)
  595. {
  596. TraceFileFunc(ttidWizard);
  597. Assert(lParam);
  598. CGenericFinishPage *pCGenericFinishPage;
  599. if (FAILED(GetCGenericFinishPageFromIDD(lParam, &pCGenericFinishPage)))
  600. {
  601. AssertSz(FALSE, "Could not find page");
  602. return;
  603. }
  604. if (IsPostInstall(pWizard))
  605. {
  606. LinkWindow_UnregisterClass(_Module.GetResourceInstance());
  607. if (NULL != pCGenericFinishPage->m_hBoldFont)
  608. DeleteObject(pCGenericFinishPage->m_hBoldFont);
  609. // 1 means it removed 1 element
  610. Assert(1 == CGenericFinishPage::m_dwIddList.erase(pCGenericFinishPage->m_dwMyIDD));
  611. delete pCGenericFinishPage;
  612. }
  613. }
  614. HRESULT CGenericFinishPage::GetCGenericFinishPageFromIDD(DWORD idd, CGenericFinishPage **pCGenericFinishPage)
  615. {
  616. AssertSz(pCGenericFinishPage, "Invalid pointer to GetCGenericFinishPageFromHWND");
  617. if (!pCGenericFinishPage)
  618. {
  619. return E_POINTER;
  620. }
  621. IDDLIST::const_iterator iter = CGenericFinishPage::m_dwIddList.find(idd);
  622. if (iter != CGenericFinishPage::m_dwIddList.end())
  623. {
  624. *pCGenericFinishPage = iter->second;
  625. }
  626. else
  627. {
  628. AssertSz(FALSE, "Could not find this page in the IDD map");
  629. return E_FAIL;
  630. }
  631. return S_OK;
  632. }
  633. HRESULT CGenericFinishPage::GetCGenericFinishPageFromHWND(HWND hwndDlg, CGenericFinishPage **pCGenericFinishPage)
  634. {
  635. AssertSz(pCGenericFinishPage, "Invalid pointer to GetCGenericFinishPageFromHWND");
  636. if (!pCGenericFinishPage)
  637. {
  638. return E_POINTER;
  639. }
  640. *pCGenericFinishPage = NULL;
  641. int iIndex = PropSheet_HwndToIndex(GetParent(hwndDlg), hwndDlg);
  642. AssertSz(-1 != iIndex, "Could not convert HWND to Index");
  643. if (-1 == iIndex)
  644. {
  645. return E_FAIL;
  646. }
  647. int iIdd = PropSheet_IndexToId(GetParent(hwndDlg), iIndex);
  648. AssertSz(iIdd, "Could not convert Index to IDD");
  649. if (!iIdd)
  650. {
  651. return E_FAIL;
  652. }
  653. return GetCGenericFinishPageFromIDD(iIdd, pCGenericFinishPage);
  654. }