//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1997 - 1999 // // File: options.h // //-------------------------------------------------------------------------- #ifndef _INC_CSCUI_OPTIONS_H #define _INC_CSCUI_OPTIONS_H /////////////////////////////////////////////////////////////////////////////// /* File: options.h Description: Revision History: Date Description Programmer -------- --------------------------------------------------- ---------- 04/15/98 Initial creation. BrianAu */ /////////////////////////////////////////////////////////////////////////////// #ifndef _WINDOWS_ # include #endif #ifndef _INC_CSCVIEW_CONFIG_H # include "config.h" #endif #ifndef _INC_CSCUI_UIHELP_H # include "uihelp.h" #endif #ifndef _INC_MATH # include #endif #ifndef _INC_CSCUI_PURGE_H # include "purge.h" #endif #include "resource.h" // // The "Advanced" dialog invoked from the "Advanced" button on the // "Offline Files" prop page. // class CAdvOptDlg { public: enum { // // Listview subitem IDs. // iLVSUBITEM_SERVER = 0, iLVSUBITEM_ACTION = 1 }; CAdvOptDlg(HINSTANCE hInstance, HWND hwndParent) : m_hInstance(hInstance), m_hwndParent(hwndParent), m_hwndDlg(NULL), m_hwndLV(NULL), m_iLastColSorted(-1), m_bSortAscending(true), m_bNoConfigGoOfflineAction(false) { } int Run(void); protected: BOOL OnInitDialog(HWND hDlg, HWND hwndFocus, LPARAM lInitParam); BOOL OnNotify(HWND hDlg, int idCtl, LPNMHDR pnmhdr); BOOL OnCommand(HWND hDlg, WORD wNotifyCode, WORD wID, HWND hwndCtl); BOOL OnDestroy(HWND hDlg); BOOL OnContextMenu(WPARAM wParam, LPARAM lParam); BOOL OnHelp(HWND hDlg, LPHELPINFO pHelpInfo); private: // // Structure to associate a radio button with an offline action code. // struct CtlActions { UINT idRbn; CConfig::OfflineAction action; }; // // Class to describe the state of controls in the dialog. Used to // determine if user has changed anything. // class PgState { public: PgState(void) : m_DefaultGoOfflineAction(CConfig::eGoOfflineSilent), m_hdpaCustomGoOfflineActions(DPA_Create(4)) { } ~PgState(void); void SetDefGoOfflineAction(CConfig::OfflineAction action) { m_DefaultGoOfflineAction = action; } CConfig::OfflineAction GetDefGoOfflineAction(void) const { return m_DefaultGoOfflineAction; } void SetCustomGoOfflineActions(HWND hwndLV); HDPA GetCustomGoOfflineActions(void) const { return m_hdpaCustomGoOfflineActions; } bool operator == (const PgState& rhs) const; bool operator != (const PgState& rhs) const { return !(*this == rhs); } private: CConfig::OfflineAction m_DefaultGoOfflineAction; HDPA m_hdpaCustomGoOfflineActions; }; HINSTANCE m_hInstance; HWND m_hwndParent; HWND m_hwndDlg; HWND m_hwndLV; int m_iLastColSorted; PgState m_state; // State on creation. bool m_bSortAscending; bool m_bNoConfigGoOfflineAction; static const CtlActions m_rgCtlActions[CConfig::eNumOfflineActions]; static const DWORD m_rgHelpIDs[]; static INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); void ApplySettings(void); void EnableCtls(HWND hwnd); void CreateListColumns(HWND hwndList); void OnLVN_GetDispInfo(LV_DISPINFO *plvdi); void OnLVN_ColumnClick(NM_LISTVIEW *pnmlv); void OnLVN_ItemChanged(NM_LISTVIEW *pnmlv); void OnLVN_KeyDown(NMLVKEYDOWN *plvkd); void OnContextMenuItemSelected(int idMenuItem); static int CALLBACK CompareLVItems(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); void GetPageState(PgState *pps); CConfig::OfflineAction GetCurrentGoOfflineAction(void) const; void AddCustomGoOfflineAction(LPCTSTR pszServer, CConfig::OfflineAction action); void ReplaceCustomGoOfflineAction(CConfig::CustomGOA *pGOA, int iItem, CConfig::OfflineAction action); void OnAddCustomGoOfflineAction(void); void OnEditCustomGoOfflineAction(void); void OnDeleteCustomGoOfflineAction(void); int CountSelectedListviewItems(int *pcSetByPolicy); void DeleteSelectedListviewItems(void); void SetSelectedListviewItemsAction(CConfig::OfflineAction action); void FocusOnSomethingInListview(void); int GetFirstSelectedLVItemRect(RECT *prc); bool IsCustomActionListviewEnabled(void) const { return boolify(IsWindowEnabled(GetDlgItem(m_hwndDlg, IDC_GRP_CUSTGOOFFLINE))); } static DWORD CheckNetServer(LPCTSTR pszServer); static int AddGOAToListView(HWND hwndLV, int iItem, const CConfig::CustomGOA& goa); static CConfig::CustomGOA *FindGOAInListView(HWND hwndLV, LPCTSTR pszServer, int *piItem); static CConfig::CustomGOA *GetListviewObject(HWND hwndLV, int iItem); // // PgState calls GetListviewObject. // friend void PgState::SetCustomGoOfflineActions(HWND); }; // // The "Offline Files" property sheet page. // class COfflineFilesPage { public: COfflineFilesPage(HINSTANCE hInstance, LPUNKNOWN pUnkOuter) : m_hInstance(hInstance), m_hwndDlg(NULL), m_pUnkOuter(pUnkOuter), m_hwndSlider(NULL), m_hwndEncryptTooltip(NULL), m_pfnOldPropSheetWndProc(NULL), m_pfnOldEncryptionTooltipWndProc(NULL), m_bUserHasMachineAccess(false), m_bCscVolSupportsEncryption(false), m_bApplyingSettings(false), m_bFirstActivate(true), m_iSliderMax(0), m_llAvailableDiskSpace(0) { } UINT GetDlgTemplateID(void) const { return IDD_CSC_OPTIONS; } LPFNPSPCALLBACK GetCallbackFuncPtr(void) const { return PageCallback; } DLGPROC GetDlgProcPtr(void) const { return DlgProc; } // // This is called by the "Advanced" page to determine if controls can // be enabled or not. // bool IsCscEnabledChecked(void) const { return m_hwndDlg && BST_CHECKED == IsDlgButtonChecked(m_hwndDlg, IDC_CBX_ENABLE_CSC); } protected: BOOL OnInitDialog(HWND hDlg, HWND hwndFocus, LPARAM lInitParam); BOOL OnNotify(HWND hDlg, int idCtl, LPNMHDR pnmhdr); BOOL OnCommand(HWND hDlg, WORD wNotifyCode, WORD wID, HWND hwndCtl); BOOL OnDestroy(HWND hDlg); BOOL OnContextMenu(HWND hwndItem, int xPos, int yPos); BOOL ApplySettings(HWND hDlg, bool bPropSheetClosing); BOOL OnHelp(HWND hDlg, LPHELPINFO pHelpInfo); BOOL OnSettingChange(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); private: class PgState { public: PgState(void) : m_bCscEnabled(false), m_bFullSyncAtLogoff(false), m_bFullSyncAtLogon(false), m_bLinkOnDesktop(false), m_bReminders(false), m_iEncrypted(BST_UNCHECKED), m_iReminderFreq(0), m_iSliderPos(0) { } void SetCscEnabled(bool bCscEnabled) { m_bCscEnabled = bCscEnabled; } bool GetCscEnabled(void) const { return m_bCscEnabled; } void SetFullSyncAtLogon(bool bFullSync) { m_bFullSyncAtLogon = bFullSync; } bool GetFullSyncAtLogon(void) const { return m_bFullSyncAtLogon; } void SetFullSyncAtLogoff(bool bFullSync) { m_bFullSyncAtLogoff = bFullSync; } bool GetFullSyncAtLogoff(void) const { return m_bFullSyncAtLogoff; } void SetEncrypted(int iEncrypted) { m_iEncrypted = iEncrypted; } int GetEncrypted(void) const { return m_iEncrypted; } void SetSliderPos(int iSliderPos) { m_iSliderPos = iSliderPos; } int GetSliderPos(void) const { return m_iSliderPos; } void SetRemindersEnabled(bool bEnabled) { m_bReminders = bEnabled; } bool GetRemindersEnabled(void) const { return m_bReminders; } void SetReminderFreq(int iMinutes) { m_iReminderFreq = iMinutes; } int GetReminderFreq(void) const { return m_iReminderFreq; } void SetLinkOnDesktop(bool bEnabled) { m_bLinkOnDesktop = bEnabled; } bool GetLinkOnDesktop(void) const { return m_bLinkOnDesktop; } bool operator == (const PgState& rhs) const { return (m_bCscEnabled == rhs.m_bCscEnabled && m_bFullSyncAtLogoff == rhs.m_bFullSyncAtLogoff && m_bFullSyncAtLogon == rhs.m_bFullSyncAtLogon && m_bLinkOnDesktop == rhs.m_bLinkOnDesktop && m_iEncrypted == rhs.m_iEncrypted && m_iSliderPos == rhs.m_iSliderPos && m_bReminders == rhs.m_bReminders && m_iReminderFreq == rhs.m_iReminderFreq); } bool operator != (const PgState& rhs) const { return !(*this == rhs); } private: bool m_bCscEnabled; bool m_bFullSyncAtLogon; bool m_bFullSyncAtLogoff; bool m_bLinkOnDesktop; bool m_bReminders; int m_iEncrypted; // BST_CHECKED, BST_UNCHECKED, BST_INDETERMINATE int m_iSliderPos; int m_iReminderFreq; }; class CConfigItems { public: CConfigItems(void) { ZeroMemory(m_rgItems, sizeof(m_rgItems)); } void Load(void); CConfig::SyncAction SyncAtLogoff(void) const { return CConfig::SyncAction(m_rgItems[iCFG_SYNCATLOGOFF].dwValue); } CConfig::SyncAction SyncAtLogon(void) const { return CConfig::SyncAction(m_rgItems[iCFG_SYNCATLOGON].dwValue); } bool NoConfigCache(void) const { return boolify(m_rgItems[iCFG_NOCONFIGCACHE].dwValue); } bool NoConfigSyncAtLogoff(void) const { return m_rgItems[iCFG_SYNCATLOGOFF].bSetByPolicy; } bool NoConfigSyncAtLogon(void) const { return m_rgItems[iCFG_SYNCATLOGON].bSetByPolicy; } bool NoReminders(void) const { return boolify(m_rgItems[iCFG_NOREMINDERS].dwValue); } bool NoConfigReminders(void) const { return m_rgItems[iCFG_NOREMINDERS].bSetByPolicy; } bool NoConfigCacheSize(void) const { return m_rgItems[iCFG_DEFCACHESIZE].bSetByPolicy; } bool NoCacheViewer(void) const { return boolify(m_rgItems[iCFG_NOCACHEVIEWER].dwValue); } bool NoConfigCscEnabled(void) const { return boolify(m_rgItems[iCFG_CSCENABLED].bSetByPolicy); } bool NoConfigReminderFreqMinutes(void) const { return boolify(m_rgItems[iCFG_REMINDERFREQMINUTES].bSetByPolicy); } int ReminderFreqMinutes(void) const { return int(m_rgItems[iCFG_REMINDERFREQMINUTES].dwValue); } bool EncryptCache(void) const { return boolify(m_rgItems[iCFG_ENCRYPTCACHE].dwValue); } bool NoConfigEncryptCache(void) const { return boolify(m_rgItems[iCFG_ENCRYPTCACHE].bSetByPolicy); } private: struct ConfigItem { DWORD dwValue; bool bSetByPolicy; }; enum eConfigItems { iCFG_NOCONFIGCACHE, iCFG_SYNCATLOGOFF, iCFG_SYNCATLOGON, iCFG_NOREMINDERS, iCFG_DEFCACHESIZE, iCFG_NOCACHEVIEWER, iCFG_CSCENABLED, iCFG_REMINDERFREQMINUTES, iCFG_ENCRYPTCACHE, MAX_CONFIG_ITEMS }; ConfigItem m_rgItems[MAX_CONFIG_ITEMS]; }; HINSTANCE m_hInstance; HWND m_hwndDlg; LPUNKNOWN m_pUnkOuter; HWND m_hwndSlider; HWND m_hwndEncryptTooltip; int m_iSliderMax; LONGLONG m_llAvailableDiskSpace; PgState m_state; CConfigItems m_config; TCHAR m_szEncryptTooltipBody[MAX_PATH]; WNDPROC m_pfnOldPropSheetWndProc; WNDPROC m_pfnOldEncryptionTooltipWndProc; bool m_bUserHasMachineAccess; bool m_bCscVolSupportsEncryption; bool m_bApplyingSettings; bool m_bFirstActivate; static const DWORD m_rgHelpIDs[]; static INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); static UINT CALLBACK PageCallback(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp); static BOOL CALLBACK PurgeCacheCallback(CCachePurger *pPurger); static DWORD CALLBACK EncryptDecryptCallback(LPCWSTR lpszName, DWORD dwStatus, DWORD dwHintFlags, DWORD dwPinCount, WIN32_FIND_DATAW *pFind32, DWORD dwReason, DWORD dwParam1, DWORD dwParam2, DWORD_PTR dwContext); static LRESULT CALLBACK PropSheetSubclassWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK EncryptionTooltipSubclassWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void OnDeleteCache(void); void OnFormatCache(void); void EnableCtls(HWND hwnd); void InitSlider(HWND hwndDlg, LONGLONG llMaxDiskSpace, LONGLONG llUsedDiskSpace); void OnHScroll(HWND hwndDlg, HWND hwndCtl, int iCode, int iPos); void SetCacheSizeDisplay(HWND hwndCtl, int iThumbPos); void EncryptOrDecryptCache(bool bEncrypt, bool bPropSheetClosing); void CreateEncryptionTooltip(void); void ShowEncryptionTooltip(bool bEncrypted); void HideEncryptionTooltip(void); void TrackEncryptionTooltip(void); void UpdateEncryptionCheckbox(void); void UpdateEncryptionTooltipBalloon(void); void UpdateEncryptionCheckboxOrBalloon(bool bCheckbox); void OnTTN_GetDispInfo(LPNMTTDISPINFO pttdi); double Fx(double x); double Fy(double y); double Rx(double x); LONGLONG DiskSpaceAtThumb(int t); int ThumbAtPctDiskSpace(double pct); void GetPageState(PgState *pps); void HandlePageStateChange(void); bool IsLinkOnDesktop(LPTSTR pszPathOut = NULL, UINT cchPathOut = 0); bool EnableOrDisableCsc(bool bEnable, bool *pbReboot, DWORD *pdwError); bool DisableForTerminalServer(void); HRESULT _ApplyEnabledSetting(RegKey& keyLM, RegKey& keyCU, const PgState& pgstNow, bool *pbUpdateSysTrayUI); HRESULT _ApplySyncAtLogoffSetting(RegKey& keyLM, RegKey& keyCU, const PgState& pgstNow); HRESULT _ApplySyncAtLogonSetting(RegKey& keyLM, RegKey& keyCU, const PgState& pgstNow); HRESULT _ApplyReminderSettings(RegKey& keyLM, RegKey& keyCU, const PgState& pgstNow); HRESULT _ApplyFolderLinkSetting(RegKey& keyLM, RegKey& keyCU, const PgState& pgstNow); HRESULT _ApplyCacheSizeSetting(RegKey& keyLM, RegKey& keyCU, const PgState& pgstNow); HRESULT _ApplyEncryptionSetting(RegKey& keyLM, RegKey& keyCU, const PgState& pgstNow, bool bPropSheetClosing, bool *pbPerformed); }; class COfflineFilesSheet { public: static DWORD CreateAndRun(HINSTANCE hInstance, HWND hwndParent, LONG *pDllRefCount, BOOL bAsync=TRUE); private: // // Increase this if more pages are required. // Currently, we only need the "Offline Files" page. // enum { MAXPAGES = 1 }; HINSTANCE m_hInstance; HWND m_hwndParent; LONG *m_pDllRefCount; // // Trivial class for passing parameters to share dialog thread proc. // class ThreadParams { public: ThreadParams(HWND hwndParent, LONG *pDllRefCount) : m_hwndParent(hwndParent), m_hInstance(NULL), m_pDllRefCount(pDllRefCount) { } HWND m_hwndParent; HINSTANCE m_hInstance; LONG *m_pDllRefCount; void SetModuleHandle(HINSTANCE hInstance) { m_hInstance = hInstance; } }; COfflineFilesSheet(HINSTANCE hInstance, LONG *pDllRefCount, HWND hwndParent); ~COfflineFilesSheet(void); DWORD Run(void); static UINT WINAPI ThreadProc(LPVOID pvParam); static BOOL CALLBACK AddPropSheetPage(HPROPSHEETPAGE hpage, LPARAM lParam); }; class CscOptPropSheetExt : public IShellExtInit, IShellPropSheetExt { public: CscOptPropSheetExt(HINSTANCE hInstance, LONG *pDllRefCnt); ~CscOptPropSheetExt(void); // // IUnknown // STDMETHODIMP QueryInterface(REFIID, void **); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); // // IShellExtInit method // STDMETHODIMP Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY); // // IShellPropSheetExt // STDMETHODIMP AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam); STDMETHODIMP ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam) { return E_NOTIMPL; } // // Change this if you add or remove any prop pages from this prop sheet ext. // enum { NUMPAGES = 2 }; private: LONG m_cRef; HINSTANCE m_hInstance; LONG *m_pDllRefCnt; COfflineFilesPage *m_pOfflineFoldersPg; HRESULT AddPage(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam, const COfflineFilesPage& pg, HPROPSHEETPAGE *phPage); }; class CustomGOAAddDlg { public: CustomGOAAddDlg(HINSTANCE hInstance, HWND hwndParent, LPTSTR pszServer, UINT cchServer, CConfig::OfflineAction *pAction); int Run(void); private: // // Structure to associate a radio button with an offline action code. // struct CtlActions { UINT idRbn; CConfig::OfflineAction action; }; HINSTANCE m_hInstance; HWND m_hwndParent; HWND m_hwndDlg; HWND m_hwndEdit; LPTSTR m_pszServer; // Output. UINT m_cchServer; CConfig::OfflineAction *m_pAction; static const CtlActions m_rgCtlActions[CConfig::eNumOfflineActions]; static const DWORD m_rgHelpIDs[]; static INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); BOOL OnInitDialog(HWND hDlg, HWND hwndFocus, LPARAM lInitParam); BOOL OnCommand(HWND hDlg, WORD wNotifyCode, WORD wID, HWND hwndCtl); BOOL OnDestroy(HWND hDlg); BOOL OnHelp(HWND hDlg, LPHELPINFO pHelpInfo); BOOL OnContextMenu(HWND hwndItem, int xPos, int yPos); void BrowseForServer(HWND hDlg, LPTSTR pszServer, UINT cchServer); void GetActionInfo(LPTSTR pszServer, UINT cchServer, CConfig::OfflineAction *pAction); bool CheckServerNameEntered(void); void GetEnteredServerName(LPTSTR pszServer, UINT cchServer, bool bTrimLeadingJunk); }; class CustomGOAEditDlg { public: CustomGOAEditDlg(HINSTANCE hInstance, HWND hwndParent, LPCTSTR pszServer, CConfig::OfflineAction *pAction); int Run(void); private: // // Structure to associate a radio button with an offline action code. // struct CtlActions { UINT idRbn; CConfig::OfflineAction action; }; HINSTANCE m_hInstance; HWND m_hwndParent; HWND m_hwndDlg; TCHAR m_szServer[MAX_PATH]; CConfig::OfflineAction *m_pAction; static const CtlActions m_rgCtlActions[CConfig::eNumOfflineActions]; static const DWORD m_rgHelpIDs[]; static INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); BOOL OnInitDialog(HWND hDlg, HWND hwndFocus, LPARAM lInitParam); BOOL OnCommand(HWND hDlg, WORD wNotifyCode, WORD wID, HWND hwndCtl); BOOL OnDestroy(HWND hDlg); BOOL OnHelp(HWND hDlg, LPHELPINFO pHelpInfo); BOOL OnContextMenu(HWND hwndItem, int xPos, int yPos); void GetActionInfo(CConfig::OfflineAction *pAction); }; //----------------------------------------------------------------------------- // Inline functions. //----------------------------------------------------------------------------- // // This is the "gain" function for the slider and resulting value. // Pass in a true position of the slider thumb and you get back // a scaled value for the thumb. To change the gain, change // this function. Remember to change Fy() also. // inline double COfflineFilesPage::Fx( double x ) { return (x * x) / 2.0; } // // This is the "gain" function for the slider solved for 'y'. // Pass in a virtual position for the thumb and you get back // a true thumb position. // inline double COfflineFilesPage::Fy( double y ) { return sqrt(2.0 * y); } // // Ratio used to calculate the disk space value for a given // true thumb position. Give it a true thumb position between // 0 and 100 and it will return a number between 0.0 and 1.0 that // can be used to find the disk space. // // DiskSpace = DiskSpaceMax * Rx(thumb) // inline double COfflineFilesPage::Rx( double x ) { double denominator = Fx(m_iSliderMax); if (0.00001 < denominator) return Fx(x) / denominator; else return 1.0; } // // Calculates the disk space value at a particular position of the // slider thumb for values of 't' between 0 and 100. // inline LONGLONG COfflineFilesPage::DiskSpaceAtThumb( int t ) { return LONGLONG(double(m_llAvailableDiskSpace) * Rx(t)); } // // Calculates the true thumb position for a given disk space // percent value between 0.0 and 1.0. // The expression breaks down as follows: // // double MaxVirtualThumb = Fx(m_iSliderMax); // double VirtualThumb = MaxVirtualThumb * pct; // double TrueThumb = Fy(VirtualThumb); // // return round(TrueThumb); // "round" used for illustration only. // inline int COfflineFilesPage::ThumbAtPctDiskSpace( double pct ) { double t = Fy(Fx(m_iSliderMax) * pct); double ft = floor(t); if (0.5 < t - ft) { // // Since the thumb position must be a whole number, // round up if necessary. Typecast from double to int // merely truncates at the decimal point. // ft += 1.0; } return int(ft); } #endif // _INC_CSCUI_OPTIONS_H