windows-nt/Source/XPSP1/NT/shell/ext/cscui/options.h
2020-09-26 16:20:57 +08:00

695 lines
25 KiB
C++

//+-------------------------------------------------------------------------
//
// 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 <windows.h>
#endif
#ifndef _INC_CSCVIEW_CONFIG_H
# include "config.h"
#endif
#ifndef _INC_CSCUI_UIHELP_H
# include "uihelp.h"
#endif
#ifndef _INC_MATH
# include <math.h>
#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