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.

656 lines
16 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 1996.
  5. //
  6. // File: advanced.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 3/13/1996 RaviR Created
  15. // 11/16/00 Dgrube Remove Win4Assert(m_pjt->MinutesInterval >= 0);
  16. // Win4Assert(m_pjt->MinutesDuration >= 0); Since they are
  17. // DWORD this is always true and is causing compiler erros
  18. //
  19. //____________________________________________________________________________
  20. #include "..\pch\headers.hxx"
  21. #pragma hdrstop
  22. #include "..\folderui\dbg.h"
  23. #include "..\folderui\macros.h"
  24. #include "..\inc\resource.h"
  25. #include "..\inc\dll.hxx"
  26. #include "dlg.hxx"
  27. #include "rc.h"
  28. #include <mstask.h>
  29. #include "uiutil.hxx"
  30. #include "strings.hxx"
  31. #include "timeutil.hxx"
  32. #include "helpids.h"
  33. //
  34. // (Control id, help id) list for context sensitivity help.
  35. //
  36. ULONG s_aAdvancedDlgHelpIds[] =
  37. {
  38. dlg_advanced, Hdlg_advanced,
  39. lbl_start_date, Hlbl_start_date,
  40. dp_start_date, Hdp_start_date,
  41. chk_repeat_task, Hchk_repeat_task,
  42. txt_repeat_task, Htxt_repeat_task,
  43. spin_repeat_task, Hspin_repeat_task,
  44. cbx_time_unit, Hcbx_time_unit,
  45. dp_end_date, Hdp_end_date,
  46. chk_terminate_at_end, Hchk_terminate_at_end,
  47. rb_end_time, Hrb_end_time,
  48. rb_end_duration, Hrb_end_duration,
  49. dp_end_time, Hdp_end_time,
  50. txt_end_duration_hr, Htxt_end_duration_hr,
  51. spin_end_duration_hr, Hspin_end_duration_hr,
  52. txt_end_duration_min, Htxt_end_duration_min,
  53. spin_end_duration_min, Hspin_end_duration_min,
  54. grp_repeat_until, Hgrp_repeat_until,
  55. lbl_hours, Hlbl_hours,
  56. lbl_min, Hlbl_min,
  57. chk_end_date, Hchk_end_date,
  58. lbl_every, Hlbl_every,
  59. lbl_until, Hlbl_until,
  60. 0,0
  61. };
  62. extern "C" TCHAR szMstaskHelp[];
  63. //
  64. // externs
  65. //
  66. extern HINSTANCE g_hInstance;
  67. #define INDEX_MINUTES 0
  68. #define INDEX_HOURS 1
  69. const size_t c_MinsPerDay = (60 * 24);
  70. class CAdvScheduleDlg : public CDlg
  71. {
  72. public:
  73. CAdvScheduleDlg(PTASK_TRIGGER pjt) : m_pjt(pjt), CDlg() {}
  74. virtual ~CAdvScheduleDlg() {}
  75. protected:
  76. virtual INT_PTR RealDlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
  77. private:
  78. LRESULT _OnInitDialog(LPARAM lParam);
  79. LRESULT _OnCommand(int id, HWND hwndCtl, UINT codeNotify);
  80. BOOL _OnOK(void);
  81. void _EnableRepeatCtrls(BOOL fEnable);
  82. LRESULT _OnSetIniChange(WPARAM wParam, LPARAM lParam);
  83. LRESULT _OnHelp(HANDLE hRequesting, UINT uiHelpCommand);
  84. void _ErrorDialog(int idsErr, LONG error = 0, UINT idsHelpHint = 0)
  85. { SchedUIErrorDialog(Hwnd(), idsErr, error, idsHelpHint); }
  86. PTASK_TRIGGER m_pjt;
  87. //
  88. // Time format string for use with Date picker control
  89. //
  90. TCHAR m_tszTimeFormat[MAX_DP_TIME_FORMAT];
  91. };
  92. INT_PTR
  93. AdvancedDialog(
  94. HWND hParent,
  95. PTASK_TRIGGER pjt)
  96. {
  97. CAdvScheduleDlg * pAdvScheduleDlg = new CAdvScheduleDlg(pjt);
  98. if (pAdvScheduleDlg != NULL)
  99. {
  100. return pAdvScheduleDlg->DoModal(dlg_advanced, hParent);
  101. }
  102. return FALSE;
  103. }
  104. INT_PTR
  105. CAdvScheduleDlg::RealDlgProc(
  106. UINT uMsg,
  107. WPARAM wParam,
  108. LPARAM lParam)
  109. {
  110. switch (uMsg)
  111. {
  112. case WM_INITDIALOG:
  113. return _OnInitDialog(lParam);
  114. case WM_COMMAND:
  115. return(_OnCommand(GET_WM_COMMAND_ID(wParam, lParam),
  116. GET_WM_COMMAND_HWND(wParam, lParam),
  117. GET_WM_COMMAND_CMD(wParam, lParam)));
  118. case WM_DESTROY:
  119. SetWindowLongPtr(Hwnd(), DWLP_USER, 0L);
  120. delete this;
  121. break;
  122. case WM_SETTINGCHANGE: // WM_WININICHANGE
  123. _OnSetIniChange(wParam, lParam);
  124. break;
  125. case WM_HELP:
  126. return _OnHelp(((LPHELPINFO) lParam)->hItemHandle, HELP_WM_HELP);
  127. case WM_CONTEXTMENU:
  128. return _OnHelp((HANDLE) wParam, HELP_CONTEXTMENU);
  129. default:
  130. return FALSE;
  131. }
  132. return TRUE;
  133. }
  134. LRESULT
  135. CAdvScheduleDlg::_OnSetIniChange(
  136. WPARAM wParam,
  137. LPARAM lParam)
  138. {
  139. TRACE(CAdvScheduleDlg, _OnSetIniChange);
  140. DateTime_SetFormat(_hCtrl(dp_start_date), NULL);
  141. DateTime_SetFormat(_hCtrl(dp_end_date), NULL);
  142. UpdateTimeFormat(m_tszTimeFormat, ARRAYLEN(m_tszTimeFormat));
  143. DateTime_SetFormat(_hCtrl(dp_end_time), m_tszTimeFormat);
  144. return 0;
  145. }
  146. LRESULT
  147. CAdvScheduleDlg::_OnHelp(
  148. HANDLE hRequesting,
  149. UINT uiHelpCommand)
  150. {
  151. WinHelp((HWND) hRequesting,
  152. szMstaskHelp,
  153. uiHelpCommand,
  154. (DWORD_PTR)(LPSTR)s_aAdvancedDlgHelpIds);
  155. return TRUE;
  156. }
  157. LRESULT
  158. CAdvScheduleDlg::_OnInitDialog(
  159. LPARAM lParam)
  160. {
  161. //
  162. // Initialize time format string m_tszTimeFormat
  163. //
  164. UpdateTimeFormat(m_tszTimeFormat, ARRAYLEN(m_tszTimeFormat));
  165. //
  166. // Init the time unit combo box
  167. //
  168. HWND hCombo = GetDlgItem(Hwnd(), cbx_time_unit);
  169. TCHAR tcBuff[100];
  170. LoadString(g_hInstance, IDS_MINUTES, tcBuff, 100);
  171. ComboBox_AddString(hCombo, tcBuff);
  172. LoadString(g_hInstance, IDS_HOURS, tcBuff, 100);
  173. ComboBox_AddString(hCombo, tcBuff);
  174. //
  175. // Init all the spin controls, and the associated edit controls
  176. //
  177. Spin_SetRange(Hwnd(), spin_repeat_task, 1, 9999);
  178. Spin_SetRange(Hwnd(), spin_end_duration_hr, 0, 9999);
  179. Spin_SetRange(Hwnd(), spin_end_duration_min, 0, 59);
  180. SendDlgItemMessage(Hwnd(), txt_repeat_task, EM_LIMITTEXT, 4, 0);
  181. SendDlgItemMessage(Hwnd(), txt_end_duration_hr, EM_LIMITTEXT, 4, 0);
  182. SendDlgItemMessage(Hwnd(), txt_end_duration_min, EM_LIMITTEXT, 2, 0);
  183. //
  184. // Set the start and end dates.
  185. //
  186. SYSTEMTIME st;
  187. ZeroMemory(&st, sizeof st);
  188. st.wYear = m_pjt->wBeginYear;
  189. st.wMonth = m_pjt->wBeginMonth;
  190. st.wDay = m_pjt->wBeginDay;
  191. if (DateTime_SetSystemtime(_hCtrl(dp_start_date), GDT_VALID, &st) == FALSE)
  192. {
  193. DEBUG_OUT((DEB_USER1, "DateTime_SetSystemtime failed, err %uL.\n", GetLastError()));
  194. }
  195. if (m_pjt->rgFlags & TASK_TRIGGER_FLAG_HAS_END_DATE)
  196. {
  197. CheckDlgButton(Hwnd(), chk_end_date, BST_CHECKED);
  198. st.wYear = m_pjt->wEndYear;
  199. st.wMonth = m_pjt->wEndMonth;
  200. st.wDay = m_pjt->wEndDay;
  201. if (DateTime_SetSystemtime(_hCtrl(dp_end_date), GDT_VALID, &st)
  202. == FALSE)
  203. {
  204. DEBUG_OUT((DEB_USER1, "DateTime_SetSystemtime failed.\n"));
  205. }
  206. }
  207. else
  208. {
  209. CheckDlgButton(Hwnd(), chk_end_date, BST_UNCHECKED);
  210. DateTime_SetFormat(_hCtrl(dp_end_date), tszBlank);
  211. EnableWindow(_hCtrl(dp_end_date), FALSE);
  212. }
  213. if (m_pjt->TriggerType == TASK_TIME_TRIGGER_ONCE)
  214. {
  215. EnableWindow(_hCtrl(lbl_start_date), FALSE);
  216. EnableWindow(_hCtrl(dp_start_date), FALSE);
  217. EnableWindow(_hCtrl(chk_end_date), FALSE);
  218. EnableWindow(_hCtrl(dp_end_date), FALSE);
  219. }
  220. //
  221. // Set repetition
  222. //
  223. if (m_pjt->MinutesInterval > 0)
  224. {
  225. CheckDlgButton(Hwnd(), chk_repeat_task, BST_CHECKED);
  226. if (m_pjt->MinutesInterval % 60)
  227. {
  228. Spin_SetPos(Hwnd(), spin_repeat_task, (WORD)m_pjt->MinutesInterval);
  229. ComboBox_SetCurSel(hCombo, INDEX_MINUTES);
  230. }
  231. else
  232. {
  233. Spin_SetPos(Hwnd(), spin_repeat_task,
  234. (WORD)(m_pjt->MinutesInterval / 60));
  235. ComboBox_SetCurSel(hCombo, INDEX_HOURS);
  236. }
  237. //
  238. // Set end time / duration
  239. //
  240. CheckRadioButton(Hwnd(), rb_end_time, rb_end_duration,
  241. rb_end_duration);
  242. WORD wHours = (WORD) (m_pjt->MinutesDuration / 60);
  243. WORD wMins = (WORD) (m_pjt->MinutesDuration % 60);
  244. if (wHours > 9999)
  245. {
  246. wMins += (wHours - 9999) * 60;
  247. }
  248. Spin_SetPos(Hwnd(), spin_end_duration_hr, wHours);
  249. Spin_SetPos(Hwnd(), spin_end_duration_min, wMins);
  250. DateTime_SetFormat(_hCtrl(dp_end_time), tszBlank);
  251. EnableWindow(_hCtrl(dp_end_time), FALSE);
  252. //
  253. // Set terminate at end
  254. //
  255. if (m_pjt->rgFlags & TASK_TRIGGER_FLAG_KILL_AT_DURATION_END)
  256. {
  257. CheckDlgButton(Hwnd(), chk_terminate_at_end, BST_CHECKED);
  258. }
  259. }
  260. else
  261. {
  262. CheckDlgButton(Hwnd(), chk_repeat_task, BST_UNCHECKED);
  263. _EnableRepeatCtrls(FALSE);
  264. }
  265. return TRUE;
  266. }
  267. void
  268. CAdvScheduleDlg::_EnableRepeatCtrls(
  269. BOOL fEnable)
  270. {
  271. int aCtrls[] =
  272. {
  273. lbl_every,
  274. txt_repeat_task,
  275. spin_repeat_task,
  276. cbx_time_unit,
  277. lbl_until,
  278. rb_end_time,
  279. rb_end_duration,
  280. txt_end_duration_hr,
  281. spin_end_duration_hr,
  282. lbl_hours,
  283. txt_end_duration_min,
  284. spin_end_duration_min,
  285. lbl_min,
  286. chk_terminate_at_end,
  287. dp_end_time // CAUTION: last position is special, see comment below
  288. };
  289. int cCtrls;
  290. //
  291. // If we're disabling repeat controls, disable them all, i.e. set cCtrls
  292. // the number of repeat controls.
  293. //
  294. // Otherwise if we're enabling controls, set cCtrls to the number of
  295. // repeat controls less one. This will prevent the end time date-
  296. // picker control from being enabled. We need to do this because when
  297. // these controls are being enabled, the Duration radio button is
  298. // always checked, therefore the end time date picker should always
  299. // remain disabled.
  300. //
  301. if (fEnable == FALSE)
  302. {
  303. cCtrls = ARRAYLEN(aCtrls);
  304. DateTime_SetFormat(_hCtrl(dp_end_time), tszBlank);
  305. SetDlgItemText(Hwnd(), txt_repeat_task, TEXT(""));
  306. SetDlgItemText(Hwnd(), txt_end_duration_hr, TEXT(""));
  307. SetDlgItemText(Hwnd(), txt_end_duration_min, TEXT(""));
  308. SetDlgItemText(Hwnd(), cbx_time_unit, TEXT(""));
  309. }
  310. else
  311. {
  312. cCtrls = ARRAYLEN(aCtrls) - 1;
  313. Spin_SetPos(Hwnd(), spin_repeat_task, 10);
  314. ComboBox_SetCurSel(_hCtrl(cbx_time_unit), INDEX_MINUTES);
  315. CheckRadioButton(Hwnd(), rb_end_time, rb_end_duration,
  316. rb_end_duration);
  317. Spin_SetPos(Hwnd(), spin_end_duration_hr, 1);
  318. Spin_SetPos(Hwnd(), spin_end_duration_min, 0);
  319. }
  320. for (int i=0; i < cCtrls; i++)
  321. {
  322. EnableWindow(_hCtrl(aCtrls[i]), fEnable);
  323. }
  324. }
  325. LRESULT
  326. CAdvScheduleDlg::_OnCommand(
  327. int id,
  328. HWND hwndCtl,
  329. UINT codeNotify)
  330. {
  331. SYSTEMTIME st;
  332. GetSystemTime(&st);
  333. switch (id)
  334. {
  335. case chk_end_date:
  336. if (IsDlgButtonChecked(Hwnd(), chk_end_date) == BST_CHECKED)
  337. {
  338. FILETIME ftNow, ftStart;
  339. SYSTEMTIME stStart, stEnd;
  340. CopyMemory(&stEnd, &st, sizeof(SYSTEMTIME));
  341. if (DateTime_GetSystemtime(_hCtrl(dp_start_date), &stStart) == GDT_VALID)
  342. {
  343. // compare start time to current date, set End == max of the two
  344. SystemTimeToFileTime(&stStart, &ftStart);
  345. SystemTimeToFileTime(&st, &ftNow);
  346. if (CompareFileTime(&ftStart, &ftNow) <= 0)
  347. {
  348. FileTimeToSystemTime(&ftNow, &stEnd);
  349. }
  350. else
  351. {
  352. FileTimeToSystemTime(&ftStart, &stEnd);
  353. }
  354. }
  355. DateTime_SetSystemtime(_hCtrl(dp_end_date), GDT_VALID, &stEnd);
  356. DateTime_SetFormat(_hCtrl(dp_end_date), tszEmpty);
  357. EnableWindow(_hCtrl(dp_end_date), TRUE);
  358. }
  359. else
  360. {
  361. DateTime_SetFormat(_hCtrl(dp_end_date), tszBlank);
  362. EnableWindow(_hCtrl(dp_end_date), FALSE);
  363. }
  364. break;
  365. case chk_repeat_task:
  366. if (IsDlgButtonChecked(Hwnd(), chk_repeat_task) == BST_CHECKED)
  367. {
  368. _EnableRepeatCtrls(TRUE);
  369. }
  370. else
  371. {
  372. _EnableRepeatCtrls(FALSE);
  373. }
  374. break;
  375. case rb_end_time:
  376. //if (IsDlgButtonChecked(Hwnd(), rb_end_time) == BST_CHECKED)
  377. {
  378. EnableWindow(_hCtrl(dp_end_time), TRUE);
  379. DateTime_SetFormat(_hCtrl(dp_end_time), m_tszTimeFormat);
  380. Spin_Disable(Hwnd(), spin_end_duration_hr);
  381. Spin_Disable(Hwnd(), spin_end_duration_min);
  382. }
  383. break;
  384. case rb_end_duration:
  385. //if (IsDlgButtonChecked(Hwnd(), rb_end_duration) == BST_CHECKED)
  386. {
  387. Spin_Enable(Hwnd(), spin_end_duration_hr, 1);
  388. Spin_Enable(Hwnd(), spin_end_duration_min, 0);
  389. DateTime_SetFormat(_hCtrl(dp_end_time), tszBlank);
  390. EnableWindow(_hCtrl(dp_end_time), FALSE);
  391. }
  392. break;
  393. case IDOK:
  394. if (_OnOK() == TRUE)
  395. {
  396. EndDialog(Hwnd(), TRUE);
  397. }
  398. break;
  399. case IDCANCEL:
  400. EndDialog(Hwnd(), FALSE);
  401. break;
  402. default:
  403. return FALSE;
  404. }
  405. return TRUE;
  406. }
  407. BOOL
  408. CAdvScheduleDlg::_OnOK(void)
  409. {
  410. WORD wTemp = 0;
  411. SYSTEMTIME stStart, stEnd;
  412. if (DateTime_GetSystemtime(_hCtrl(dp_start_date), &stStart) == GDT_VALID)
  413. {
  414. m_pjt->wBeginYear = stStart.wYear;
  415. m_pjt->wBeginMonth = stStart.wMonth;
  416. m_pjt->wBeginDay = stStart.wDay;
  417. }
  418. else
  419. {
  420. DEBUG_OUT((DEB_USER1, "DateTime_GetSystemtime failed.\n"));
  421. }
  422. if (IsDlgButtonChecked(Hwnd(), chk_end_date) == BST_CHECKED)
  423. {
  424. if (DateTime_GetSystemtime(_hCtrl(dp_end_date), &stEnd) == GDT_VALID)
  425. {
  426. m_pjt->wEndYear = stEnd.wYear;
  427. m_pjt->wEndMonth = stEnd.wMonth;
  428. m_pjt->wEndDay = stEnd.wDay;
  429. }
  430. else
  431. {
  432. DEBUG_OUT((DEB_USER1, "DateTime_GetSystemtime failed.\n"));
  433. }
  434. m_pjt->rgFlags |= TASK_TRIGGER_FLAG_HAS_END_DATE;
  435. //
  436. // Ensure end date is after start date
  437. //
  438. stStart.wDayOfWeek = 0;
  439. stEnd.wDayOfWeek = 0;
  440. if (CompareSystemDate(stStart, stEnd) > 0)
  441. {
  442. _ErrorDialog(IERR_ENDDATE_LT_STARTDATE);
  443. return FALSE;
  444. }
  445. }
  446. else
  447. {
  448. m_pjt->rgFlags &= ~TASK_TRIGGER_FLAG_HAS_END_DATE;
  449. }
  450. if (IsDlgButtonChecked(Hwnd(), chk_repeat_task) == BST_CHECKED)
  451. {
  452. //
  453. // Determine MinutesInterval
  454. //
  455. m_pjt->MinutesInterval = Spin_GetPos(Hwnd(), spin_repeat_task);
  456. switch (ComboBox_GetCurSel(_hCtrl(cbx_time_unit)))
  457. {
  458. case INDEX_MINUTES:
  459. break;
  460. case INDEX_HOURS:
  461. m_pjt->MinutesInterval *= 60;
  462. break;
  463. }
  464. //
  465. // Determine MinutesDuration
  466. //
  467. if (IsDlgButtonChecked(Hwnd(), rb_end_time) == BST_CHECKED)
  468. {
  469. SYSTEMTIME stEndTime;
  470. if (DateTime_GetSystemtime(_hCtrl(dp_end_time), &stEndTime)
  471. == GDT_VALID)
  472. {
  473. DWORD dwMin = 0;
  474. DWORD dwStartMin = m_pjt->wStartHour * 60 + m_pjt->wStartMinute;
  475. DWORD dwEndMin = stEndTime.wHour * 60 + stEndTime.wMinute;
  476. if (dwEndMin > dwStartMin)
  477. {
  478. dwMin = dwEndMin - dwStartMin;
  479. }
  480. else
  481. {
  482. dwMin = c_MinsPerDay - (dwStartMin - dwEndMin);
  483. }
  484. m_pjt->MinutesDuration = dwMin;
  485. }
  486. else
  487. {
  488. DEBUG_OUT((DEB_USER1, "DateTime_GetSystemtime failed.\n"));
  489. }
  490. }
  491. else
  492. {
  493. ULONG ulDuration = Spin_GetPos(Hwnd(), spin_end_duration_min);
  494. if (HIWORD(ulDuration))
  495. {
  496. ulDuration = 59;
  497. }
  498. m_pjt->MinutesDuration = ulDuration + 60 *
  499. Spin_GetPos(Hwnd(), spin_end_duration_hr);
  500. }
  501. if (m_pjt->MinutesDuration <= m_pjt->MinutesInterval)
  502. {
  503. _ErrorDialog(IERR_DURATION_LT_INTERVAL);
  504. return FALSE;
  505. }
  506. if (IsDlgButtonChecked(Hwnd(), chk_terminate_at_end) == BST_CHECKED)
  507. {
  508. m_pjt->rgFlags |= TASK_TRIGGER_FLAG_KILL_AT_DURATION_END;
  509. }
  510. else
  511. {
  512. m_pjt->rgFlags &= ~TASK_TRIGGER_FLAG_KILL_AT_DURATION_END;
  513. }
  514. }
  515. else
  516. {
  517. m_pjt->MinutesInterval = 0;
  518. m_pjt->MinutesDuration = 0;
  519. m_pjt->rgFlags &= ~TASK_TRIGGER_FLAG_KILL_AT_DURATION_END;
  520. }
  521. return TRUE;
  522. }