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.

568 lines
16 KiB

  1. /*--------------------------------------------------------------------------*
  2. *
  3. * Microsoft Windows
  4. * Copyright (C) Microsoft Corporation, 1992 - 1999
  5. *
  6. * File: props.cpp
  7. *
  8. * Contents: Implementation file for console property sheet and page(s)
  9. *
  10. * History: 05-Dec-97 JeffRo Created
  11. *
  12. *--------------------------------------------------------------------------*/
  13. #include "stdafx.h"
  14. #include "amc.h"
  15. #include "props.h"
  16. #include "mainfrm.h"
  17. #include "amcdoc.h"
  18. #include "pickicon.h"
  19. //#ifdef _DEBUG
  20. //#define new DEBUG_NEW
  21. //#undef THIS_FILE
  22. //static char THIS_FILE[] = __FILE__;
  23. //#endif
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CConsolePropSheet
  26. IMPLEMENT_DYNAMIC(CConsolePropSheet, CPropertySheet)
  27. CConsolePropSheet::CConsolePropSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
  28. : CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
  29. {
  30. CommonConstruct ();
  31. }
  32. CConsolePropSheet::CConsolePropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
  33. : CPropertySheet(pszCaption, pParentWnd, iSelectPage)
  34. {
  35. CommonConstruct ();
  36. }
  37. void CConsolePropSheet::CommonConstruct()
  38. {
  39. DECLARE_SC(sc, TEXT("CConsolePropSheet::CommonConstruct"));
  40. CAMCApp *pAMCApp = AMCGetApp();
  41. sc = ScCheckPointers( pAMCApp, E_UNEXPECTED );
  42. if (sc)
  43. sc.TraceAndClear();
  44. // add the main page only for author mode
  45. if ( (pAMCApp != NULL) && (pAMCApp->GetMode() == eMode_Author) )
  46. {
  47. AddPage (&m_ConsolePage);
  48. }
  49. AddPage (&m_diskCleanupPage);
  50. }
  51. BOOL CConsolePropSheet::OnInitDialog()
  52. {
  53. ModifyStyleEx(0, WS_EX_CONTEXTHELP, SWP_NOSIZE);
  54. return CPropertySheet::OnInitDialog();
  55. }
  56. CConsolePropSheet::~CConsolePropSheet()
  57. {
  58. }
  59. BEGIN_MESSAGE_MAP(CConsolePropSheet, CPropertySheet)
  60. //{{AFX_MSG_MAP(CConsolePropSheet)
  61. //}}AFX_MSG_MAP
  62. END_MESSAGE_MAP()
  63. /*+-------------------------------------------------------------------------*
  64. * CConsolePropSheet::DoModal
  65. *
  66. *
  67. *--------------------------------------------------------------------------*/
  68. INT_PTR CConsolePropSheet::DoModal()
  69. {
  70. CThemeContextActivator activator;
  71. return CPropertySheet::DoModal();
  72. }
  73. /////////////////////////////////////////////////////////////////////////////
  74. // CConsolePropPage property page
  75. IMPLEMENT_DYNCREATE(CConsolePropPage, CPropertyPage)
  76. CConsolePropPage::CConsolePropPage()
  77. : CPropertyPage(CConsolePropPage::IDD),
  78. m_pDoc (CAMCDoc::GetDocument())
  79. {
  80. ASSERT (m_pDoc != NULL);
  81. ASSERT_VALID (m_pDoc);
  82. ASSERT_KINDOF (CAMCDoc, m_pDoc);
  83. m_hinstSelf = AfxGetInstanceHandle ();
  84. m_fTitleChanged = false;
  85. m_fIconChanged = false;
  86. m_strTitle = m_pDoc->GetCustomTitle ();
  87. m_nConsoleMode = m_pDoc->GetMode ();
  88. m_fDontSaveChanges = m_pDoc->IsLogicalReadOnly ();
  89. m_fAllowViewCustomization = m_pDoc->AllowViewCustomization ();
  90. }
  91. CConsolePropPage::~CConsolePropPage()
  92. {
  93. }
  94. void CConsolePropPage::DoDataExchange(CDataExchange* pDX)
  95. {
  96. CPropertyPage::DoDataExchange(pDX);
  97. //{{AFX_DATA_MAP(CConsolePropPage)
  98. DDX_Control(pDX, IDC_DONTSAVECHANGES, m_wndDontSaveChanges);
  99. DDX_Control(pDX, IDC_AllowViewCustomization, m_wndAllowViewCustomization);
  100. DDX_Control(pDX, IDC_CONSOLE_MODE_DESCRIPTION, m_wndModeDescription);
  101. DDX_Control(pDX, IDC_CUSTOM_TITLE, m_wndTitle);
  102. DDX_CBIndex(pDX, IDC_CONSOLE_MODE, m_nConsoleMode);
  103. DDX_Check(pDX, IDC_DONTSAVECHANGES, m_fDontSaveChanges);
  104. DDX_Text(pDX, IDC_CUSTOM_TITLE, m_strTitle);
  105. DDX_Check(pDX, IDC_AllowViewCustomization, m_fAllowViewCustomization);
  106. //}}AFX_DATA_MAP
  107. }
  108. BEGIN_MESSAGE_MAP(CConsolePropPage, CPropertyPage)
  109. //{{AFX_MSG_MAP(CConsolePropPage)
  110. ON_CBN_SELENDOK(IDC_CONSOLE_MODE, OnSelendokConsoleMode)
  111. ON_BN_CLICKED(IDC_DONTSAVECHANGES, OnDontSaveChanges)
  112. ON_BN_CLICKED(IDC_AllowViewCustomization, OnAllowViewCustomization)
  113. ON_BN_CLICKED(IDC_CHANGE_ICON, OnChangeIcon)
  114. ON_EN_CHANGE(IDC_CUSTOM_TITLE, OnChangeCustomTitle)
  115. //}}AFX_MSG_MAP
  116. ON_MMC_CONTEXT_HELP()
  117. END_MESSAGE_MAP()
  118. /////////////////////////////////////////////////////////////////////////////
  119. // CConsolePropPage message handlers
  120. void CConsolePropPage::OnOK()
  121. {
  122. m_pDoc->SetMode (static_cast<ProgramMode>(m_nConsoleMode));
  123. m_pDoc->SetLogicalReadOnlyFlag (m_fDontSaveChanges);
  124. m_pDoc->AllowViewCustomization (m_fAllowViewCustomization);
  125. if (m_fIconChanged)
  126. {
  127. m_pDoc->SetCustomIcon (m_strIconFile, m_nIconIndex);
  128. m_fIconChanged = false;
  129. }
  130. if (m_fTitleChanged)
  131. {
  132. m_pDoc->SetCustomTitle (m_strTitle);
  133. m_fTitleChanged = false;
  134. }
  135. CPropertyPage::OnOK();
  136. }
  137. void CConsolePropPage::OnSelendokConsoleMode()
  138. {
  139. SetModified ();
  140. UpdateData ();
  141. SetDescriptionText ();
  142. EnableDontSaveChanges ();
  143. }
  144. void CConsolePropPage::SetDescriptionText ()
  145. {
  146. // make sure the mode index is within range
  147. ASSERT (IsValidProgramMode (static_cast<ProgramMode>(m_nConsoleMode)));
  148. m_wndModeDescription.SetWindowText (m_strDescription[m_nConsoleMode]);
  149. }
  150. BOOL CConsolePropPage::OnInitDialog()
  151. {
  152. CPropertyPage::OnInitDialog();
  153. /*
  154. * make sure the string IDs are as the code expects them
  155. */
  156. ASSERT ((IDS_ModeAuthor + 1) == IDS_ModeUserFull);
  157. ASSERT ((IDS_ModeUserFull + 1) == IDS_ModeUserMDI);
  158. ASSERT ((IDS_ModeUserMDI + 1) == IDS_ModeUserSDI);
  159. ASSERT ((IDS_ModeAuthor_Description + 1) == IDS_ModeUserFull_Description);
  160. ASSERT ((IDS_ModeUserFull_Description + 1) == IDS_ModeUserMDI_Description);
  161. ASSERT ((IDS_ModeUserMDI_Description + 1) == IDS_ModeUserSDI_Description);
  162. /*
  163. * load the mode names into the combo box
  164. */
  165. int i;
  166. CString strComboText;
  167. CComboBox* pCombo = reinterpret_cast<CComboBox*>(GetDlgItem (IDC_CONSOLE_MODE));
  168. ASSERT (pCombo != NULL);
  169. for (i = 0; i < eMode_Count; i++)
  170. {
  171. VERIFY (LoadString (strComboText, IDS_ModeAuthor + i));
  172. pCombo->AddString (strComboText);
  173. }
  174. pCombo->SetCurSel (m_nConsoleMode - eMode_Author);
  175. /*
  176. * load up the description text
  177. */
  178. ASSERT (countof (m_strDescription) == eMode_Count);
  179. for (i = 0; i < countof (m_strDescription); i++)
  180. {
  181. VERIFY (LoadString (m_strDescription[i], IDS_ModeAuthor_Description + i));
  182. }
  183. SetDescriptionText ();
  184. EnableDontSaveChanges ();
  185. /*
  186. * Get the current icon for this console file
  187. */
  188. ASSERT (m_pDoc != NULL);
  189. HICON hIcon = m_pDoc->GetCustomIcon (true, &m_strIconFile, &m_nIconIndex);
  190. m_wndIcon.SubclassDlgItem (IDC_CONSOLE_ICON, this);
  191. /*
  192. * if we haven't specified a custom icon yet, use MMC.EXE
  193. */
  194. if (hIcon == NULL)
  195. {
  196. ASSERT (m_strIconFile.IsEmpty());
  197. const int cchBuffer = MAX_PATH;
  198. GetModuleFileName (AfxGetInstanceHandle(), m_strIconFile.GetBuffer(cchBuffer), cchBuffer);
  199. m_strIconFile.ReleaseBuffer();
  200. m_nIconIndex = 0;
  201. }
  202. else
  203. m_wndIcon.SetIcon (hIcon);
  204. /*
  205. * Get the current title for this console file
  206. */
  207. m_wndTitle.SetWindowText (m_pDoc->GetCustomTitle());
  208. m_fTitleChanged = false;
  209. return TRUE; // return TRUE unless you set the focus to a control
  210. // EXCEPTION: OCX Property Pages should return FALSE
  211. }
  212. void CConsolePropPage::OnDontSaveChanges()
  213. {
  214. SetModified ();
  215. }
  216. void CConsolePropPage::OnAllowViewCustomization()
  217. {
  218. SetModified ();
  219. }
  220. void CConsolePropPage::EnableDontSaveChanges()
  221. {
  222. if (m_nConsoleMode == eMode_Author)
  223. {
  224. m_wndDontSaveChanges. EnableWindow (false);
  225. m_wndDontSaveChanges. SetCheck (0);
  226. m_wndAllowViewCustomization.EnableWindow (false);
  227. m_wndAllowViewCustomization.SetCheck (1);
  228. }
  229. else
  230. {
  231. m_wndDontSaveChanges. EnableWindow (true);
  232. m_wndAllowViewCustomization.EnableWindow (true);
  233. }
  234. }
  235. void CConsolePropPage::OnChangeIcon()
  236. {
  237. int nIconIndex = m_nIconIndex;
  238. TCHAR szIconFile[MAX_PATH];
  239. lstrcpy (szIconFile, m_strIconFile);
  240. /*
  241. * show the pick 'em dialog; if something changed, enable OK/Apply
  242. */
  243. if (PickIconDlg (m_hWnd, szIconFile, countof (szIconFile), &nIconIndex) &&
  244. ((nIconIndex != m_nIconIndex) || (lstrcmpi (szIconFile, m_strIconFile) != 0)))
  245. {
  246. m_icon.Attach (ExtractIcon (m_hinstSelf, szIconFile, nIconIndex));
  247. if (m_icon != NULL)
  248. {
  249. m_fIconChanged = true;
  250. m_strIconFile = szIconFile;
  251. m_nIconIndex = nIconIndex;
  252. m_wndIcon.SetIcon (m_icon);
  253. SetModified();
  254. }
  255. }
  256. }
  257. void CConsolePropPage::OnChangeCustomTitle()
  258. {
  259. m_fTitleChanged = true;
  260. SetModified();
  261. }
  262. /////////////////////////////////////////////////////////////////////////////
  263. // CDiskCleanupPage property page
  264. IMPLEMENT_DYNCREATE(CDiskCleanupPage, CPropertyPage)
  265. BEGIN_MESSAGE_MAP(CDiskCleanupPage, CPropertyPage)
  266. ON_MMC_CONTEXT_HELP()
  267. ON_BN_CLICKED(IDC_DELETE_TEMP_FILES, OnDeleteTemporaryFiles)
  268. END_MESSAGE_MAP()
  269. CDiskCleanupPage::CDiskCleanupPage() : CPropertyPage(CDiskCleanupPage::IDD)
  270. {
  271. }
  272. CDiskCleanupPage::~CDiskCleanupPage()
  273. {
  274. }
  275. BOOL CDiskCleanupPage::OnInitDialog()
  276. {
  277. CPropertyPage::OnInitDialog();
  278. ScRecalculateUsedSpace();
  279. return TRUE;
  280. }
  281. /***************************************************************************\
  282. *
  283. * METHOD: CDiskCleanupPage::OnDeleteTemporaryFiles
  284. *
  285. * PURPOSE: Invoked when "Delete Filed" button is pressed
  286. * Removes all files from MMC folder storing the user data
  287. *
  288. * PARAMETERS:
  289. *
  290. * RETURNS:
  291. *
  292. \***************************************************************************/
  293. void CDiskCleanupPage::OnDeleteTemporaryFiles()
  294. {
  295. DECLARE_SC(sc, TEXT("CDiskCleanupPage::OnDeleteTemporaryFiles"));
  296. // ask user if he is sure...
  297. CString strConfirmMessage;
  298. CString strConfirmCaption;
  299. if (!LoadString(strConfirmMessage, IDS_ConfirmDeleteTempFiles) ||
  300. !LoadString(strConfirmCaption, IDR_MAINFRAME))
  301. {
  302. sc = E_UNEXPECTED;
  303. return;
  304. }
  305. int ans = ::MessageBox( m_hWnd, strConfirmMessage, strConfirmCaption, MB_YESNO | MB_ICONWARNING);
  306. if ( ans != IDYES )
  307. return;
  308. // display wait cursor while working
  309. CWaitCursor cursorWait;
  310. // get folder
  311. tstring strFileFolder;
  312. sc = CConsoleFilePersistor::ScGetUserDataFolder(strFileFolder);
  313. if (sc)
  314. return;
  315. // get file mask
  316. tstring strFileMask = strFileFolder;
  317. strFileMask += _T("\\*.*");
  318. WIN32_FIND_DATA findFileData;
  319. ZeroMemory( &findFileData, sizeof(findFileData) );
  320. // start file search
  321. HANDLE hFindFile = FindFirstFile( strFileMask.c_str(), &findFileData );
  322. if ( hFindFile == INVALID_HANDLE_VALUE )
  323. {
  324. sc.FromLastError();
  325. return;
  326. }
  327. // loop thru files and delete them
  328. bool bContinue = true;
  329. while ( bContinue )
  330. {
  331. tstring strFileToDelete = strFileFolder + _T('\\') + findFileData.cFileName;
  332. DWORD dwFileAttributes = findFileData.dwFileAttributes;
  333. // get to the next file first
  334. bContinue = FindNextFile( hFindFile, &findFileData );
  335. // delete files, but not directories
  336. if ( 0 == (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
  337. {
  338. // delete
  339. if ( !DeleteFile( strFileToDelete.c_str() ) )
  340. {
  341. // trace on errors (but do not stop)
  342. sc.FromLastError().TraceAndClear();
  343. }
  344. }
  345. }
  346. // Done, release the handle
  347. FindClose(hFindFile);
  348. sc = ScRecalculateUsedSpace();
  349. if (sc)
  350. sc.TraceAndClear();
  351. }
  352. /***************************************************************************\
  353. *
  354. * METHOD: CDiskCleanupPage::ScRecalculateUsedSpace
  355. *
  356. * PURPOSE: Recalculates and displays disk space occupied by user data in this profile
  357. *
  358. * PARAMETERS:
  359. *
  360. * RETURNS:
  361. * SC - result code
  362. *
  363. \***************************************************************************/
  364. SC CDiskCleanupPage::ScRecalculateUsedSpace()
  365. {
  366. DECLARE_SC(sc, TEXT("CDiskCleanupPage::ScRecalculateUsedSpace"));
  367. // display wait cursor while working
  368. CWaitCursor cursorWait;
  369. // get folder
  370. tstring strFileFolder;
  371. sc = CConsoleFilePersistor::ScGetUserDataFolder(strFileFolder);
  372. if (sc)
  373. return sc;
  374. // get file mask
  375. tstring strFileMask = strFileFolder;
  376. strFileMask += _T("\\*.*");
  377. WIN32_FIND_DATA findFileData;
  378. ZeroMemory( &findFileData, sizeof(findFileData) );
  379. // start file search
  380. HANDLE hFindFile = FindFirstFile( strFileMask.c_str(), &findFileData );
  381. if ( hFindFile == INVALID_HANDLE_VALUE )
  382. return sc.FromLastError();
  383. // loop thru files and count size
  384. ULARGE_INTEGER ulgOccupied = {0};
  385. bool bContinue = true;
  386. while ( bContinue )
  387. {
  388. DWORD dwFileAttributes = findFileData.dwFileAttributes;
  389. if ( 0 == (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
  390. {
  391. // add the high and low part separatelly, since findFileData does not have it bundled
  392. ulgOccupied.HighPart += findFileData.nFileSizeHigh;
  393. // add lower part to the whole large integer not to lose carry on overflow
  394. ulgOccupied.QuadPart += findFileData.nFileSizeLow;
  395. }
  396. // get to the next file first
  397. bContinue = FindNextFile( hFindFile, &findFileData );
  398. }
  399. // Done, release the handle
  400. FindClose(hFindFile);
  401. // now conver the size into string
  402. UINT nTerraBytes = (UINT)(ulgOccupied.QuadPart >> 40);
  403. UINT nGigaBytes = (UINT)(ulgOccupied.QuadPart >> 30) & 0x3ff;
  404. UINT nMegaBytes = ((ulgOccupied.LowPart >> 20) & 0x3ff);
  405. UINT nKiloBytes = ((ulgOccupied.LowPart >> 10) & 0x3ff);
  406. UINT nBytes = ( ulgOccupied.LowPart & 0x3ff);
  407. CString strUnit;
  408. double dSize = 0.0;
  409. bool bNonZeroOccupied = (ulgOccupied.QuadPart != 0);
  410. // display only biggest units, and never more than 999
  411. // instead of "1001 KB" we display "0.98 MB"
  412. if ( (nTerraBytes) > 0 || (nGigaBytes > 999) )
  413. {
  414. LoadString(strUnit, IDS_FileSize_TB);
  415. dSize = (double)nTerraBytes + ((double)nGigaBytes / 1024.);
  416. }
  417. else if ( (nGigaBytes) > 0 || (nMegaBytes > 999) )
  418. {
  419. LoadString(strUnit, IDS_FileSize_GB);
  420. dSize = (double)nGigaBytes + ((double)nMegaBytes / 1024.);
  421. }
  422. else if ( (nMegaBytes) > 0 || (nKiloBytes > 999) )
  423. {
  424. LoadString(strUnit, IDS_FileSize_MB);
  425. dSize = (double)nMegaBytes + ((double)nKiloBytes / 1024.);
  426. }
  427. else if ( (nKiloBytes) > 0 || (nBytes > 999) )
  428. {
  429. LoadString(strUnit, IDS_FileSize_KB);
  430. dSize = (double)nKiloBytes + ((double)nBytes / 1024.);
  431. }
  432. else
  433. {
  434. LoadString(strUnit, IDS_FileSize_bytes);
  435. dSize = (double)nBytes;
  436. }
  437. // format with op to two decimal points
  438. CString strSize;
  439. strSize.Format(_T("%.2f"), dSize);
  440. //truncate trailing zeros
  441. while (strSize.Right(1) == _T("0"))
  442. strSize = strSize.Left(strSize.GetLength() - 1);
  443. //truncate trailing decimal point
  444. if (strSize.Right(1) == _T("."))
  445. strSize = strSize.Left(strSize.GetLength() - 1);
  446. // add units ( in locale independant way )
  447. strUnit.Replace(_T("%1"), strSize);
  448. // set to the window
  449. SetDlgItemText( IDC_DISKCLEANUP_OCCUPIED, strUnit );
  450. // enable/disable "Delete Files" button
  451. CWnd *pWndDeleteBtn = GetDlgItem(IDC_DELETE_TEMP_FILES);
  452. sc = ScCheckPointers( pWndDeleteBtn, E_UNEXPECTED );
  453. if (sc)
  454. return sc;
  455. pWndDeleteBtn->EnableWindow( bNonZeroOccupied );
  456. // if the focus went away (belonged to the window being disabled)
  457. // set it to the OK button
  458. if ( ::GetFocus() == NULL && GetParent())
  459. {
  460. GetParent()->SetFocus();
  461. GetParent()->SendMessage(DM_SETDEFID, IDOK);
  462. }
  463. return sc;
  464. }