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.

813 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. /////////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Microsoft Windows
  5. // Copyright (C) Microsoft Corporation, 1998-2001
  6. //
  7. // File: SchedDlg.cpp
  8. //
  9. // Contents: Implementation of CConnectionScheduleDlg
  10. //
  11. //----------------------------------------------------------------------------
  12. #include "stdafx.h"
  13. #include "SchedDlg.h"
  14. #include "log_gmt.h"
  15. #include "loghrapi.h"
  16. #ifdef _DEBUG
  17. //#define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. //
  22. // The schedule block has been redefined to have 1 byte for every hour.
  23. // CODEWORK These should be defined in SCHEDULE.H. JonN 2/9/98
  24. //
  25. #define INTERVAL_MASK 0x0F
  26. #define RESERVED 0xF0
  27. #define FIRST_15_MINUTES 0x01
  28. #define SECOND_15_MINUTES 0x02
  29. #define THIRD_15_MINUTES 0x04
  30. #define FOURTH_15_MINUTES 0x08
  31. const int NONE_PER_HOUR = 0;
  32. const int ONE_PER_HOUR = 33;
  33. const int TWO_PER_HOUR = 67;
  34. const int FOUR_PER_HOUR = 100;
  35. /////////////////////////////////////////////////////////////////////
  36. // ConnectionScheduleDialog ()
  37. //
  38. // Invoke a dialog to set/modify a schedule, for example
  39. // -- the logon hours for a particular user
  40. // -- the schedule for a connection
  41. //
  42. // RETURNS
  43. // Return S_OK if the user clicked on the OK button.
  44. // Return S_FALSE if the user clicked on the Cancel button.
  45. // Return E_OUTOFMEMORY if there is not enough memory.
  46. /// Return E_UNEXPECTED if an expected error occured (eg: bad parameter)
  47. //
  48. // INTERFACE NOTES
  49. // Each bit in the array represents one hour. As a result, the
  50. // expected length of the array should be (24 / 8) * 7 = 21 bytes.
  51. // For convenience, the first day of the week is Sunday and
  52. // the last day is Saturday.
  53. // Consequently, the first bit of the array represents the schedule
  54. // for Sunday during period 12 AM to 1 AM.
  55. // - If *pprgbData is NULL, then the routine will allocate
  56. // an array of 21 bytes using LocalAlloc (). The caller
  57. // is responsible of releasing the memory using LocalFree ().
  58. // - If *pprgbData is not NULL, the routine re-use the array as its
  59. // output parameter.
  60. //
  61. // HISTORY
  62. // 17-Jul-97 t-danm Creation.
  63. // 16-Sep-97 jonn Changed to UiScheduleDialog
  64. //
  65. HRESULT
  66. ConnectionScheduleDialog (
  67. HWND hwndParent, // IN: Parent's window handle
  68. BYTE ** pprgbData, // INOUT: Pointer to pointer to array of 21 bytes (one bit per hour)
  69. LPCTSTR pszTitle) // IN: Dialog title
  70. {
  71. return ConnectionScheduleDialogEx (hwndParent, pprgbData, pszTitle, 0);
  72. }
  73. HRESULT
  74. ConnectionScheduleDialogEx (
  75. HWND hwndParent, // IN: Parent's window handle
  76. BYTE ** pprgbData, // INOUT: Pointer to pointer to array of 21 bytes (one bit per hour)
  77. LPCTSTR pszTitle, // IN: Dialog title
  78. DWORD dwFlags)
  79. {
  80. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  81. ASSERT (::IsWindow (hwndParent));
  82. ASSERT (pprgbData);
  83. ASSERT (pszTitle);
  84. ENDORSE (NULL == *pprgbData); // TRUE => Use default logon hours (7x24)
  85. if (*pprgbData == NULL)
  86. {
  87. BYTE * pargbData; // Pointer to allocated array of bytes
  88. pargbData = (BYTE *)LocalAlloc (0, 7*24); // Allocate 168 bytes
  89. if ( !pargbData )
  90. return E_OUTOFMEMORY;
  91. // Set the logon hours to be valid 24 hours a day and 7 days a week.
  92. memset (OUT pargbData, -1, 7*24);
  93. *pprgbData = pargbData;
  94. }
  95. // If hwndParent passed in, create a CWnd to pass as the parent window
  96. CWnd* pWnd = 0;
  97. if ( ::IsWindow (hwndParent) )
  98. {
  99. pWnd = new CWnd;
  100. if ( pWnd )
  101. {
  102. pWnd->Attach (hwndParent);
  103. }
  104. else
  105. return E_OUTOFMEMORY;
  106. }
  107. HRESULT hr = S_OK;
  108. CConnectionScheduleDlg dlg (pWnd);
  109. dlg.SetTitle (pszTitle);
  110. dlg.SetConnectionByteArray (INOUT *pprgbData);
  111. dlg.SetFlags (dwFlags);
  112. if (IDOK != dlg.DoModal ())
  113. hr = S_FALSE;
  114. // Delete CWnd
  115. if ( pWnd )
  116. {
  117. pWnd->Detach ();
  118. delete pWnd;
  119. }
  120. return hr;
  121. } // ConnectionScheduleDialog ()
  122. HRESULT
  123. ReplicationScheduleDialog (
  124. HWND hwndParent, // IN: Parent's window handle
  125. BYTE ** pprgbData, // INOUT: Pointer to pointer to array of 21 bytes (one bit per hour)
  126. LPCTSTR pszTitle) // IN: Dialog title
  127. {
  128. return ReplicationScheduleDialogEx (hwndParent, pprgbData, pszTitle, 0);
  129. } // ReplicationScheduleDialog ()
  130. HRESULT ReplicationScheduleDialogEx (
  131. HWND hwndParent, // parent window
  132. BYTE ** pprgbData, // pointer to pointer to array of 84 bytes
  133. LPCTSTR pszTitle, // dialog title
  134. DWORD dwFlags) // option flags
  135. {
  136. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  137. ASSERT (::IsWindow (hwndParent));
  138. ASSERT (pprgbData);
  139. ASSERT (pszTitle);
  140. ENDORSE (NULL == *pprgbData); // TRUE => Use default logon hours (7x24)
  141. if (*pprgbData == NULL)
  142. {
  143. BYTE * pargbData; // Pointer to allocated array of bytes
  144. pargbData = (BYTE *)LocalAlloc (0, 7*24); // Allocate 168 bytes
  145. if ( !pargbData )
  146. return E_OUTOFMEMORY;
  147. // Set the logon hours to be valid 24 hours a day and 7 days a week.
  148. memset (OUT pargbData, -1, 7*24);
  149. *pprgbData = pargbData;
  150. }
  151. // If hwndParent passed in, create a CWnd to pass as the parent window
  152. CWnd* pWnd = 0;
  153. if ( ::IsWindow (hwndParent) )
  154. {
  155. pWnd = new CWnd;
  156. if ( pWnd )
  157. {
  158. pWnd->Attach (hwndParent);
  159. }
  160. else
  161. return E_OUTOFMEMORY;
  162. }
  163. HRESULT hr = S_OK;
  164. CReplicationScheduleDlg dlg (pWnd);
  165. dlg.SetTitle (pszTitle);
  166. dlg.SetConnectionByteArray (INOUT *pprgbData);
  167. dlg.SetFlags (dwFlags);
  168. if (IDOK != dlg.DoModal ())
  169. hr = S_FALSE;
  170. // Delete CWnd
  171. if ( pWnd )
  172. {
  173. pWnd->Detach ();
  174. delete pWnd;
  175. }
  176. return hr;
  177. } // ReplicationScheduleDialogEx
  178. /////////////////////////////////////////////////////////////////////////////
  179. // CConnectionScheduleDlg dialog
  180. CConnectionScheduleDlg::CConnectionScheduleDlg(CWnd* pParent)
  181. : CScheduleBaseDlg(CConnectionScheduleDlg::IDD, true, pParent),
  182. m_prgbData168 (0)
  183. {
  184. EnableAutomation();
  185. //{{AFX_DATA_INIT(CConnectionScheduleDlg)
  186. // NOTE: the ClassWizard will add member initialization here
  187. //}}AFX_DATA_INIT
  188. }
  189. void CConnectionScheduleDlg::OnFinalRelease()
  190. {
  191. // When the last reference for an automation object is released
  192. // OnFinalRelease is called. The base class will automatically
  193. // deletes the object. Add additional cleanup required for your
  194. // object before calling the base class.
  195. CScheduleBaseDlg::OnFinalRelease();
  196. }
  197. void CConnectionScheduleDlg::DoDataExchange(CDataExchange* pDX)
  198. {
  199. CScheduleBaseDlg::DoDataExchange(pDX);
  200. //{{AFX_DATA_MAP(CConnectionScheduleDlg)
  201. DDX_Control(pDX, IDC_RADIO_NONE, m_buttonNone);
  202. DDX_Control(pDX, IDC_RADIO_ONE, m_buttonOne);
  203. DDX_Control(pDX, IDC_RADIO_TWO, m_buttonTwo);
  204. DDX_Control(pDX, IDC_RADIO_FOUR, m_buttonFour);
  205. //}}AFX_DATA_MAP
  206. }
  207. BEGIN_MESSAGE_MAP(CConnectionScheduleDlg, CScheduleBaseDlg)
  208. //{{AFX_MSG_MAP(CConnectionScheduleDlg)
  209. ON_BN_CLICKED(IDC_RADIO_FOUR, OnRadioFour)
  210. ON_BN_CLICKED(IDC_RADIO_NONE, OnRadioNone)
  211. ON_BN_CLICKED(IDC_RADIO_ONE, OnRadioOne)
  212. ON_BN_CLICKED(IDC_RADIO_TWO, OnRadioTwo)
  213. //}}AFX_MSG_MAP
  214. END_MESSAGE_MAP()
  215. BEGIN_DISPATCH_MAP(CConnectionScheduleDlg, CScheduleBaseDlg)
  216. //{{AFX_DISPATCH_MAP(CConnectionScheduleDlg)
  217. // NOTE - the ClassWizard will add and remove mapping macros here.
  218. //}}AFX_DISPATCH_MAP
  219. END_DISPATCH_MAP()
  220. // Note: we add support for IID_IDSScheduleDlg to support typesafe binding
  221. // from VBA. This IID must match the GUID that is attached to the
  222. // dispinterface in the .ODL file.
  223. // {701CFB36-AEF8-11D1-9864-00C04FB94F17}
  224. static const IID IID_IDSScheduleDlg =
  225. { 0x701cfb36, 0xaef8, 0x11d1, { 0x98, 0x64, 0x0, 0xc0, 0x4f, 0xb9, 0x4f, 0x17 } };
  226. BEGIN_INTERFACE_MAP(CConnectionScheduleDlg, CScheduleBaseDlg)
  227. INTERFACE_PART(CConnectionScheduleDlg, IID_IDSScheduleDlg, Dispatch)
  228. END_INTERFACE_MAP()
  229. /////////////////////////////////////////////////////////////////////////////
  230. // CConnectionScheduleDlg message handlers
  231. BOOL CConnectionScheduleDlg::OnInitDialog()
  232. {
  233. CScheduleBaseDlg::OnInitDialog();
  234. // Set up the "none" legend
  235. m_legendNone.Init (this, IDC_STATIC_LEGEND_NONE, &m_schedulematrix, NONE_PER_HOUR);
  236. // Set up the "one" legend
  237. m_legendOne.Init (this, IDC_STATIC_LEGEND_ONE, &m_schedulematrix, ONE_PER_HOUR);
  238. // Set up the "two" legend
  239. m_legendTwo.Init (this, IDC_STATIC_LEGEND_TWO, &m_schedulematrix, TWO_PER_HOUR);
  240. // Set up the "four" legend
  241. m_legendFour.Init (this, IDC_STATIC_LEGEND_FOUR, &m_schedulematrix, FOUR_PER_HOUR);
  242. if ( GetFlags () & SCHED_FLAG_READ_ONLY )
  243. {
  244. // Disable the grid settings buttons
  245. m_buttonNone.EnableWindow (FALSE);
  246. m_buttonOne.EnableWindow (FALSE);
  247. m_buttonTwo.EnableWindow (FALSE);
  248. m_buttonFour.EnableWindow (FALSE);
  249. }
  250. return TRUE; // return TRUE unless you set the focus to a control
  251. // EXCEPTION: OCX Property Pages should return FALSE
  252. }
  253. void CConnectionScheduleDlg::OnOK()
  254. {
  255. if ( m_prgbData168 )
  256. {
  257. GetByteArray (OUT m_prgbData168);
  258. // Convert back the hours to GMT time.
  259. ConvertConnectionHoursToGMT (INOUT m_prgbData168, m_bAddDaylightBias);
  260. }
  261. CScheduleBaseDlg::OnOK();
  262. }
  263. void CConnectionScheduleDlg::UpdateButtons ()
  264. {
  265. UINT nHour = 0;
  266. UINT nDay = 0;
  267. UINT nNumHours = 0;
  268. UINT nNumDays = 0;
  269. m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
  270. // Assume in each case that all selected squares are all set one way until
  271. // proven otherwise. These are 'int' so that I can add them up afterwards
  272. // to assure that only one of the buttons will be checked.
  273. int fNoneAllSet = 1;
  274. int fOneAllSet = 1;
  275. int fTwoAllSet = 1;
  276. int fFourAllSet = 1;
  277. if (nNumHours > 0)
  278. {
  279. for (UINT iDayOfWeek = nDay; iDayOfWeek < nDay+nNumDays; iDayOfWeek++)
  280. {
  281. for (UINT iHour = nHour; iHour < nHour+nNumHours; iHour++)
  282. {
  283. switch (m_schedulematrix.GetPercentage (iHour, iDayOfWeek))
  284. {
  285. case NONE_PER_HOUR:
  286. fOneAllSet = 0;
  287. fTwoAllSet = 0;
  288. fFourAllSet = 0;
  289. break;
  290. case ONE_PER_HOUR:
  291. fNoneAllSet = 0;
  292. fTwoAllSet = 0;
  293. fFourAllSet = 0;
  294. break;
  295. case TWO_PER_HOUR:
  296. fNoneAllSet = 0;
  297. fOneAllSet = 0;
  298. fFourAllSet = 0;
  299. break;
  300. case FOUR_PER_HOUR:
  301. fNoneAllSet = 0;
  302. fOneAllSet = 0;
  303. fTwoAllSet = 0;
  304. break;
  305. default:
  306. ASSERT (0);
  307. break;
  308. }
  309. } // for
  310. } // for
  311. }
  312. else
  313. {
  314. fNoneAllSet = 0;
  315. fOneAllSet = 0;
  316. fTwoAllSet = 0;
  317. fFourAllSet = 0;
  318. }
  319. // Ensure that at most, only one of these is 'true'
  320. ASSERT ((fNoneAllSet + fOneAllSet + fTwoAllSet + fFourAllSet <= 1));
  321. m_buttonNone.SetCheck (fNoneAllSet);
  322. m_buttonOne.SetCheck (fOneAllSet);
  323. m_buttonTwo.SetCheck (fTwoAllSet);
  324. m_buttonFour.SetCheck (fFourAllSet);
  325. }
  326. void CConnectionScheduleDlg::OnRadioFour()
  327. {
  328. UINT nHour = 0;
  329. UINT nDay = 0;
  330. UINT nNumHours = 0;
  331. UINT nNumDays = 0;
  332. m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
  333. if (nNumHours <= 0)
  334. return; // Nothing selected
  335. m_schedulematrix.SetPercentage (FOUR_PER_HOUR, nHour, nDay, nNumHours, nNumDays);
  336. UpdateButtons ();
  337. }
  338. void CConnectionScheduleDlg::OnRadioNone()
  339. {
  340. UINT nHour = 0;
  341. UINT nDay = 0;
  342. UINT nNumHours = 0;
  343. UINT nNumDays = 0;
  344. m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
  345. if (nNumHours <= 0)
  346. return; // Nothing selected
  347. m_schedulematrix.SetPercentage (NONE_PER_HOUR, nHour, nDay, nNumHours, nNumDays);
  348. UpdateButtons ();
  349. }
  350. void CConnectionScheduleDlg::OnRadioOne()
  351. {
  352. UINT nHour = 0;
  353. UINT nDay = 0;
  354. UINT nNumHours = 0;
  355. UINT nNumDays = 0;
  356. m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
  357. if (nNumHours <= 0)
  358. return; // Nothing selected
  359. m_schedulematrix.SetPercentage (ONE_PER_HOUR, nHour, nDay, nNumHours, nNumDays);
  360. UpdateButtons ();
  361. }
  362. void CConnectionScheduleDlg::OnRadioTwo()
  363. {
  364. UINT nHour = 0;
  365. UINT nDay = 0;
  366. UINT nNumHours = 0;
  367. UINT nNumDays = 0;
  368. m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
  369. if (nNumHours <= 0)
  370. return; // Nothing selected
  371. m_schedulematrix.SetPercentage (TWO_PER_HOUR, nHour, nDay, nNumHours, nNumDays);
  372. UpdateButtons ();
  373. }
  374. void CConnectionScheduleDlg::InitMatrix()
  375. {
  376. if ( m_prgbData168 )
  377. {
  378. BYTE rgData[SCHEDULE_DATA_ENTRIES]; // Array of logonhours bits
  379. // Make a copy of the connection hours (in case the user click on cancel button)
  380. memcpy (OUT rgData, IN m_prgbData168, sizeof (rgData));
  381. // Convert the hours from GMT to local hours.
  382. ConvertConnectionHoursFromGMT (INOUT rgData, m_bAddDaylightBias);
  383. // Initialize the matrix
  384. InitMatrix2 (IN rgData);
  385. }
  386. }
  387. void CConnectionScheduleDlg::SetConnectionByteArray(INOUT BYTE rgbData [SCHEDULE_DATA_ENTRIES])
  388. {
  389. ASSERT (rgbData);
  390. m_prgbData168 = rgbData;
  391. }
  392. // This table represent the numbers of bits set in the lower nibble of the BYTE.
  393. // 0 bits -> 0
  394. // 1 bit -> 25
  395. // 2 or 3 bits -> 50
  396. // 4 bits -> 100
  397. static BYTE setConversionTable[16] =
  398. {NONE_PER_HOUR, // 0000
  399. ONE_PER_HOUR, // 0001
  400. ONE_PER_HOUR, // 0010
  401. TWO_PER_HOUR, // 0011
  402. ONE_PER_HOUR, // 0100
  403. TWO_PER_HOUR, // 0101
  404. TWO_PER_HOUR, // 0110
  405. TWO_PER_HOUR, // 0111
  406. ONE_PER_HOUR, // 1000
  407. TWO_PER_HOUR, // 1001
  408. TWO_PER_HOUR, // 1010
  409. TWO_PER_HOUR, // 1011
  410. TWO_PER_HOUR, // 1100
  411. TWO_PER_HOUR, // 1101
  412. TWO_PER_HOUR, // 1110
  413. FOUR_PER_HOUR}; // 1111
  414. UINT CConnectionScheduleDlg::GetPercentageToSet(const BYTE bData)
  415. {
  416. ASSERT ((bData & 0x0F) < 16);
  417. return setConversionTable[bData & 0x0F];
  418. }
  419. BYTE CConnectionScheduleDlg::GetMatrixPercentage(UINT nHour, UINT nDay)
  420. {
  421. BYTE byResult = 0;
  422. switch (m_schedulematrix.GetPercentage (nHour, nDay))
  423. {
  424. case NONE_PER_HOUR:
  425. // value remains 0n
  426. break;
  427. case ONE_PER_HOUR:
  428. byResult = FIRST_15_MINUTES;
  429. break;
  430. case TWO_PER_HOUR:
  431. byResult = FIRST_15_MINUTES | THIRD_15_MINUTES;
  432. break;
  433. case FOUR_PER_HOUR:
  434. byResult = FIRST_15_MINUTES | SECOND_15_MINUTES | THIRD_15_MINUTES | FOURTH_15_MINUTES;
  435. break;
  436. default:
  437. ASSERT (0);
  438. break;
  439. }
  440. return byResult;
  441. }
  442. UINT CConnectionScheduleDlg::GetExpectedArrayLength()
  443. {
  444. return SCHEDULE_DATA_ENTRIES;
  445. }
  446. // Called when WM_TIMECHANGE is received
  447. void CConnectionScheduleDlg::TimeChange()
  448. {
  449. m_buttonNone.EnableWindow (FALSE);
  450. m_buttonOne.EnableWindow (FALSE);
  451. m_buttonTwo.EnableWindow (FALSE);
  452. m_buttonFour.EnableWindow (FALSE);
  453. }
  454. /////////////////////////////////////////////////////////////////////////////
  455. // CReplicationScheduleDlg dialog
  456. CReplicationScheduleDlg::CReplicationScheduleDlg(CWnd* pParent)
  457. : CScheduleBaseDlg(CReplicationScheduleDlg::IDD, true, pParent),
  458. m_prgbData168 (0)
  459. {
  460. EnableAutomation();
  461. //{{AFX_DATA_INIT(CReplicationScheduleDlg)
  462. // NOTE: the ClassWizard will add member initialization here
  463. //}}AFX_DATA_INIT
  464. }
  465. void CReplicationScheduleDlg::OnFinalRelease()
  466. {
  467. // When the last reference for an automation object is released
  468. // OnFinalRelease is called. The base class will automatically
  469. // deletes the object. Add additional cleanup required for your
  470. // object before calling the base class.
  471. CScheduleBaseDlg::OnFinalRelease();
  472. }
  473. void CReplicationScheduleDlg::DoDataExchange(CDataExchange* pDX)
  474. {
  475. CScheduleBaseDlg::DoDataExchange(pDX);
  476. //{{AFX_DATA_MAP(CReplicationScheduleDlg)
  477. DDX_Control(pDX, IDC_RADIO_NONE, m_buttonNone);
  478. DDX_Control(pDX, IDC_RADIO_FOUR, m_buttonFour);
  479. //}}AFX_DATA_MAP
  480. }
  481. BEGIN_MESSAGE_MAP(CReplicationScheduleDlg, CScheduleBaseDlg)
  482. //{{AFX_MSG_MAP(CReplicationScheduleDlg)
  483. ON_BN_CLICKED(IDC_RADIO_FOUR, OnRadioFour)
  484. ON_BN_CLICKED(IDC_RADIO_NONE, OnRadioNone)
  485. //}}AFX_MSG_MAP
  486. END_MESSAGE_MAP()
  487. BEGIN_DISPATCH_MAP(CReplicationScheduleDlg, CScheduleBaseDlg)
  488. //{{AFX_DISPATCH_MAP(CReplicationScheduleDlg)
  489. // NOTE - the ClassWizard will add and remove mapping macros here.
  490. //}}AFX_DISPATCH_MAP
  491. END_DISPATCH_MAP()
  492. // Note: we add support for IID_IDSScheduleDlg to support typesafe binding
  493. // from VBA. This IID must match the GUID that is attached to the
  494. // dispinterface in the .ODL file.
  495. // {8DE6E2DA-7B4E-11d2-AC13-00C04F79DDCA}
  496. static const IID IID_IReplicationScheduleDlg =
  497. { 0x8de6e2da, 0x7b4e, 0x11d2, { 0xac, 0x13, 0x0, 0xc0, 0x4f, 0x79, 0xdd, 0xca } };
  498. BEGIN_INTERFACE_MAP(CReplicationScheduleDlg, CScheduleBaseDlg)
  499. INTERFACE_PART(CReplicationScheduleDlg, IID_IReplicationScheduleDlg, Dispatch)
  500. END_INTERFACE_MAP()
  501. /////////////////////////////////////////////////////////////////////////////
  502. // CReplicationScheduleDlg message handlers
  503. BOOL CReplicationScheduleDlg::OnInitDialog()
  504. {
  505. CScheduleBaseDlg::OnInitDialog();
  506. // Set up the "none" legend
  507. m_legendNone.Init (this, IDC_STATIC_LEGEND_NONE, &m_schedulematrix, NONE_PER_HOUR);
  508. // Set up the "four" legend
  509. m_legendFour.Init (this, IDC_STATIC_LEGEND_FOUR, &m_schedulematrix, FOUR_PER_HOUR);
  510. if ( GetFlags () & SCHED_FLAG_READ_ONLY )
  511. {
  512. // Disable the grid settings buttons
  513. m_buttonNone.EnableWindow (FALSE);
  514. m_buttonFour.EnableWindow (FALSE);
  515. }
  516. return TRUE; // return TRUE unless you set the focus to a control
  517. // EXCEPTION: OCX Property Pages should return FALSE
  518. }
  519. void CReplicationScheduleDlg::OnOK()
  520. {
  521. if ( m_prgbData168 )
  522. {
  523. GetByteArray (OUT m_prgbData168);
  524. // Convert back the hours to GMT time.
  525. ConvertConnectionHoursToGMT (INOUT m_prgbData168, m_bAddDaylightBias);
  526. }
  527. CScheduleBaseDlg::OnOK();
  528. }
  529. void CReplicationScheduleDlg::UpdateButtons ()
  530. {
  531. UINT nHour = 0;
  532. UINT nDay = 0;
  533. UINT nNumHours = 0;
  534. UINT nNumDays = 0;
  535. m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
  536. // Assume in each case that all selected squares are all set one way until
  537. // proven otherwise. These are 'int' so that I can add them up afterwards
  538. // to assure that only one of the buttons will be checked.
  539. int fNoneAllSet = 1;
  540. int fFourAllSet = 1;
  541. if (nNumHours > 0)
  542. {
  543. for (UINT iDayOfWeek = nDay; iDayOfWeek < nDay+nNumDays; iDayOfWeek++)
  544. {
  545. for (UINT iHour = nHour; iHour < nHour+nNumHours; iHour++)
  546. {
  547. switch (m_schedulematrix.GetPercentage (iHour, iDayOfWeek))
  548. {
  549. case NONE_PER_HOUR:
  550. fFourAllSet = 0;
  551. break;
  552. case FOUR_PER_HOUR:
  553. fNoneAllSet = 0;
  554. break;
  555. default:
  556. ASSERT (0);
  557. break;
  558. }
  559. } // for
  560. } // for
  561. }
  562. else
  563. {
  564. fNoneAllSet = 0;
  565. }
  566. ASSERT (fNoneAllSet + fFourAllSet <= 1);
  567. m_buttonNone.SetCheck (fNoneAllSet);
  568. m_buttonFour.SetCheck (fFourAllSet);
  569. }
  570. void CReplicationScheduleDlg::OnRadioFour()
  571. {
  572. UINT nHour = 0;
  573. UINT nDay = 0;
  574. UINT nNumHours = 0;
  575. UINT nNumDays = 0;
  576. m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
  577. if (nNumHours <= 0)
  578. return; // Nothing selected
  579. m_schedulematrix.SetPercentage (FOUR_PER_HOUR, nHour, nDay, nNumHours, nNumDays);
  580. UpdateButtons ();
  581. }
  582. void CReplicationScheduleDlg::OnRadioNone()
  583. {
  584. UINT nHour = 0;
  585. UINT nDay = 0;
  586. UINT nNumHours = 0;
  587. UINT nNumDays = 0;
  588. m_schedulematrix.GetSel (OUT nHour, OUT nDay, OUT nNumHours, OUT nNumDays);
  589. if (nNumHours <= 0)
  590. return; // Nothing selected
  591. m_schedulematrix.SetPercentage (NONE_PER_HOUR, nHour, nDay, nNumHours, nNumDays);
  592. UpdateButtons ();
  593. }
  594. void CReplicationScheduleDlg::InitMatrix()
  595. {
  596. if ( m_prgbData168 )
  597. {
  598. BYTE rgData[SCHEDULE_DATA_ENTRIES]; // Array of logonhours bits
  599. // Make a copy of the connection hours (in case the user click on cancel button)
  600. memcpy (OUT rgData, IN m_prgbData168, sizeof (rgData));
  601. // Convert the hours from GMT to local hours.
  602. ConvertConnectionHoursFromGMT (INOUT rgData, m_bAddDaylightBias);
  603. // Initialize the matrix
  604. InitMatrix2 (IN rgData);
  605. }
  606. }
  607. void CReplicationScheduleDlg::SetConnectionByteArray(INOUT BYTE rgbData [SCHEDULE_DATA_ENTRIES])
  608. {
  609. ASSERT (rgbData);
  610. m_prgbData168 = rgbData;
  611. }
  612. // This table represent the numbers of bits set in the lower nibble of the BYTE.
  613. // 0 bits -> 0
  614. // 1 bit -> 25
  615. // 2 or 3 bits -> 50
  616. // 4 bits -> 100
  617. static BYTE setConversionTableForReplication[16] =
  618. {NONE_PER_HOUR, // 0000
  619. FOUR_PER_HOUR, // 0001
  620. FOUR_PER_HOUR, // 0010
  621. FOUR_PER_HOUR, // 0011
  622. FOUR_PER_HOUR, // 0100
  623. FOUR_PER_HOUR, // 0101
  624. FOUR_PER_HOUR, // 0110
  625. FOUR_PER_HOUR, // 0111
  626. FOUR_PER_HOUR, // 1000
  627. FOUR_PER_HOUR, // 1001
  628. FOUR_PER_HOUR, // 1010
  629. FOUR_PER_HOUR, // 1011
  630. FOUR_PER_HOUR, // 1100
  631. FOUR_PER_HOUR, // 1101
  632. FOUR_PER_HOUR, // 1110
  633. FOUR_PER_HOUR}; // 1111
  634. UINT CReplicationScheduleDlg::GetPercentageToSet(const BYTE bData)
  635. {
  636. ASSERT ((bData & 0x0F) < 16);
  637. return setConversionTableForReplication[bData & 0x0F];
  638. }
  639. BYTE CReplicationScheduleDlg::GetMatrixPercentage(UINT nHour, UINT nDay)
  640. {
  641. BYTE byResult = 0;
  642. switch (m_schedulematrix.GetPercentage (nHour, nDay))
  643. {
  644. case NONE_PER_HOUR:
  645. // value remains 0n
  646. break;
  647. case ONE_PER_HOUR:
  648. case TWO_PER_HOUR:
  649. case FOUR_PER_HOUR:
  650. byResult = FIRST_15_MINUTES | SECOND_15_MINUTES | THIRD_15_MINUTES | FOURTH_15_MINUTES;
  651. break;
  652. default:
  653. ASSERT (0);
  654. break;
  655. }
  656. return byResult;
  657. }
  658. UINT CReplicationScheduleDlg::GetExpectedArrayLength()
  659. {
  660. return SCHEDULE_DATA_ENTRIES;
  661. }
  662. // Called when WM_TIMECHANGE is received
  663. void CReplicationScheduleDlg::TimeChange()
  664. {
  665. m_buttonNone.EnableWindow (FALSE);
  666. m_buttonFour.EnableWindow (FALSE);
  667. }
  668. /////////////////////////////////////////////////////////////////////
  669. // Converts the connection hours from local time to GMT.
  670. void
  671. ConvertConnectionHoursToGMT (INOUT BYTE rgbData[SCHEDULE_DATA_ENTRIES], IN bool bAddDaylightBias)
  672. {
  673. VERIFY ( ::NetpRotateLogonHoursBYTE (rgbData, SCHEDULE_DATA_ENTRIES, TRUE, bAddDaylightBias) );
  674. }
  675. /////////////////////////////////////////////////////////////////////
  676. // Converts the connection hours from GMT to local time.
  677. void
  678. ConvertConnectionHoursFromGMT (INOUT BYTE rgbData[SCHEDULE_DATA_ENTRIES], IN bool bAddDaylightBias)
  679. {
  680. VERIFY ( ::NetpRotateLogonHoursBYTE (rgbData, SCHEDULE_DATA_ENTRIES, FALSE, bAddDaylightBias) );
  681. }