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.

458 lines
11 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. * ***** calmon2.c
  7. *
  8. */
  9. #include "cal.h"
  10. /**** FMonthPrev ****/
  11. BOOL APIENTRY FMonthPrev ()
  12. {
  13. if (vd3To.wMonth != MONTHJAN)
  14. vd3To.wMonth--;
  15. else
  16. {
  17. if (vd3To.wYear == YEAR1980)
  18. return (FALSE);
  19. vd3To.wYear--;
  20. vd3To.wMonth = MONTHDEC;
  21. }
  22. return (TRUE);
  23. }
  24. /**** FMonthNext ****/
  25. BOOL APIENTRY FMonthNext ()
  26. {
  27. if (vd3To.wMonth != MONTHDEC)
  28. vd3To.wMonth++;
  29. else
  30. {
  31. if (vd3To.wYear == YEAR2099)
  32. return (FALSE);
  33. vd3To.wYear++;
  34. vd3To.wMonth = MONTHJAN;
  35. }
  36. return (TRUE);
  37. }
  38. /**** ShowMonthPrevNext ****/
  39. VOID APIENTRY ShowMonthPrevNext (BOOL fNext)
  40. {
  41. /* First see if able to move to previous or next month. (Can't
  42. move back if already January 1980, can't move forward if already
  43. December 2099.)
  44. */
  45. if (fNext ? FMonthNext () : FMonthPrev ())
  46. UpdateMonth ();
  47. }
  48. /**** UpdateMonth - update the month display after the month has been
  49. changed, or when switching from day mode to month mode.
  50. Set the selected day to the minimum of the sticky day or the
  51. last day of the month.
  52. ****/
  53. VOID APIENTRY FAR UpdateMonth ()
  54. {
  55. HDC hDC;
  56. /* See if the data can be fetched for the target date. If not,
  57. don't switch to that date. If so, switch.
  58. */
  59. vd3To.wDay = (WORD)min ((INT)(CDaysMonth (&vd3To) - 1), (INT)vwDaySticky);
  60. if (FFetchTargetDate ())
  61. {
  62. vd3Sel=vd3To;
  63. SetScrollPos(vhwnd2B, SB_VERT, vd3Sel.wYear*12+vd3Sel.wMonth, TRUE);
  64. SetUpMonth ();
  65. InvalidateMonth ();
  66. UpdateWindow (vhwnd0); /* changed from vhwnd2B to fix scrollbar
  67. repaint problems */
  68. SetNotesEc ();
  69. hDC=GetDC(vhwnd2A);
  70. DispDate (hDC, &vd3To);
  71. ReleaseDC(vhwnd2A, hDC);
  72. }
  73. }
  74. /**** MouseSelectDay - we have a click in the monthly calendar. Map
  75. it to a day and move the selection.
  76. *****/
  77. VOID APIENTRY MouseSelectDay (
  78. MPOINT point, /* Screen coordinates of mouse where click
  79. occurred.
  80. */
  81. BOOL fDblClk) /* TRUE for double click. */
  82. {
  83. INT ixco, iyco, irgb;
  84. if (FMapCoToIGrid (point.x, vrgxcoGrid, 7, &ixco) &&
  85. FMapCoToIGrid (point.y, vrgycoGrid, vcWeeksMonth, &iyco) &&
  86. vrgbMonth [irgb = 7 * iyco + ixco +7*vmScrollPos + hmScrollPos]
  87. != 0)
  88. {
  89. vd3To = vd3Sel;
  90. MoveSelCurMonth (irgb - vwWeekdayFirst );
  91. /* Give the focus to the calendar if it doesn't already have it. */
  92. if (GetFocus () != vhwnd2B)
  93. CalSetFocus (vhwnd2B);
  94. /* Switch to day mode for the day the user double clicked on. */
  95. if (fDblClk)
  96. DayMode (&vd3Sel);
  97. }
  98. }
  99. /**** FScrollMonth */
  100. /************************************************************************
  101. *
  102. * VOID PASCAL FScrollMonth (code, posNew)
  103. *
  104. * purpose : calculates sone vertical scroll globals and scrolls
  105. * the month display vertically.
  106. *
  107. ***********************************************************************/
  108. VOID APIENTRY FScrollMonth (
  109. INT code,
  110. UINT posNew)
  111. {
  112. INT dy;
  113. RECT rect;
  114. /* calculate the step size for the scroll. The step size is
  115. approximately the height of the month grid */
  116. if (hmScrollMax == 0)
  117. dy = (vcyWnd2BBot - vcyBorder +vcyHScrollBar)/ vcWeeksMonth;
  118. else
  119. dy = (vcyWnd2BBot - vcyBorder)/ vcWeeksMonth;
  120. switch (code)
  121. {
  122. case SB_LINEUP :
  123. vmScrollInc = -1;
  124. break;
  125. case SB_LINEDOWN:
  126. vmScrollInc = 1;
  127. break;
  128. case SB_TOP:
  129. vmScrollInc = -vmScrollPos;
  130. break;
  131. case SB_BOTTOM :
  132. vmScrollInc = vmScrollMax - vmScrollPos;
  133. break;
  134. case SB_PAGEUP :
  135. case SB_PAGEDOWN :
  136. break;
  137. case SB_THUMBTRACK :
  138. vmScrollInc = posNew -vmScrollPos;
  139. break;
  140. default:
  141. vmScrollInc = 0;
  142. }
  143. if ((vmScrollInc = max(-vmScrollPos,
  144. min (vmScrollInc, vmScrollMax-vmScrollPos))) != 0)
  145. {
  146. GetClientRect (vhwnd2B, (LPRECT)&rect);
  147. rect.top = vcyWnd2BTop;
  148. rect.bottom = vcyWnd2BBot + 2*dy;
  149. if (vmScrollMax ==1)
  150. rect.bottom += dy;
  151. vmScrollPos +=vmScrollInc;
  152. ScrollWindow (vhwnd2B, 0, -dy * vmScrollInc, &rect, &rect);
  153. SetScrollPos (vhwnd2B, SB_VERT, vmScrollPos, TRUE);
  154. /* refresh screen to get rid of caret droppings */
  155. rect.bottom = vcyWnd2BBot;
  156. rect.top -= 3*vcyLineToLine;
  157. InvalidateRect(vhwnd2B, (LPRECT)&rect, TRUE);
  158. UpdateWindow (vhwnd2B);
  159. }
  160. }
  161. /************************************************************************
  162. *
  163. * VOID PASCAL FHorizScrollMonth (code, posNew)
  164. *
  165. * purpose : calculates some horizontal scroll globals and scrolls the
  166. * month display vertically.
  167. *
  168. ***********************************************************************/
  169. VOID APIENTRY FHorizScrollMonth (
  170. INT code,
  171. WORD posNew)
  172. {
  173. RECT rect;
  174. INT dx;
  175. /* calculate the step size for the scroll. The step size
  176. is approximately the width of the month grid */
  177. if (vmScrollMax == 0)
  178. dx = (vcxWnd2B + vcxBorder+ vcxVScrollBar)/7;
  179. else
  180. dx = (vcxWnd2B + vcxBorder)/7;
  181. switch (code)
  182. {
  183. case SB_LINEUP:
  184. hmScrollInc = -1;
  185. break;
  186. case SB_LINEDOWN:
  187. hmScrollInc = 1;
  188. break;
  189. case SB_TOP :
  190. hmScrollInc = -hmScrollPos;
  191. break;
  192. case SB_BOTTOM:
  193. hmScrollInc = hmScrollMax -hmScrollPos;
  194. break;
  195. case SB_PAGEUP:
  196. case SB_PAGEDOWN:
  197. break;
  198. case SB_THUMBTRACK:
  199. hmScrollInc = posNew - hmScrollPos;
  200. break;
  201. default:
  202. hmScrollInc = 0;
  203. }
  204. if ((hmScrollInc = max(-hmScrollPos,
  205. min(hmScrollInc, hmScrollMax - hmScrollPos))) != 0)
  206. {
  207. GetClientRect (vhwnd2B, (LPRECT)&rect);
  208. rect.top = vcyWnd2BTop - vcyLineToLine;
  209. rect.bottom = vycoQdMax;
  210. hmScrollPos += hmScrollInc;
  211. ScrollWindow ( vhwnd2B , -dx*hmScrollInc, 0, &rect, &rect);
  212. SetScrollPos ( vhwnd2B, SB_HORZ, hmScrollPos, TRUE );
  213. /* refresh screen to get rid of caret droppings */
  214. rect.bottom += vcyHScrollBar;
  215. rect.top -= 2* vcyLineToLine;
  216. InvalidateRect(vhwnd2B, (LPRECT)&rect, TRUE);
  217. UpdateWindow ( vhwnd2B );
  218. }
  219. }
  220. /**** FCalKey ****/
  221. BOOL APIENTRY FCalKey (
  222. HWND hwnd,
  223. WPARAM kc) /* The virtual key code. */
  224. {
  225. register INT iTemp;
  226. if (!vfDayMode && hwnd == vhwnd2B)
  227. {
  228. vd3To = vd3Sel;
  229. switch (kc)
  230. {
  231. case VK_LEFT:
  232. if (vd3To.wDay != 0)
  233. MoveSelCurMonth (vd3To.wDay - 1);
  234. else
  235. if (FMonthPrev ())
  236. MoveSelNewMonth (CDaysMonth (&vd3To) - 1);
  237. break;
  238. case VK_RIGHT:
  239. if ((iTemp = vd3To.wDay + 1) < vcDaysMonth)
  240. MoveSelCurMonth (iTemp);
  241. else
  242. if (FMonthNext ())
  243. MoveSelNewMonth (0);
  244. break;
  245. case VK_UP:
  246. if ((iTemp = vd3To.wDay - 7) >= 0)
  247. MoveSelCurMonth (iTemp);
  248. else
  249. if (FMonthPrev ())
  250. MoveSelNewMonth (CDaysMonth (&vd3To) + iTemp);
  251. break;
  252. case VK_DOWN:
  253. if ((iTemp = vd3To.wDay + 7) < vcDaysMonth)
  254. MoveSelCurMonth (iTemp);
  255. else
  256. {
  257. iTemp -= vcDaysMonth;
  258. if (FMonthNext ())
  259. MoveSelNewMonth (iTemp);
  260. }
  261. break;
  262. case VK_PRIOR:
  263. ShowMonthPrevNext (FALSE);
  264. break;
  265. case VK_NEXT:
  266. ShowMonthPrevNext (TRUE);
  267. break;
  268. case VK_TAB:
  269. /* Switch to the notes area. */
  270. CalSetFocus (vhwnd2C);
  271. break;
  272. case VK_RETURN:
  273. /* Switch to day mode for the selected day. */
  274. DayMode (&vd3Sel);
  275. break;
  276. default:
  277. return (FALSE);
  278. }
  279. return (TRUE);
  280. }
  281. return (FALSE);
  282. }
  283. /**** MoveSelCurMonth ****/
  284. VOID APIENTRY MoveSelCurMonth (UINT uiDaySel)
  285. {
  286. HDC hDC;
  287. WORD wDaySel = (WORD)uiDaySel;
  288. /* Only switch if we can fetch the data for the target date. */
  289. vd3To.wDay = wDaySel;
  290. if (FFetchTargetDate ())
  291. {
  292. hDC = CalGetDC (vhwnd2B);
  293. InvertDay (hDC, vd3Sel.wDay);
  294. InvertDay (hDC, vwDaySticky = vd3Sel.wDay = wDaySel);
  295. ReleaseDC (vhwnd2B, hDC);
  296. hDC=GetDC(vhwnd2A);
  297. DispDate (hDC, &vd3Sel);
  298. ReleaseDC(vhwnd2A, hDC);
  299. PositionCaret ();
  300. SetNotesEc ();
  301. }
  302. }
  303. /**** MoveSelNewMonth ****/
  304. VOID APIENTRY MoveSelNewMonth (UINT uiDaySel)
  305. {
  306. WORD wDaySel = (WORD)uiDaySel;
  307. vd3To.wDay = wDaySel;
  308. /* Don't change vwDaySticky unless we can successfully switch to the
  309. target date.
  310. */
  311. if (FFetchTargetDate ())
  312. {
  313. vwDaySticky = wDaySel;
  314. UpdateMonth ();
  315. }
  316. }
  317. /**** JumpDate - Jump to specified date in month mode. ****/
  318. VOID APIENTRY JumpDate (D3*pd3)
  319. {
  320. register WORD wDay;
  321. wDay = pd3 -> wDay;
  322. if (pd3 -> wMonth == vd3Sel.wMonth && pd3 -> wYear == vd3Sel.wYear)
  323. {
  324. /* The target date is in the same month as the one we are
  325. currently displaying - just move the highlight.
  326. */
  327. MoveSelCurMonth (wDay);
  328. }
  329. else
  330. {
  331. /* The target date is not in the current month. Need to
  332. update the entire month display.
  333. */
  334. vd3To = *pd3;
  335. MoveSelNewMonth (wDay);
  336. }
  337. }
  338. /**** InvalidateMonth ****/
  339. VOID APIENTRY InvalidateMonth ()
  340. {
  341. InvalidateRect (vhwnd2B, NULL, TRUE);
  342. }
  343. /**** FFetchTargetDate ****/
  344. BOOL APIENTRY FFetchTargetDate ()
  345. {
  346. register HWND hwndFocus;
  347. register BOOL fOk;
  348. /* FGetDateDr leaves the focus NULL if it succeeds, so remember who
  349. has it now, and set it back when finished.
  350. */
  351. hwndFocus = GetFocus ();
  352. fOk = FGetDateDr (DtFromPd3 (&vd3To));
  353. CalSetFocus (hwndFocus);
  354. return (fOk);
  355. }