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.

987 lines
24 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 1996.
  5. //
  6. // File: settings.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // Notes: For the first release of the scheduling agent, all security
  15. // operations are disabled under Win95, even Win95 to NT.
  16. //
  17. // History: 3/4/1996 RaviR Created
  18. //
  19. //____________________________________________________________________________
  20. #include "..\pch\headers.hxx"
  21. #pragma hdrstop
  22. #include <mstask.h>
  23. #include "..\inc\common.hxx"
  24. #include "..\folderui\dbg.h"
  25. #include "..\folderui\macros.h"
  26. #include "..\folderui\util.hxx"
  27. #if !defined(_CHICAGO_)
  28. #include "..\inc\network.hxx"
  29. #endif // !defined(_CHICAGO_)
  30. #include "..\inc\dll.hxx"
  31. #include "dlg.hxx"
  32. #include "rc.h"
  33. #include "defines.h"
  34. #include "uiutil.hxx"
  35. #include "helpids.h"
  36. #include "schedui.hxx"
  37. //
  38. // (Control id, help id) list for context sensitivity help.
  39. //
  40. ULONG s_aSettingsPageHelpIds[] =
  41. {
  42. chk_start_on_idle, Hchk_start_on_idle,
  43. chk_stop_if_not_idle, Hchk_stop_if_not_idle,
  44. chk_dont_start_if_on_batteries, Hchk_dont_start_if_on_batteries,
  45. chk_kill_if_going_on_batteries, Hchk_kill_if_going_on_batteries,
  46. chk_delete_when_done, Hchk_delete_when_done,
  47. chk_stop_after, Hchk_stop_after,
  48. txt_stop_after_hr, Htxt_stop_after_hr,
  49. spin_stop_after_hr, Hspin_stop_after_hr,
  50. txt_stop_after_min, Htxt_stop_after_min,
  51. spin_stop_after_min, Hspin_stop_after_min,
  52. txt_idle_min, Htxt_idle_min,
  53. spin_idle_min, Hspin_idle_min,
  54. lbl_idle_deadline1, Hlbl_idle_deadline,
  55. lbl_idle_deadline2, Hlbl_idle_deadline,
  56. txt_idle_deadline, Htxt_idle_deadline,
  57. spin_idle_deadline, Hspin_idle_deadline,
  58. lbl_min, Hlbl_settings_min,
  59. lbl_hours, Hlbl_settings_hours,
  60. grp_idle_time, Hgrp_idle_time,
  61. txt_idle_minutes, Htxt_idle_minutes,
  62. grp_task_completed, Hgrp_task_completed,
  63. grp_power_management, Hgrp_power_management,
  64. btn_new, Hbtn_new,
  65. btn_delete, Hbtn_delete,
  66. chk_system_required, Hchk_system_required,
  67. 0,0
  68. };
  69. extern "C" TCHAR szMstaskHelp[];
  70. //
  71. // extern
  72. //
  73. extern HINSTANCE g_hInstance;
  74. //
  75. // All task flags included in this define will be modified when the page
  76. // values are persisted in the _OnApply method.
  77. //
  78. // If we're running on NT and targeting NT, the controls for some of these
  79. // flags will be initialized to the job's values and hidden.
  80. //
  81. #define TASK_FLAGS_IN_SETTINGS_PAGE (TASK_FLAG_START_ONLY_IF_IDLE | \
  82. TASK_FLAG_KILL_ON_IDLE_END | \
  83. TASK_FLAG_DONT_START_IF_ON_BATTERIES | \
  84. TASK_FLAG_KILL_IF_GOING_ON_BATTERIES | \
  85. TASK_FLAG_SYSTEM_REQUIRED | \
  86. TASK_FLAG_DELETE_WHEN_DONE)
  87. //____________________________________________________________________________
  88. //____________________________________________________________________________
  89. //________________ ______________________________________
  90. //________________ class CSettingsPage ______________________________________
  91. //________________ ______________________________________
  92. //____________________________________________________________________________
  93. //____________________________________________________________________________
  94. class CSettingsPage : public CPropPage
  95. {
  96. public:
  97. CSettingsPage(ITask * pIJob,
  98. LPTSTR ptszTaskPath,
  99. BOOL fPersistChanges);
  100. ~CSettingsPage();
  101. private:
  102. virtual LRESULT _OnInitDialog(LPARAM lParam);
  103. virtual LRESULT _OnCommand(int id, HWND hwndCtl, UINT codeNotify);
  104. virtual LRESULT _OnApply();
  105. virtual LRESULT _OnPSMQuerySibling(WPARAM wParam, LPARAM lParam);
  106. virtual LRESULT _OnPSNSetActive(LPARAM lParam);
  107. virtual LRESULT _OnPSNKillActive(LPARAM lParam);
  108. virtual LRESULT _OnHelp(HANDLE hRequesting, UINT uiHelpCommand);
  109. void _ReadIdleSettings();
  110. void _ErrorDialog(int idsErr, LONG error = 0, UINT idsHelpHint = 0)
  111. { SchedUIErrorDialog(Hwnd(), idsErr, error, idsHelpHint); }
  112. BOOL _PerformSanityChk();
  113. ITask * m_pIJob;
  114. DWORD m_dwFlags;
  115. DWORD m_dwMaxRunTime;
  116. WORD m_wIdleWait;
  117. WORD m_wIdleDeadline;
  118. //
  119. // Should we save on Apply or OK.
  120. //
  121. BOOL m_fPersistChanges;
  122. }; // class CSettingsPage
  123. inline
  124. CSettingsPage::CSettingsPage(
  125. ITask * pIJob,
  126. LPTSTR ptszTaskPath,
  127. BOOL fPersistChanges)
  128. :
  129. m_pIJob(pIJob),
  130. m_fPersistChanges(fPersistChanges),
  131. m_dwFlags(0),
  132. m_dwMaxRunTime(0),
  133. m_wIdleWait(0),
  134. m_wIdleDeadline(0),
  135. CPropPage(MAKEINTRESOURCE(settings_page), ptszTaskPath)
  136. {
  137. TRACE(CSettingsPage, CSettingsPage);
  138. Win4Assert(m_pIJob != NULL);
  139. pIJob->AddRef();
  140. }
  141. inline
  142. CSettingsPage::~CSettingsPage()
  143. {
  144. TRACE(CSettingsPage, ~CSettingsPage);
  145. if (m_pIJob != NULL)
  146. {
  147. m_pIJob->Release();
  148. }
  149. }
  150. LRESULT
  151. CSettingsPage::_OnHelp(
  152. HANDLE hRequesting,
  153. UINT uiHelpCommand)
  154. {
  155. WinHelp((HWND)hRequesting,
  156. szMstaskHelp,
  157. uiHelpCommand,
  158. (DWORD_PTR)(LPSTR)s_aSettingsPageHelpIds);
  159. return TRUE;
  160. }
  161. LRESULT
  162. CSettingsPage::_OnInitDialog(
  163. LPARAM lParam)
  164. {
  165. TRACE(CSettingsPage, _OnInitDialog);
  166. HRESULT hr = S_OK;
  167. ITask * pIJob = m_pIJob;
  168. Spin_SetRange(m_hPage, spin_idle_min, 1, MAX_IDLE_MINUTES);
  169. Edit_LimitText(_hCtrl(txt_idle_min), MAX_IDLE_DIGITS);
  170. Spin_SetRange(m_hPage, spin_idle_deadline, 0, MAX_IDLE_MINUTES);
  171. Edit_LimitText(_hCtrl(txt_idle_deadline), MAX_IDLE_DIGITS);
  172. Spin_SetRange(m_hPage, spin_stop_after_hr, 0, MAX_MAXRUNTIME_HOURS);
  173. Edit_LimitText(_hCtrl(txt_stop_after_hr), MAX_MAXRUNTIME_DIGITS);
  174. Spin_SetRange(m_hPage, spin_stop_after_min, 0, 59);
  175. Edit_LimitText(_hCtrl(txt_stop_after_min), 2);
  176. do
  177. {
  178. //
  179. // Set job flags
  180. //
  181. hr = pIJob->GetFlags(&m_dwFlags);
  182. CHECK_HRESULT(hr);
  183. BREAK_ON_FAIL(hr);
  184. CheckDlgButton(m_hPage, chk_start_on_idle,
  185. (m_dwFlags & TASK_FLAG_START_ONLY_IF_IDLE));
  186. CheckDlgButton(m_hPage, chk_stop_if_not_idle,
  187. (m_dwFlags & TASK_FLAG_KILL_ON_IDLE_END));
  188. CheckDlgButton(m_hPage, chk_dont_start_if_on_batteries,
  189. (m_dwFlags & TASK_FLAG_DONT_START_IF_ON_BATTERIES));
  190. CheckDlgButton(m_hPage, chk_kill_if_going_on_batteries,
  191. (m_dwFlags & TASK_FLAG_KILL_IF_GOING_ON_BATTERIES));
  192. CheckDlgButton(m_hPage, chk_system_required,
  193. (m_dwFlags & TASK_FLAG_SYSTEM_REQUIRED));
  194. CheckDlgButton(m_hPage, chk_delete_when_done,
  195. (m_dwFlags & TASK_FLAG_DELETE_WHEN_DONE));
  196. //
  197. // Not all machines have resume timers, which are used to support the
  198. // TASK_FLAG_SYSTEM_REQUIRED flag. If the target machine doesn't
  199. // have resume timers, hide the control.
  200. //
  201. if (!SupportsSystemRequired())
  202. {
  203. RECT rcSysReq;
  204. RECT rcGroup;
  205. LONG cy;
  206. //
  207. // Get the distance in pixels from the top of the system required
  208. // checkbox to the bottom of the group window.
  209. //
  210. // Reduce the height of the groupbox by this amount.
  211. //
  212. GetWindowRect(_hCtrl(chk_system_required), &rcSysReq);
  213. GetWindowRect(_hCtrl(grp_power_management), &rcGroup);
  214. cy = rcGroup.bottom - rcSysReq.top + 1;
  215. //
  216. // Hide the checkbox and resize the group window
  217. //
  218. ShowWindow(_hCtrl(chk_system_required), SW_HIDE);
  219. SetWindowPos(_hCtrl(grp_power_management),
  220. NULL,
  221. 0,0,
  222. rcGroup.right - rcGroup.left + 1,
  223. rcGroup.bottom - rcGroup.top - cy + 1,
  224. SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  225. }
  226. //
  227. // Init idle controls
  228. //
  229. hr = m_pIJob->GetIdleWait(&m_wIdleWait, &m_wIdleDeadline);
  230. CHECK_HRESULT(hr);
  231. BREAK_ON_FAIL(hr);
  232. if (m_wIdleWait > MAX_IDLE_MINUTES)
  233. {
  234. m_wIdleWait = MAX_IDLE_MINUTES;
  235. }
  236. if (m_wIdleDeadline > MAX_IDLE_MINUTES)
  237. {
  238. m_wIdleDeadline = MAX_IDLE_MINUTES;
  239. }
  240. if (m_dwFlags & TASK_FLAG_START_ONLY_IF_IDLE)
  241. {
  242. Spin_Enable(m_hPage, spin_idle_min, m_wIdleWait);
  243. Spin_Enable(m_hPage, spin_idle_deadline, m_wIdleDeadline);
  244. Spin_SetPos(m_hPage, spin_idle_min, m_wIdleWait);
  245. Spin_SetPos(m_hPage, spin_idle_deadline, m_wIdleDeadline);
  246. }
  247. else
  248. {
  249. m_wIdleWait = SCH_DEFAULT_IDLE_TIME;
  250. m_wIdleDeadline = SCH_DEFAULT_IDLE_DEADLINE;
  251. Spin_Disable(m_hPage, spin_idle_min);
  252. Spin_Disable(m_hPage, spin_idle_deadline);
  253. }
  254. //
  255. // Set max run time
  256. //
  257. hr = pIJob->GetMaxRunTime(&m_dwMaxRunTime);
  258. CHECK_HRESULT(hr);
  259. BREAK_ON_FAIL(hr);
  260. if (m_dwMaxRunTime != (DWORD)-1)
  261. {
  262. CheckDlgButton(m_hPage, chk_stop_after, BST_CHECKED);
  263. //
  264. // Convert to minutes from milliseconds. If the value is larger
  265. // than the UI supports, reduce it.
  266. //
  267. m_dwMaxRunTime /= 60000;
  268. if (m_dwMaxRunTime > (MAX_MAXRUNTIME_HOURS * 60 + 59))
  269. {
  270. m_dwMaxRunTime = MAX_MAXRUNTIME_HOURS * 60 + 59;
  271. }
  272. WORD wHours = (WORD) (m_dwMaxRunTime / 60);
  273. WORD wMins = (WORD) (m_dwMaxRunTime % 60);
  274. Spin_SetPos(m_hPage, spin_stop_after_hr, wHours);
  275. Spin_SetPos(m_hPage, spin_stop_after_min, wMins);
  276. }
  277. else
  278. {
  279. CheckDlgButton(m_hPage, chk_stop_after, BST_UNCHECKED);
  280. Spin_Disable(m_hPage, spin_stop_after_hr);
  281. Spin_Disable(m_hPage, spin_stop_after_min);
  282. }
  283. } while (0);
  284. if (FAILED(hr))
  285. {
  286. if (hr == E_OUTOFMEMORY)
  287. {
  288. _ErrorDialog(IERR_OUT_OF_MEMORY);
  289. }
  290. else
  291. {
  292. _ErrorDialog(IERR_SETTINGS_PAGE_INIT, hr);
  293. }
  294. EnableWindow(Hwnd(), FALSE);
  295. return FALSE;
  296. }
  297. m_fDirty = FALSE;
  298. return TRUE;
  299. }
  300. LRESULT
  301. CSettingsPage::_OnCommand(
  302. int id,
  303. HWND hwndCtl,
  304. UINT codeNotify)
  305. {
  306. TRACE(CSettingsPage, _OnCommand);
  307. switch (id)
  308. {
  309. case chk_stop_after:
  310. if (codeNotify != BN_CLICKED)
  311. {
  312. return TRUE;
  313. }
  314. if (IsDlgButtonChecked(m_hPage, chk_stop_after) == BST_CHECKED)
  315. {
  316. Spin_Enable(m_hPage,
  317. spin_stop_after_hr,
  318. DEFAULT_MAXRUNTIME_HOURS);
  319. Spin_Enable(m_hPage,
  320. spin_stop_after_min,
  321. DEFAULT_MAXRUNTIME_MINUTES);
  322. }
  323. else
  324. {
  325. Spin_Disable(m_hPage, spin_stop_after_hr);
  326. Spin_Disable(m_hPage, spin_stop_after_min);
  327. }
  328. break;
  329. case chk_start_on_idle:
  330. if (codeNotify != BN_CLICKED)
  331. {
  332. return TRUE;
  333. }
  334. if (IsDlgButtonChecked(m_hPage, chk_start_on_idle) == BST_CHECKED)
  335. {
  336. Spin_Enable(m_hPage, spin_idle_min, m_wIdleWait);
  337. Spin_Enable(m_hPage, spin_idle_deadline, m_wIdleDeadline);
  338. }
  339. else
  340. {
  341. Spin_Disable(m_hPage, spin_idle_min);
  342. Spin_Disable(m_hPage, spin_idle_deadline);
  343. }
  344. break;
  345. case txt_idle_min:
  346. case txt_idle_deadline:
  347. case txt_stop_after_hr:
  348. case txt_stop_after_min:
  349. if (codeNotify != EN_CHANGE)
  350. {
  351. return TRUE;
  352. }
  353. break;
  354. // case spin_stop_after_hr:
  355. // case spin_stop_after_min:
  356. // break;
  357. case chk_stop_if_not_idle:
  358. case chk_dont_start_if_on_batteries:
  359. case chk_kill_if_going_on_batteries:
  360. case chk_delete_when_done:
  361. case chk_system_required:
  362. if (codeNotify != BN_CLICKED)
  363. {
  364. return TRUE;
  365. }
  366. break;
  367. default:
  368. return FALSE;
  369. }
  370. _EnableApplyButton();
  371. return TRUE;
  372. }
  373. //+--------------------------------------------------------------------------
  374. //
  375. // Member: CSettingsPage::_ReadIdleSettings
  376. //
  377. // Synopsis: Move the idle settings from the edit controls to the member
  378. // variables, setting them on the job if they have been
  379. // updated.
  380. //
  381. // History: 07-17-1997 DavidMun Created
  382. //
  383. //---------------------------------------------------------------------------
  384. void
  385. CSettingsPage::_ReadIdleSettings()
  386. {
  387. ULONG ulSpinPos;
  388. WORD wIdleWait;
  389. WORD wIdleDeadline;
  390. //
  391. // If idle wait isn't turned on, the controls don't have meaningful
  392. // values.
  393. //
  394. if (IsDlgButtonChecked(m_hPage, chk_start_on_idle) != BST_CHECKED)
  395. {
  396. return;
  397. }
  398. ulSpinPos = Spin_GetPos(m_hPage, spin_idle_min);
  399. if (HIWORD(ulSpinPos))
  400. {
  401. wIdleWait = SCH_DEFAULT_IDLE_TIME;
  402. }
  403. else
  404. {
  405. wIdleWait = LOWORD(ulSpinPos);
  406. }
  407. ulSpinPos = Spin_GetPos(m_hPage, spin_idle_deadline);
  408. if (HIWORD(ulSpinPos))
  409. {
  410. wIdleDeadline = SCH_DEFAULT_IDLE_DEADLINE;
  411. }
  412. else
  413. {
  414. wIdleDeadline = LOWORD(ulSpinPos);
  415. }
  416. if (m_wIdleWait != wIdleWait || m_wIdleDeadline != wIdleDeadline)
  417. {
  418. HRESULT hr;
  419. hr = m_pIJob->SetIdleWait(wIdleWait, wIdleDeadline);
  420. CHECK_HRESULT(hr);
  421. if (SUCCEEDED(hr))
  422. {
  423. m_wIdleWait = wIdleWait;
  424. m_wIdleDeadline = wIdleDeadline;
  425. }
  426. }
  427. }
  428. BOOL
  429. CSettingsPage::_PerformSanityChk(void)
  430. {
  431. ULONG ul;
  432. if (IsDlgButtonChecked(m_hPage, chk_stop_after) == BST_CHECKED)
  433. {
  434. ul = GetDlgItemInt(Hwnd(), txt_stop_after_hr, NULL, FALSE);
  435. if (!ul)
  436. {
  437. ul = GetDlgItemInt(Hwnd(), txt_stop_after_min, NULL, FALSE);
  438. if (!ul)
  439. {
  440. Spin_SetPos(Hwnd(), spin_stop_after_min, 1);
  441. _ErrorDialog(IERR_MAXRUNTIME);
  442. return FALSE;
  443. }
  444. }
  445. }
  446. return TRUE;
  447. }
  448. LRESULT
  449. CSettingsPage::_OnPSNKillActive(
  450. LPARAM lParam)
  451. {
  452. TRACE(CSettingsPage, _OnPSNKillActive);
  453. if (_PerformSanityChk() == FALSE)
  454. {
  455. // Returns TRUE to prevent the page from losing the activation
  456. SetWindowLongPtr(m_hPage, DWLP_MSGRESULT, TRUE);
  457. return TRUE;
  458. }
  459. //
  460. // Make sure Schedule page is synchronized with IdleWait changes.
  461. //
  462. _ReadIdleSettings();
  463. return CPropPage::_OnPSNKillActive(lParam);
  464. }
  465. LRESULT
  466. CSettingsPage::_OnPSNSetActive(LPARAM lParam)
  467. {
  468. m_fInInit = TRUE;
  469. //
  470. // Make sure IdleWait is synchronized with Schedule page changes.
  471. //
  472. WORD wDummy;
  473. HRESULT hr = m_pIJob->GetIdleWait(&m_wIdleWait, &wDummy);
  474. if (SUCCEEDED(hr) &&
  475. IsDlgButtonChecked(m_hPage, chk_start_on_idle) == BST_CHECKED)
  476. {
  477. Spin_SetPos(m_hPage, spin_idle_min, m_wIdleWait);
  478. }
  479. m_fInInit = FALSE;
  480. return CPropPage::_OnPSNSetActive(lParam);
  481. }
  482. LRESULT
  483. CSettingsPage::_OnApply(void)
  484. {
  485. TRACE(CSettingsPage, _OnApply);
  486. //DbxDisplay("CSettingsPage::_OnApply");
  487. if (m_fDirty == FALSE)
  488. {
  489. return TRUE;
  490. }
  491. if (_PerformSanityChk() == FALSE)
  492. {
  493. SetWindowLongPtr(Hwnd(), DWLP_MSGRESULT, FALSE);
  494. return FALSE;
  495. }
  496. HRESULT hr = S_OK;
  497. ITask * pIJob = m_pIJob;
  498. DWORD dwFlags = 0;
  499. do
  500. {
  501. if (IsDlgButtonChecked(m_hPage, chk_start_on_idle) == BST_CHECKED)
  502. {
  503. dwFlags |= TASK_FLAG_START_ONLY_IF_IDLE;
  504. }
  505. if (IsDlgButtonChecked(m_hPage, chk_stop_if_not_idle) == BST_CHECKED)
  506. {
  507. dwFlags |= TASK_FLAG_KILL_ON_IDLE_END;
  508. }
  509. if (IsDlgButtonChecked(m_hPage, chk_dont_start_if_on_batteries)
  510. == BST_CHECKED)
  511. {
  512. dwFlags |= TASK_FLAG_DONT_START_IF_ON_BATTERIES;
  513. }
  514. if (IsDlgButtonChecked(m_hPage, chk_kill_if_going_on_batteries) ==
  515. BST_CHECKED)
  516. {
  517. dwFlags |= TASK_FLAG_KILL_IF_GOING_ON_BATTERIES;
  518. }
  519. if (IsDlgButtonChecked(m_hPage, chk_system_required) ==
  520. BST_CHECKED)
  521. {
  522. dwFlags |= TASK_FLAG_SYSTEM_REQUIRED;
  523. }
  524. if (IsDlgButtonChecked(m_hPage, chk_delete_when_done) == BST_CHECKED)
  525. {
  526. dwFlags |= TASK_FLAG_DELETE_WHEN_DONE;
  527. }
  528. if ((m_dwFlags & TASK_FLAGS_IN_SETTINGS_PAGE) != dwFlags)
  529. {
  530. hr = pIJob->GetFlags(&m_dwFlags);
  531. CHECK_HRESULT(hr);
  532. BREAK_ON_FAIL(hr);
  533. dwFlags |= (m_dwFlags & ~TASK_FLAGS_IN_SETTINGS_PAGE);
  534. hr = pIJob->SetFlags(dwFlags);
  535. CHECK_HRESULT(hr);
  536. BREAK_ON_FAIL(hr);
  537. m_dwFlags = dwFlags;
  538. }
  539. _ReadIdleSettings();
  540. DWORD dwMins = (DWORD)-1;
  541. if (IsDlgButtonChecked(m_hPage, chk_stop_after) == BST_CHECKED)
  542. {
  543. ULONG ulSpinPos = Spin_GetPos(m_hPage, spin_stop_after_hr);
  544. if (HIWORD(ulSpinPos))
  545. {
  546. dwMins = DEFAULT_MAXRUNTIME_HOURS * 60;
  547. }
  548. else
  549. {
  550. dwMins = LOWORD(ulSpinPos) * 60;
  551. }
  552. ulSpinPos = Spin_GetPos(m_hPage, spin_stop_after_min);
  553. if (HIWORD(ulSpinPos))
  554. {
  555. dwMins += DEFAULT_MAXRUNTIME_MINUTES;
  556. }
  557. else
  558. {
  559. dwMins += LOWORD(ulSpinPos);
  560. }
  561. }
  562. Win4Assert(dwMins != 0);
  563. if (m_dwMaxRunTime != dwMins)
  564. {
  565. // Max run time is in milliseconds
  566. hr = pIJob->SetMaxRunTime(
  567. ((dwMins == (DWORD)-1) ? (DWORD)-1 : (dwMins * 60000)));
  568. CHECK_HRESULT(hr);
  569. BREAK_ON_FAIL(hr);
  570. m_dwMaxRunTime = dwMins;
  571. }
  572. //
  573. // reset dirty flag
  574. //
  575. m_fDirty = FALSE;
  576. //
  577. // If evrything went well see if the other pages are ready to
  578. // save the job to storage.
  579. //
  580. if ((m_fPersistChanges == TRUE) &&
  581. (PropSheet_QuerySiblings(GetParent(Hwnd()),
  582. QUERY_READY_TO_BE_SAVED, 0))
  583. == 0)
  584. {
  585. //
  586. // Save the job file to storage.
  587. //
  588. // First, fetch general page task, application dirty status flags.
  589. // Default to not dirty if the general page isn't present.
  590. //
  591. #if !defined(_CHICAGO_)
  592. BOOL fTaskApplicationChange = FALSE;
  593. PropSheet_QuerySiblings(GetParent(Hwnd()),
  594. QUERY_TASK_APPLICATION_DIRTY_STATUS,
  595. (LPARAM)&fTaskApplicationChange);
  596. BOOL fTaskAccountChange = FALSE;
  597. PropSheet_QuerySiblings(GetParent(Hwnd()),
  598. QUERY_TASK_ACCOUNT_INFO_DIRTY_STATUS,
  599. (LPARAM)&fTaskAccountChange);
  600. BOOL fSuppressAccountInfoRequest = FALSE;
  601. PropSheet_QuerySiblings(GetParent(Hwnd()),
  602. QUERY_SUPPRESS_ACCOUNT_INFO_REQUEST_FLAG,
  603. (LPARAM)&fSuppressAccountInfoRequest);
  604. #endif // !defined(_CHICAGO_)
  605. hr = JFSaveJob(Hwnd(),
  606. pIJob,
  607. #if !defined(_CHICAGO_)
  608. this->GetPlatformId() == VER_PLATFORM_WIN32_NT &&
  609. this->IsTaskInTasksFolder(),
  610. fTaskAccountChange,
  611. fTaskApplicationChange,
  612. fSuppressAccountInfoRequest);
  613. #else
  614. FALSE,
  615. FALSE,
  616. FALSE);
  617. #endif // !defined(_CHICAGO_)
  618. CHECK_HRESULT(hr);
  619. BREAK_ON_FAIL(hr);
  620. #if !defined(_CHICAGO_)
  621. PropSheet_QuerySiblings(GetParent(Hwnd()),
  622. RESET_TASK_APPLICATION_DIRTY_STATUS, 0);
  623. PropSheet_QuerySiblings(GetParent(Hwnd()),
  624. RESET_TASK_ACCOUNT_INFO_DIRTY_STATUS, 0);
  625. PropSheet_QuerySiblings(GetParent(Hwnd()),
  626. RESET_SUPPRESS_ACCOUNT_INFO_REQUEST_FLAG, 0);
  627. //
  628. // Instruct the general page to refresh account information.
  629. //
  630. PropSheet_QuerySiblings(GetParent(Hwnd()),
  631. TASK_ACCOUNT_CHANGE_NOTIFY, 0);
  632. #endif // !defined(_CHICAGO_)
  633. }
  634. } while (0);
  635. if (FAILED(hr))
  636. {
  637. if (hr == E_OUTOFMEMORY)
  638. {
  639. _ErrorDialog(IERR_OUT_OF_MEMORY);
  640. }
  641. else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  642. {
  643. _ErrorDialog(IERR_FILE_NOT_FOUND);
  644. }
  645. else if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED))
  646. {
  647. _ErrorDialog(IERR_ACCESS_DENIED);
  648. }
  649. else
  650. {
  651. _ErrorDialog(IERR_INTERNAL_ERROR, hr);
  652. }
  653. }
  654. return TRUE;
  655. }
  656. LRESULT
  657. CSettingsPage::_OnPSMQuerySibling(
  658. WPARAM wParam,
  659. LPARAM lParam)
  660. {
  661. int iRet = 0;
  662. switch (wParam)
  663. {
  664. case QUERY_READY_TO_BE_SAVED:
  665. iRet = (int)m_fDirty;
  666. break;
  667. }
  668. SetWindowLongPtr(Hwnd(), DWLP_MSGRESULT, iRet);
  669. return iRet;
  670. }
  671. HRESULT
  672. GetSettingsPage(
  673. ITask * pIJob,
  674. LPTSTR ptszTaskPath,
  675. BOOL fPersistChanges,
  676. HPROPSHEETPAGE * phpage)
  677. {
  678. Win4Assert(pIJob != NULL);
  679. Win4Assert(phpage != NULL);
  680. LPTSTR ptszPath = NULL;
  681. HRESULT hr = S_OK;
  682. WORD cTriggers = 0;
  683. do
  684. {
  685. //
  686. // Get the job name.
  687. //
  688. if (ptszTaskPath != NULL)
  689. {
  690. //
  691. // Use passed-in path
  692. //
  693. ptszPath = ptszTaskPath;
  694. }
  695. else
  696. {
  697. //
  698. // Obtain the job path from the interfaces.
  699. //
  700. hr = GetJobPath(pIJob, &ptszPath);
  701. BREAK_ON_FAIL(hr);
  702. }
  703. hr = pIJob->GetTriggerCount(&cTriggers);
  704. if (FAILED(hr))
  705. {
  706. CHECK_HRESULT(hr);
  707. break;
  708. }
  709. CSettingsPage * pPage = new CSettingsPage(
  710. pIJob,
  711. ptszPath,
  712. fPersistChanges);
  713. if (pPage == NULL)
  714. {
  715. hr = E_OUTOFMEMORY;
  716. CHECK_HRESULT(hr);
  717. break;
  718. }
  719. HPROPSHEETPAGE hpage = CreatePropertySheetPage(&pPage->m_psp);
  720. if (hpage == NULL)
  721. {
  722. delete pPage;
  723. hr = E_OUTOFMEMORY;
  724. CHECK_HRESULT(hr);
  725. break;
  726. }
  727. *phpage = hpage;
  728. } while (0);
  729. //
  730. // If we made a copy of pIJob's path string, free it.
  731. //
  732. if (ptszPath != ptszTaskPath)
  733. {
  734. delete [] ptszPath;
  735. }
  736. return hr;
  737. }
  738. HRESULT
  739. AddSettingsPage(
  740. PROPSHEETHEADER &psh,
  741. ITask * pIJob)
  742. {
  743. HPROPSHEETPAGE hpage = NULL;
  744. HRESULT hr = GetSettingsPage(pIJob, NULL, TRUE, &hpage);
  745. if (SUCCEEDED(hr))
  746. {
  747. psh.phpage[psh.nPages++] = hpage;
  748. }
  749. return hr;
  750. }
  751. HRESULT
  752. AddSettingsPage(
  753. LPFNADDPROPSHEETPAGE lpfnAddPage,
  754. LPARAM cookie,
  755. ITask * pIJob)
  756. {
  757. HPROPSHEETPAGE hpage = NULL;
  758. HRESULT hr = GetSettingsPage(pIJob, NULL, TRUE, &hpage);
  759. CHECK_HRESULT(hr);
  760. if (SUCCEEDED(hr))
  761. {
  762. if (!lpfnAddPage(hpage, cookie))
  763. {
  764. DestroyPropertySheetPage(hpage);
  765. hr = E_FAIL;
  766. CHECK_HRESULT(hr);
  767. }
  768. }
  769. return hr;
  770. }