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.

246 lines
6.2 KiB

  1. /*
  2. * Windows Calendar
  3. * Copyright (c) 1985 by Microsoft Corporation, all rights reserved.
  4. * Written by Mark L. Chamberlin, consultant to Microsoft.
  5. *
  6. */
  7. /*
  8. *****
  9. ***** calday2.c
  10. *****
  11. */
  12. #include "cal.h"
  13. /**** SetDayScrollRange */
  14. VOID APIENTRY SetDayScrollRange ()
  15. {
  16. /* Set the range so that the minimum thumb position corresponds to
  17. having the first TM of the day at the top of the window and
  18. the maximum thumb position corresponds to having the last TM
  19. of the day at the bottom of the window. We want to always be
  20. able to work from the first TM in the window, so we observe
  21. that the last TM of the day is at the bottom of the window
  22. when the last windowful (or page) of TMs is up, and this
  23. is when the (ctmDay - vcln)th TM is at the top of the window.
  24. For example, if there are 100 TMs (0 - 99), and we can display
  25. 10 TMs in the window (vcln == 10), we are maxed out when
  26. 90 through 99 are in the window.
  27. Note that calling ItmFromTm with TMNILHIGH returns the count
  28. of TMs in the day.
  29. */
  30. SetScrollRange (vhwnd2B, SB_VERT, 0, ItmFromTm (TMNILHIGH) - vcln, FALSE);
  31. }
  32. /**** AdjustDayScrollRange - adjust the scroll bar range by the specified
  33. number of TMs.
  34. */
  35. VOID APIENTRY AdjustDayScrollRange (INT ctm)
  36. {
  37. INT itmMin;
  38. INT itmMax;
  39. GetScrollRange (vhwnd2B, SB_VERT, (LPINT)&itmMin, (LPINT)&itmMax);
  40. SetScrollRange (vhwnd2B, SB_VERT, 0, itmMax + ctm, FALSE);
  41. }
  42. /**** SetDayScrollPos - position the thumb. */
  43. VOID APIENTRY SetDayScrollPos (register INT itm)
  44. {
  45. /* If called with itm == -1, position the thumb based on the TM
  46. at the top of the window.
  47. */
  48. if (itm == -1)
  49. itm = ItmFromTm (vtld [0].tm);
  50. SetScrollPos (vhwnd2B, SB_VERT, itm, TRUE);
  51. }
  52. /**** AdjustDayScrollPos - adjust the position of the thumb relative
  53. to its old position.
  54. */
  55. VOID APIENTRY AdjustDayScrollPos (INT ctm)
  56. /* Positive to increase thumb position (towards
  57. bottom of window), negative to decrease thumb
  58. (towards top of window).
  59. */
  60. {
  61. SetDayScrollPos (GetScrollPos (vhwnd2B, SB_VERT) + ctm);
  62. }
  63. /**** ItmFromTm - map a TM to an index within the range of TMs for the day.
  64. If tmToMap does not exist within the day (not a regular time and
  65. not in the tqr), we return the index of the next
  66. highest TM. Therefore, to find out how many TMs there are in
  67. the day, call ItmFromTm with tmToMap == TMNILHIGH. SetDayScrollRange
  68. depends on this.
  69. Note - tmToMap must be in the closed interval 0 through TMNILHIGH.
  70. */
  71. INT APIENTRY ItmFromTm (TM tmToMap)
  72. {
  73. INT itm;
  74. itm = -1;
  75. MapTmAndItm (&tmToMap, &itm);
  76. return (itm);
  77. }
  78. /**** TmFromItm - map TM to an index within the range of TMs for this date. */
  79. TM APIENTRY TmFromItm (INT itm)
  80. {
  81. TM tm;
  82. MapTmAndItm (&tm, &itm);
  83. return (tm);
  84. }
  85. /**** MapTmAndItm - map TM to itm and vice versa.
  86. To map a TM to an itm: *ptmMap == TM to map, *pitmMap == -1.
  87. To map an itm to a TM:: *ptmMap == don't care, *pitmMap == itm to map.
  88. */
  89. VOID APIENTRY MapTmAndItm (
  90. TM *ptmMap,
  91. INT *pitmMap)
  92. {
  93. register TM tmCur;
  94. register TM tmFromQr;
  95. TM tmMap;
  96. DR *pdr;
  97. PQR pqrCur;
  98. PQR pqrMax;
  99. INT itm;
  100. BOOL fMapTmToItm;
  101. tmMap = ((fMapTmToItm = *pitmMap) == -1) ? *ptmMap : TMNILHIGH;
  102. /* Lock the DR, and get First and Max pointers for the tqr. */
  103. pdr = PdrLockCur ();
  104. pqrMax = (PQR)((BYTE*)(pqrCur = (PQR)PbTqrFromPdr(pdr)) + pdr->cbTqr);
  105. /* Find the first QR time. */
  106. tmFromQr = TmFromQr (&pqrCur, pqrMax);
  107. /* Starting at the first possible TM of the day (0), keep going
  108. until we find a TM greater than or equal to the one we're mapping.
  109. */
  110. for (itm = (INT)(tmCur = 0); tmCur < tmMap && itm != *pitmMap; itm++)
  111. {
  112. if ((tmCur = TmNextRegular (tmCur)) >= tmFromQr)
  113. {
  114. /* The QR TM is less than or equal to the next
  115. regular TM, so use the one from the QR in order to
  116. skip over it.
  117. Note - At this point, both tmCur and tmFromQr could
  118. be TMNILHIGH (because there aren't anymore QRs
  119. and there are no more regular times. This works OK
  120. since we end up using TMNILHIGH which will terminate
  121. terminate the loop since TMNILHIGH is the highest value
  122. the caller is permitted to pass. Calling TmFromQr
  123. with pqrCur == pqrMax works OK too, so no problem there.
  124. */
  125. if ((tmFromQr = TmFromQr (&pqrCur, pqrMax)) < tmCur)
  126. tmCur = tmFromQr;
  127. }
  128. }
  129. DrUnlockCur ();
  130. /* Pass back the mapped value to the caller. */
  131. if (fMapTmToItm)
  132. *pitmMap = itm;
  133. else
  134. *ptmMap = tmCur;
  135. }
  136. /**** TmFromQr - return TM of the current QR or TMNILHIGH if there
  137. isn't one. Also update pqrCur to point past the last QR we inspect.
  138. Note - Guaranteed to do the right thing if called with
  139. pqrCur == pqrMax. In this case we return TMNILHIGH and pqrCur
  140. is unchanged.
  141. */
  142. TM APIENTRY TmFromQr (
  143. PQR *ppqrCur, /* Input - pqrCur points to the current QR.
  144. Output - pqrCur points to the next QR or
  145. is equal to pqrMax if no next QR.
  146. */
  147. PQR pqrMax)
  148. {
  149. register PQR pqr;
  150. register TM tm;
  151. /* Assume there are no more QRs. */
  152. tm = TMNILHIGH;
  153. if ((pqr = *ppqrCur) < pqrMax)
  154. {
  155. tm = pqr -> tm;
  156. *ppqrCur = (PQR)((BYTE*)pqr + pqr->cb);
  157. }
  158. return (tm);
  159. }
  160. /**** TmNextRegular - return the next regular TM or TMNILHIGH if there
  161. is no next regular TM.
  162. */
  163. TM APIENTRY TmNextRegular (register TM tm)
  164. {
  165. register TM tmNext;
  166. /* Calculate the next regular appointment time. */
  167. tmNext = tm + vcMinInterval - (tm % vcMinInterval);
  168. /* Return TMNILHIGH if beyond the end of the day. */
  169. if (tmNext > TMLAST)
  170. tmNext = TMNILHIGH;
  171. return (tmNext);
  172. }