//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1997 - 1999 // // File: firstpin.cpp // //-------------------------------------------------------------------------- #include "pch.h" #pragma hdrstop #include "firstpin.h" #include "folder.h" #include "idlhelp.h" #include "msgbox.h" #include "cscst.h" #include "syncmgr.h" #include "strings.h" // // Base class for all "first pin" wizard pages. // Contains the single dialog proc used for all pages. Specialization // for individual pages is achieved through deriviation and implementing // virtual functions. // class CWizardPage { public: enum { WM_WIZARDFINISHED = (WM_USER + 1) }; CWizardPage(HINSTANCE hInstance, UINT idDlgTemplate, UINT idsHdrTitle, UINT idsHdrSubtitle, DWORD dwPgFlags, DWORD dwBtnFlags); virtual ~CWizardPage(void); UINT GetDlgTemplate(void) const { return m_idDlgTemplate; } UINT GetHeaderTitle(void) const { return m_idsHdrTitle; } UINT GetHeaderSubtitle(void) const { return m_idsHdrSubtitle; } DWORD GetPageFlags(void) const { return m_dwPgFlags; } DWORD GetBtnFlags(void) const { return m_dwBtnFlags; } DLGPROC GetDlgProc(void) const { return DlgProc; } virtual BOOL OnInitDialog(WPARAM wParam, LPARAM lParam) { return TRUE; } virtual BOOL OnPSNSetActive(void); virtual BOOL OnPSNWizFinish(void) { SetWindowLong(m_hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); return FALSE; } virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam) { return FALSE; } virtual BOOL OnWizardFinished(void) { return FALSE; } protected: HINSTANCE m_hInstance; HWND m_hwndDlg; HFONT m_hTitleFont; // Used only by cover and finish pages. UINT m_cyTitleFontHt; // Title font height in pts. int FontPtsToHt(HWND hwnd, int pts); BOOL FormatTitleFont(UINT idcTitle); private: UINT m_idDlgTemplate; // Dialog resource template. UINT m_idsHdrTitle; // String ID for pg header title. UINT m_idsHdrSubtitle; // String ID for pg header subtitle. DWORD m_dwBtnFlags; // PSB_WIZXXXXX flags. DWORD m_dwPgFlags; // PSP_XXXX flags. static INT_PTR CALLBACK DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); }; // // Welcome page. // class CWizardPgWelcome : public CWizardPage { public: CWizardPgWelcome(HINSTANCE hInstance, UINT idDlgTemplate, UINT idsHdrTitle, UINT idsHdrSubtitle, DWORD dwPgFlags, DWORD dwBtnFlags ) : CWizardPage(hInstance, idDlgTemplate, idsHdrTitle, idsHdrSubtitle, dwPgFlags, dwBtnFlags) { } BOOL OnInitDialog(WPARAM wParam, LPARAM lParam); }; // // Pinning page. // class CWizardPgPin : public CWizardPage { public: CWizardPgPin(HINSTANCE hInstance, UINT idDlgTemplate, UINT idsHdrTitle, UINT idsHdrSubtitle, DWORD dwPgFlags, DWORD dwBtnFlags ) : CWizardPage(hInstance, idDlgTemplate, idsHdrTitle, idsHdrSubtitle, dwPgFlags, dwBtnFlags) { } BOOL OnInitDialog(WPARAM wParam, LPARAM lParam); BOOL OnWizardFinished(void); }; // // Offline page. // class CWizardPgOffline : public CWizardPage { public: CWizardPgOffline(HINSTANCE hInstance, UINT idDlgTemplate, UINT idsHdrTitle, UINT idsHdrSubtitle, DWORD dwPgFlags, DWORD dwBtnFlags ) : CWizardPage(hInstance, idDlgTemplate, idsHdrTitle, idsHdrSubtitle, dwPgFlags, dwBtnFlags) { } BOOL OnInitDialog(WPARAM wParam, LPARAM lParam); BOOL OnPSNWizFinish(void); BOOL OnWizardFinished(void); }; // // Class encapsulating the functionality of the entire wizard. // It contains member instances of each of the page types. // class CFirstPinWizard { public: CFirstPinWizard(HINSTANCE hInstance, HWND hwndParent); HRESULT Run(void); private: enum { PG_WELCOME, PG_PIN, PG_OFFLINE, PG_NUMPAGES }; HINSTANCE m_hInstance; HWND m_hwndParent; CWizardPgWelcome m_PgWelcome; CWizardPgPin m_PgPin; CWizardPgOffline m_PgOffline; CWizardPage *m_rgpWizPages[PG_NUMPAGES]; }; // // CWizardPage members -------------------------------------------------------- // CWizardPage::CWizardPage( HINSTANCE hInstance, UINT idDlgTemplate, UINT idsHdrTitle, UINT idsHdrSubtitle, DWORD dwPgFlags, DWORD dwBtnFlags ) : m_hInstance(hInstance), m_idDlgTemplate(idDlgTemplate), m_idsHdrTitle(idsHdrTitle), m_idsHdrSubtitle(idsHdrSubtitle), m_dwPgFlags(dwPgFlags), m_dwBtnFlags(dwBtnFlags), m_cyTitleFontHt(12), m_hwndDlg(NULL), m_hTitleFont(NULL) { // // Get the title font height from a resource string. That way localizers can // play with the font dimensions if necessary. // TCHAR szFontHt[20]; if (0 < LoadString(m_hInstance, IDS_FIRSTPIN_FONTHT_PTS, szFontHt, ARRAYSIZE(szFontHt))) { m_cyTitleFontHt = StrToInt(szFontHt); } } CWizardPage::~CWizardPage( void ) { if (NULL != m_hTitleFont) { DeleteObject(m_hTitleFont); } } // // PSN_SETACTIVE handler. // BOOL CWizardPage::OnPSNSetActive( void ) { PropSheet_SetWizButtons(GetParent(m_hwndDlg), m_dwBtnFlags); return FALSE; } // // Dialog proc used by all pages in this wizard. // INT_PTR CALLBACK CWizardPage::DlgProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { CWizardPage *pPage = (CWizardPage *)GetWindowLongPtr(hwnd, DWLP_USER); BOOL bResult = FALSE; switch(uMsg) { case WM_INITDIALOG: { PROPSHEETPAGE *ppsp = (PROPSHEETPAGE *)lParam; pPage = (CWizardPage *)ppsp->lParam; TraceAssert(NULL != pPage); SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)pPage); pPage->m_hwndDlg = hwnd; bResult = pPage->OnInitDialog(wParam, lParam); break; } case WM_COMMAND: if (NULL != pPage) bResult = pPage->OnCommand(wParam, lParam); break; case WM_NOTIFY: switch(((LPNMHDR)lParam)->code) { case PSN_SETACTIVE: bResult = pPage->OnPSNSetActive(); break; case PSN_WIZFINISH: bResult = pPage->OnPSNWizFinish(); break; } break; case PSM_QUERYSIBLINGS: if (CWizardPage::WM_WIZARDFINISHED == wParam) bResult = pPage->OnWizardFinished(); break; default: break; } return bResult; } // // Helper function to convert a font point size to a height value // used in a LOGFONT structure. // int CWizardPage::FontPtsToHt( HWND hwnd, int pts ) { int ht = 10; HDC hdc = GetDC(hwnd); if (NULL != hdc) { ht = -MulDiv(pts, GetDeviceCaps(hdc, LOGPIXELSY), 72); ReleaseDC(hwnd, hdc); } return ht; } // // The title text on the cover and finish pages is enlarged and bold. // This code modifies the text in the dialog accordingly. // On return, m_hTitleFont contains the handle to the title font. // BOOL CWizardPage::FormatTitleFont( UINT idcTitle ) { BOOL bResult = FALSE; HWND hwndTitle = GetDlgItem(m_hwndDlg, idcTitle); HFONT hFont = (HFONT)SendMessage(hwndTitle, WM_GETFONT, 0, 0); if (NULL != hFont) { if (NULL == m_hTitleFont) { LOGFONT lf; if (GetObject(hFont, sizeof(lf), &lf)) { lf.lfHeight = FontPtsToHt(hwndTitle, m_cyTitleFontHt); m_hTitleFont = CreateFontIndirect(&lf); } } if (NULL != m_hTitleFont) { SendMessage(hwndTitle, WM_SETFONT, (WPARAM)m_hTitleFont, 0); bResult = TRUE; } } return bResult; } // // CWizardPgWelcome members ----------------------------------------------------- // // // WM_INITDIALOG handler. // BOOL CWizardPgWelcome::OnInitDialog( WPARAM wParam, LPARAM lParam ) { FormatTitleFont(IDC_TXT_FIRSTPIN_WELCOME_TITLE); return CWizardPage::OnInitDialog(wParam, lParam); } // // CWizardPgPin members ------------------------------------------------------- // // // WM_INITDIALOG handler. // BOOL CWizardPgPin::OnInitDialog( WPARAM wParam, LPARAM lParam ) { HRESULT hr = IsRegisteredForSyncAtLogonAndLogoff(); CheckDlgButton(m_hwndDlg, IDC_CBX_FIRSTPIN_AUTOSYNC, S_OK == hr ? BST_CHECKED : BST_UNCHECKED); return CWizardPage::OnInitDialog(wParam, lParam); } // // PSN_WIZFINISH handler. // BOOL CWizardPgPin::OnWizardFinished( void ) { HRESULT hr; RegisterSyncMgrHandler(TRUE); if (BST_CHECKED == IsDlgButtonChecked(m_hwndDlg, IDC_CBX_FIRSTPIN_AUTOSYNC)) { const DWORD dwFlags = SYNCMGRREGISTERFLAG_CONNECT | SYNCMGRREGISTERFLAG_PENDINGDISCONNECT; hr = RegisterForSyncAtLogonAndLogoff(dwFlags, dwFlags); if (SUCCEEDED(hr)) { SetSyncMgrInitialized(); } else { CscMessageBox(m_hwndDlg, MB_OK | MB_ICONERROR, Win32Error(HRESULT_CODE(hr)), m_hInstance, IDS_ERR_REGSYNCATLOGONLOGOFF); } } return CWizardPage::OnWizardFinished(); } // // CWizardPgOffline members --------------------------------------------------- // // // WM_INITDIALOG handler. // BOOL CWizardPgOffline::OnInitDialog( WPARAM wParam, LPARAM lParam ) { // // If policy allows configuration of the reminders, check the "enable reminders" // checkbox. // CConfig& config = CConfig::GetSingleton(); bool bNoConfigReminders; bool bNoCacheViewer = config.NoCacheViewer(); config.NoReminders(&bNoConfigReminders); CheckDlgButton(m_hwndDlg, IDC_CBX_REMINDERS, !bNoConfigReminders); EnableWindow(GetDlgItem(m_hwndDlg, IDC_CBX_REMINDERS), !bNoConfigReminders); CheckDlgButton(m_hwndDlg, IDC_CBX_FIRSTPIN_FLDRLNK, BST_UNCHECKED); EnableWindow(GetDlgItem(m_hwndDlg, IDC_CBX_FIRSTPIN_FLDRLNK), !bNoCacheViewer); return CWizardPage::OnInitDialog(wParam, lParam); } // // PSN_WIZFINISH handler. // BOOL CWizardPgOffline::OnPSNWizFinish( void ) { // // Send PSM_QUERYSIBLINGS to all of the pages with // wParam set to WM_WIZARDFINISHED. This will trigger // a call to the virtual function OnWizardFinished() // allowing each page to respond to the successful completion // of the wizard. // PropSheet_QuerySiblings(GetParent(m_hwndDlg), CWizardPage::WM_WIZARDFINISHED, 0); // // Now handle for this page. // OnWizardFinished(); return CWizardPage::OnPSNWizFinish(); } // // PSN_WIZFINISH handler. // BOOL CWizardPgOffline::OnWizardFinished( void ) { bool bEnableReminders = (BST_CHECKED == IsDlgButtonChecked(m_hwndDlg, IDC_CBX_REMINDERS)); DWORD dwValue; DWORD dwErr; dwValue = bEnableReminders ? 0 : 1; dwErr = SHSetValue(HKEY_CURRENT_USER, REGSTR_KEY_OFFLINEFILES, REGSTR_VAL_NOREMINDERS, REG_DWORD, &dwValue, sizeof(dwValue)); if (bEnableReminders) { PostToSystray(PWM_RESET_REMINDERTIMER, 0, 0); } if (BST_CHECKED == IsDlgButtonChecked(m_hwndDlg, IDC_CBX_FIRSTPIN_FLDRLNK)) { COfflineFilesFolder::CreateLinkOnDesktop(m_hwndDlg); } return CWizardPage::OnWizardFinished(); } // // CFirstPinWizard members ---------------------------------------------------- // CFirstPinWizard::CFirstPinWizard( HINSTANCE hInstance, HWND hwndParent ) : m_hInstance(hInstance), m_hwndParent(hwndParent), m_PgWelcome(hInstance, IDD_FIRSTPIN_WELCOME, 0, 0, PSP_DEFAULT, PSWIZB_NEXT), m_PgPin(hInstance, IDD_FIRSTPIN_PIN, 0, 0, PSP_DEFAULT, PSWIZB_NEXT | PSWIZB_BACK), m_PgOffline(hInstance, IDD_FIRSTPIN_OFFLINE, 0, 0, PSP_DEFAULT, PSWIZB_FINISH | PSWIZB_BACK) { // // Store pointers to each page in an array. Makes creating the // prop sheet easier in Run(). // m_rgpWizPages[0] = &m_PgWelcome; m_rgpWizPages[1] = &m_PgPin; m_rgpWizPages[2] = &m_PgOffline; } // // Creates the wizard and runs it. // The wizard runs modally. // // Returns: // // S_OK = User completed wizard and pressed "Finish". // S_FALSE = User pressed "Cancel" in wizard. // Other = Error creating wizard. // HRESULT CFirstPinWizard::Run( void ) { HRESULT hr = NOERROR; PROPSHEETHEADER psh; PROPSHEETPAGE psp; HPROPSHEETPAGE rghpage[ARRAYSIZE(m_rgpWizPages)]; ZeroMemory(&psh, sizeof(psh)); ZeroMemory(rghpage, sizeof(rghpage)); psh.dwSize = sizeof(psh); psh.dwFlags = PSH_WIZARD_LITE; psh.hwndParent = m_hwndParent; psh.hInstance = m_hInstance; psh.nPages = ARRAYSIZE(rghpage); psh.phpage = rghpage; TCHAR szTitle[MAX_PATH]; TCHAR szSubTitle[MAX_PATH]; for (int i = 0; i < ARRAYSIZE(rghpage) && SUCCEEDED(hr); i++) { CWizardPage *pwp = m_rgpWizPages[i]; ZeroMemory(&psp, sizeof(psp)); psp.dwSize = sizeof(psp); psp.dwFlags |= pwp->GetPageFlags(); psp.hInstance = m_hInstance; psp.pszTemplate = MAKEINTRESOURCE(pwp->GetDlgTemplate()); psp.pfnDlgProc = pwp->GetDlgProc(); psp.lParam = (LPARAM)pwp; rghpage[i] = CreatePropertySheetPage(&psp); if (NULL == rghpage[i]) { while(0 <= --i) { DestroyPropertySheetPage(rghpage[i]); } hr = E_FAIL; } } if (SUCCEEDED(hr)) { switch(PropertySheet(&psh)) { case -1: hr = HRESULT_FROM_WIN32(GetLastError()); break; case 0: hr = S_FALSE; // User pressed "Cancel". break; case 1: hr = S_OK; // User pressed "Finish". break; } } return hr; } // // This is the function you call when you want to run the wizard. // It merely creates a wizard object and tells it to run. // If the user finishes the wizard, it records this fact in the // registry. Calling FirstPinWizardCompleted() will tell // you later if the user has finished the wizard. // // Returns: // // S_OK = User completed wizard and pressed "Finish". // S_FALSE = User cancelled out of wizard. // Other = Error creating wizard. // HRESULT ShowFirstPinWizard( HWND hwndParent ) { HRESULT hr = NOERROR; CFirstPinWizard Wizard(g_hInstance, hwndParent); hr = Wizard.Run(); if (S_OK == hr) { // // Only record "finished" in registry if user // pressed "finish". // RegKey key(HKEY_CURRENT_USER, REGSTR_KEY_OFFLINEFILES); if (SUCCEEDED(key.Open(KEY_SET_VALUE, true))) { key.SetValue(REGSTR_VAL_FIRSTPINWIZARDSHOWN, 1); } } return hr; } // // Has user seen the wizard and pressed "finish"? // bool FirstPinWizardCompleted( void ) { return CConfig::GetSingleton().FirstPinWizardShown(); }