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.

671 lines
17 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: firstpin.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "pch.h"
  11. #pragma hdrstop
  12. #include "firstpin.h"
  13. #include "folder.h"
  14. #include "msgbox.h"
  15. #include "cscst.h"
  16. #include "syncmgr.h"
  17. #include "strings.h"
  18. //
  19. // Base class for all "first pin" wizard pages.
  20. // Contains the single dialog proc used for all pages. Specialization
  21. // for individual pages is achieved through deriviation and implementing
  22. // virtual functions.
  23. //
  24. class CWizardPage
  25. {
  26. public:
  27. enum { WM_WIZARDFINISHED = (WM_USER + 1) };
  28. CWizardPage(HINSTANCE hInstance,
  29. UINT idDlgTemplate,
  30. UINT idsHdrTitle,
  31. UINT idsHdrSubtitle,
  32. DWORD dwPgFlags,
  33. DWORD dwBtnFlags);
  34. virtual ~CWizardPage(void);
  35. UINT GetDlgTemplate(void) const
  36. { return m_idDlgTemplate; }
  37. UINT GetHeaderTitle(void) const
  38. { return m_idsHdrTitle; }
  39. UINT GetHeaderSubtitle(void) const
  40. { return m_idsHdrSubtitle; }
  41. DWORD GetPageFlags(void) const
  42. { return m_dwPgFlags; }
  43. DWORD GetBtnFlags(void) const
  44. { return m_dwBtnFlags; }
  45. DLGPROC GetDlgProc(void) const
  46. { return DlgProc; }
  47. virtual BOOL OnInitDialog(WPARAM wParam, LPARAM lParam)
  48. { return TRUE; }
  49. virtual BOOL OnPSNSetActive(void);
  50. virtual BOOL OnPSNWizFinish(void)
  51. { SetWindowLong(m_hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); return FALSE; }
  52. virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam)
  53. { return FALSE; }
  54. virtual BOOL OnWizardFinished(void) { return FALSE; }
  55. protected:
  56. HINSTANCE m_hInstance;
  57. HWND m_hwndDlg;
  58. HFONT m_hTitleFont; // Used only by cover and finish pages.
  59. UINT m_cyTitleFontHt; // Title font height in pts.
  60. int FontPtsToHt(HWND hwnd, int pts);
  61. BOOL FormatTitleFont(UINT idcTitle);
  62. private:
  63. UINT m_idDlgTemplate; // Dialog resource template.
  64. UINT m_idsHdrTitle; // String ID for pg header title.
  65. UINT m_idsHdrSubtitle; // String ID for pg header subtitle.
  66. DWORD m_dwBtnFlags; // PSB_WIZXXXXX flags.
  67. DWORD m_dwPgFlags; // PSP_XXXX flags.
  68. static INT_PTR CALLBACK DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  69. };
  70. //
  71. // Welcome page.
  72. //
  73. class CWizardPgWelcome : public CWizardPage
  74. {
  75. public:
  76. CWizardPgWelcome(HINSTANCE hInstance,
  77. UINT idDlgTemplate,
  78. UINT idsHdrTitle,
  79. UINT idsHdrSubtitle,
  80. DWORD dwPgFlags,
  81. DWORD dwBtnFlags
  82. ) : CWizardPage(hInstance,
  83. idDlgTemplate,
  84. idsHdrTitle,
  85. idsHdrSubtitle,
  86. dwPgFlags,
  87. dwBtnFlags)
  88. { }
  89. BOOL OnInitDialog(WPARAM wParam, LPARAM lParam);
  90. };
  91. //
  92. // Pinning page.
  93. //
  94. class CWizardPgPin : public CWizardPage
  95. {
  96. public:
  97. CWizardPgPin(HINSTANCE hInstance,
  98. UINT idDlgTemplate,
  99. UINT idsHdrTitle,
  100. UINT idsHdrSubtitle,
  101. DWORD dwPgFlags,
  102. DWORD dwBtnFlags
  103. ) : CWizardPage(hInstance,
  104. idDlgTemplate,
  105. idsHdrTitle,
  106. idsHdrSubtitle,
  107. dwPgFlags,
  108. dwBtnFlags) { }
  109. BOOL OnInitDialog(WPARAM wParam, LPARAM lParam);
  110. BOOL OnWizardFinished(void);
  111. };
  112. //
  113. // Offline page.
  114. //
  115. class CWizardPgOffline : public CWizardPage
  116. {
  117. public:
  118. CWizardPgOffline(HINSTANCE hInstance,
  119. UINT idDlgTemplate,
  120. UINT idsHdrTitle,
  121. UINT idsHdrSubtitle,
  122. DWORD dwPgFlags,
  123. DWORD dwBtnFlags
  124. ) : CWizardPage(hInstance,
  125. idDlgTemplate,
  126. idsHdrTitle,
  127. idsHdrSubtitle,
  128. dwPgFlags,
  129. dwBtnFlags) { }
  130. BOOL OnInitDialog(WPARAM wParam, LPARAM lParam);
  131. BOOL OnPSNWizFinish(void);
  132. BOOL OnWizardFinished(void);
  133. };
  134. //
  135. // Class encapsulating the functionality of the entire wizard.
  136. // It contains member instances of each of the page types.
  137. //
  138. class CFirstPinWizard
  139. {
  140. public:
  141. CFirstPinWizard(HINSTANCE hInstance, HWND hwndParent);
  142. HRESULT Run(void);
  143. private:
  144. enum { PG_WELCOME,
  145. PG_PIN,
  146. PG_OFFLINE,
  147. PG_NUMPAGES };
  148. HINSTANCE m_hInstance;
  149. HWND m_hwndParent;
  150. CWizardPgWelcome m_PgWelcome;
  151. CWizardPgPin m_PgPin;
  152. CWizardPgOffline m_PgOffline;
  153. CWizardPage *m_rgpWizPages[PG_NUMPAGES];
  154. };
  155. //
  156. // CWizardPage members --------------------------------------------------------
  157. //
  158. CWizardPage::CWizardPage(
  159. HINSTANCE hInstance,
  160. UINT idDlgTemplate,
  161. UINT idsHdrTitle,
  162. UINT idsHdrSubtitle,
  163. DWORD dwPgFlags,
  164. DWORD dwBtnFlags
  165. ) : m_hInstance(hInstance),
  166. m_idDlgTemplate(idDlgTemplate),
  167. m_idsHdrTitle(idsHdrTitle),
  168. m_idsHdrSubtitle(idsHdrSubtitle),
  169. m_dwPgFlags(dwPgFlags),
  170. m_dwBtnFlags(dwBtnFlags),
  171. m_cyTitleFontHt(12),
  172. m_hwndDlg(NULL),
  173. m_hTitleFont(NULL)
  174. {
  175. //
  176. // Get the title font height from a resource string. That way localizers can
  177. // play with the font dimensions if necessary.
  178. //
  179. TCHAR szFontHt[20];
  180. if (0 < LoadString(m_hInstance, IDS_FIRSTPIN_FONTHT_PTS, szFontHt, ARRAYSIZE(szFontHt)))
  181. {
  182. m_cyTitleFontHt = StrToInt(szFontHt);
  183. }
  184. }
  185. CWizardPage::~CWizardPage(
  186. void
  187. )
  188. {
  189. if (NULL != m_hTitleFont)
  190. {
  191. DeleteObject(m_hTitleFont);
  192. }
  193. }
  194. //
  195. // PSN_SETACTIVE handler.
  196. //
  197. BOOL
  198. CWizardPage::OnPSNSetActive(
  199. void
  200. )
  201. {
  202. PropSheet_SetWizButtons(GetParent(m_hwndDlg), m_dwBtnFlags);
  203. return FALSE;
  204. }
  205. //
  206. // Dialog proc used by all pages in this wizard.
  207. //
  208. INT_PTR CALLBACK
  209. CWizardPage::DlgProc(
  210. HWND hwnd,
  211. UINT uMsg,
  212. WPARAM wParam,
  213. LPARAM lParam
  214. )
  215. {
  216. CWizardPage *pPage = (CWizardPage *)GetWindowLongPtr(hwnd, DWLP_USER);
  217. BOOL bResult = FALSE;
  218. switch(uMsg)
  219. {
  220. case WM_INITDIALOG:
  221. {
  222. PROPSHEETPAGE *ppsp = (PROPSHEETPAGE *)lParam;
  223. pPage = (CWizardPage *)ppsp->lParam;
  224. TraceAssert(NULL != pPage);
  225. SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)pPage);
  226. pPage->m_hwndDlg = hwnd;
  227. bResult = pPage->OnInitDialog(wParam, lParam);
  228. break;
  229. }
  230. case WM_COMMAND:
  231. if (NULL != pPage)
  232. bResult = pPage->OnCommand(wParam, lParam);
  233. break;
  234. case WM_NOTIFY:
  235. switch(((LPNMHDR)lParam)->code)
  236. {
  237. case PSN_SETACTIVE:
  238. bResult = pPage->OnPSNSetActive();
  239. break;
  240. case PSN_WIZFINISH:
  241. bResult = pPage->OnPSNWizFinish();
  242. break;
  243. }
  244. break;
  245. case PSM_QUERYSIBLINGS:
  246. if (CWizardPage::WM_WIZARDFINISHED == wParam)
  247. bResult = pPage->OnWizardFinished();
  248. break;
  249. default:
  250. break;
  251. }
  252. return bResult;
  253. }
  254. //
  255. // Helper function to convert a font point size to a height value
  256. // used in a LOGFONT structure.
  257. //
  258. int
  259. CWizardPage::FontPtsToHt(
  260. HWND hwnd,
  261. int pts
  262. )
  263. {
  264. int ht = 10;
  265. HDC hdc = GetDC(hwnd);
  266. if (NULL != hdc)
  267. {
  268. ht = -MulDiv(pts, GetDeviceCaps(hdc, LOGPIXELSY), 72);
  269. ReleaseDC(hwnd, hdc);
  270. }
  271. return ht;
  272. }
  273. //
  274. // The title text on the cover and finish pages is enlarged and bold.
  275. // This code modifies the text in the dialog accordingly.
  276. // On return, m_hTitleFont contains the handle to the title font.
  277. //
  278. BOOL
  279. CWizardPage::FormatTitleFont(
  280. UINT idcTitle
  281. )
  282. {
  283. BOOL bResult = FALSE;
  284. HWND hwndTitle = GetDlgItem(m_hwndDlg, idcTitle);
  285. HFONT hFont = (HFONT)SendMessage(hwndTitle, WM_GETFONT, 0, 0);
  286. if (NULL != hFont)
  287. {
  288. if (NULL == m_hTitleFont)
  289. {
  290. LOGFONT lf;
  291. if (GetObject(hFont, sizeof(lf), &lf))
  292. {
  293. lf.lfHeight = FontPtsToHt(hwndTitle, m_cyTitleFontHt);
  294. m_hTitleFont = CreateFontIndirect(&lf);
  295. }
  296. }
  297. if (NULL != m_hTitleFont)
  298. {
  299. SendMessage(hwndTitle, WM_SETFONT, (WPARAM)m_hTitleFont, 0);
  300. bResult = TRUE;
  301. }
  302. }
  303. return bResult;
  304. }
  305. //
  306. // CWizardPgWelcome members -----------------------------------------------------
  307. //
  308. //
  309. // WM_INITDIALOG handler.
  310. //
  311. BOOL
  312. CWizardPgWelcome::OnInitDialog(
  313. WPARAM wParam,
  314. LPARAM lParam
  315. )
  316. {
  317. FormatTitleFont(IDC_TXT_FIRSTPIN_WELCOME_TITLE);
  318. return CWizardPage::OnInitDialog(wParam, lParam);
  319. }
  320. //
  321. // CWizardPgPin members -------------------------------------------------------
  322. //
  323. //
  324. // WM_INITDIALOG handler.
  325. //
  326. BOOL
  327. CWizardPgPin::OnInitDialog(
  328. WPARAM wParam,
  329. LPARAM lParam
  330. )
  331. {
  332. HRESULT hr = IsRegisteredForSyncAtLogonAndLogoff();
  333. CheckDlgButton(m_hwndDlg,
  334. IDC_CBX_FIRSTPIN_AUTOSYNC,
  335. S_OK == hr ? BST_CHECKED : BST_UNCHECKED);
  336. return CWizardPage::OnInitDialog(wParam, lParam);
  337. }
  338. //
  339. // PSN_WIZFINISH handler.
  340. //
  341. BOOL
  342. CWizardPgPin::OnWizardFinished(
  343. void
  344. )
  345. {
  346. HRESULT hr;
  347. RegisterSyncMgrHandler(TRUE);
  348. if (BST_CHECKED == IsDlgButtonChecked(m_hwndDlg, IDC_CBX_FIRSTPIN_AUTOSYNC))
  349. {
  350. const DWORD dwFlags = SYNCMGRREGISTERFLAG_CONNECT | SYNCMGRREGISTERFLAG_PENDINGDISCONNECT;
  351. hr = RegisterForSyncAtLogonAndLogoff(dwFlags, dwFlags);
  352. if (SUCCEEDED(hr))
  353. {
  354. SetSyncMgrInitialized();
  355. }
  356. else
  357. {
  358. CscMessageBox(m_hwndDlg,
  359. MB_OK | MB_ICONERROR,
  360. Win32Error(HRESULT_CODE(hr)),
  361. m_hInstance,
  362. IDS_ERR_REGSYNCATLOGONLOGOFF);
  363. }
  364. }
  365. return CWizardPage::OnWizardFinished();
  366. }
  367. //
  368. // CWizardPgOffline members ---------------------------------------------------
  369. //
  370. //
  371. // WM_INITDIALOG handler.
  372. //
  373. BOOL
  374. CWizardPgOffline::OnInitDialog(
  375. WPARAM wParam,
  376. LPARAM lParam
  377. )
  378. {
  379. //
  380. // If policy allows configuration of the reminders, check the "enable reminders"
  381. // checkbox.
  382. //
  383. CConfig& config = CConfig::GetSingleton();
  384. bool bNoConfigReminders;
  385. bool bNoCacheViewer = config.NoCacheViewer();
  386. config.NoReminders(&bNoConfigReminders);
  387. CheckDlgButton(m_hwndDlg, IDC_CBX_REMINDERS, !bNoConfigReminders);
  388. EnableWindow(GetDlgItem(m_hwndDlg, IDC_CBX_REMINDERS), !bNoConfigReminders);
  389. CheckDlgButton(m_hwndDlg, IDC_CBX_FIRSTPIN_FLDRLNK, BST_UNCHECKED);
  390. EnableWindow(GetDlgItem(m_hwndDlg, IDC_CBX_FIRSTPIN_FLDRLNK), !bNoCacheViewer);
  391. return CWizardPage::OnInitDialog(wParam, lParam);
  392. }
  393. //
  394. // PSN_WIZFINISH handler.
  395. //
  396. BOOL
  397. CWizardPgOffline::OnPSNWizFinish(
  398. void
  399. )
  400. {
  401. //
  402. // Send PSM_QUERYSIBLINGS to all of the pages with
  403. // wParam set to WM_WIZARDFINISHED. This will trigger
  404. // a call to the virtual function OnWizardFinished()
  405. // allowing each page to respond to the successful completion
  406. // of the wizard.
  407. //
  408. PropSheet_QuerySiblings(GetParent(m_hwndDlg),
  409. CWizardPage::WM_WIZARDFINISHED,
  410. 0);
  411. //
  412. // Now handle for this page.
  413. //
  414. OnWizardFinished();
  415. return CWizardPage::OnPSNWizFinish();
  416. }
  417. //
  418. // PSN_WIZFINISH handler.
  419. //
  420. BOOL
  421. CWizardPgOffline::OnWizardFinished(
  422. void
  423. )
  424. {
  425. bool bEnableReminders = (BST_CHECKED == IsDlgButtonChecked(m_hwndDlg, IDC_CBX_REMINDERS));
  426. DWORD dwValue;
  427. DWORD dwErr;
  428. dwValue = bEnableReminders ? 0 : 1;
  429. dwErr = SHSetValue(HKEY_CURRENT_USER,
  430. REGSTR_KEY_OFFLINEFILES,
  431. REGSTR_VAL_NOREMINDERS,
  432. REG_DWORD,
  433. &dwValue,
  434. sizeof(dwValue));
  435. if (bEnableReminders)
  436. {
  437. PostToSystray(PWM_RESET_REMINDERTIMER, 0, 0);
  438. }
  439. if (BST_CHECKED == IsDlgButtonChecked(m_hwndDlg, IDC_CBX_FIRSTPIN_FLDRLNK))
  440. {
  441. COfflineFilesFolder::CreateLinkOnDesktop(m_hwndDlg);
  442. }
  443. return CWizardPage::OnWizardFinished();
  444. }
  445. //
  446. // CFirstPinWizard members ----------------------------------------------------
  447. //
  448. CFirstPinWizard::CFirstPinWizard(
  449. HINSTANCE hInstance,
  450. HWND hwndParent
  451. ) : m_hInstance(hInstance),
  452. m_hwndParent(hwndParent),
  453. m_PgWelcome(hInstance,
  454. IDD_FIRSTPIN_WELCOME,
  455. 0,
  456. 0,
  457. PSP_DEFAULT,
  458. PSWIZB_NEXT),
  459. m_PgPin(hInstance,
  460. IDD_FIRSTPIN_PIN,
  461. 0,
  462. 0,
  463. PSP_DEFAULT,
  464. PSWIZB_NEXT | PSWIZB_BACK),
  465. m_PgOffline(hInstance,
  466. IDD_FIRSTPIN_OFFLINE,
  467. 0,
  468. 0,
  469. PSP_DEFAULT,
  470. PSWIZB_FINISH | PSWIZB_BACK)
  471. {
  472. //
  473. // Store pointers to each page in an array. Makes creating the
  474. // prop sheet easier in Run().
  475. //
  476. m_rgpWizPages[0] = &m_PgWelcome;
  477. m_rgpWizPages[1] = &m_PgPin;
  478. m_rgpWizPages[2] = &m_PgOffline;
  479. }
  480. //
  481. // Creates the wizard and runs it.
  482. // The wizard runs modally.
  483. //
  484. // Returns:
  485. //
  486. // S_OK = User completed wizard and pressed "Finish".
  487. // S_FALSE = User pressed "Cancel" in wizard.
  488. // Other = Error creating wizard.
  489. //
  490. HRESULT
  491. CFirstPinWizard::Run(
  492. void
  493. )
  494. {
  495. HRESULT hr = NOERROR;
  496. PROPSHEETHEADER psh;
  497. PROPSHEETPAGE psp;
  498. HPROPSHEETPAGE rghpage[ARRAYSIZE(m_rgpWizPages)];
  499. ZeroMemory(&psh, sizeof(psh));
  500. ZeroMemory(rghpage, sizeof(rghpage));
  501. psh.dwSize = sizeof(psh);
  502. psh.dwFlags = PSH_WIZARD_LITE;
  503. psh.hwndParent = m_hwndParent;
  504. psh.hInstance = m_hInstance;
  505. psh.nPages = ARRAYSIZE(rghpage);
  506. psh.phpage = rghpage;
  507. for (int i = 0; i < ARRAYSIZE(rghpage) && SUCCEEDED(hr); i++)
  508. {
  509. CWizardPage *pwp = m_rgpWizPages[i];
  510. ZeroMemory(&psp, sizeof(psp));
  511. psp.dwSize = sizeof(psp);
  512. psp.dwFlags |= pwp->GetPageFlags();
  513. psp.hInstance = m_hInstance;
  514. psp.pszTemplate = MAKEINTRESOURCE(pwp->GetDlgTemplate());
  515. psp.pfnDlgProc = pwp->GetDlgProc();
  516. psp.lParam = (LPARAM)pwp;
  517. rghpage[i] = CreatePropertySheetPage(&psp);
  518. if (NULL == rghpage[i])
  519. {
  520. while(0 <= --i)
  521. {
  522. DestroyPropertySheetPage(rghpage[i]);
  523. }
  524. hr = E_FAIL;
  525. }
  526. }
  527. if (SUCCEEDED(hr))
  528. {
  529. switch(PropertySheet(&psh))
  530. {
  531. case -1:
  532. hr = HRESULT_FROM_WIN32(GetLastError());
  533. break;
  534. case 0:
  535. hr = S_FALSE; // User pressed "Cancel".
  536. break;
  537. case 1:
  538. hr = S_OK; // User pressed "Finish".
  539. break;
  540. }
  541. }
  542. return hr;
  543. }
  544. //
  545. // This is the function you call when you want to run the wizard.
  546. // It merely creates a wizard object and tells it to run.
  547. // If the user finishes the wizard, it records this fact in the
  548. // registry. Calling FirstPinWizardCompleted() will tell
  549. // you later if the user has finished the wizard.
  550. //
  551. // Returns:
  552. //
  553. // S_OK = User completed wizard and pressed "Finish".
  554. // S_FALSE = User cancelled out of wizard.
  555. // Other = Error creating wizard.
  556. //
  557. HRESULT
  558. ShowFirstPinWizard(
  559. HWND hwndParent
  560. )
  561. {
  562. HRESULT hr = NOERROR;
  563. CFirstPinWizard Wizard(g_hInstance, hwndParent);
  564. hr = Wizard.Run();
  565. if (S_OK == hr)
  566. {
  567. //
  568. // Only record "finished" in registry if user
  569. // pressed "finish".
  570. //
  571. DWORD dwValue = 1;
  572. SHSetValue(HKEY_CURRENT_USER, REGSTR_KEY_OFFLINEFILES, REGSTR_VAL_FIRSTPINWIZARDSHOWN, REG_DWORD, &dwValue, sizeof(dwValue));
  573. }
  574. return hr;
  575. }
  576. //
  577. // Has user seen the wizard and pressed "finish"?
  578. //
  579. bool
  580. FirstPinWizardCompleted(
  581. void
  582. )
  583. {
  584. return CConfig::GetSingleton().FirstPinWizardShown();
  585. }