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.

709 lines
19 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. ***** calday.c
  10. *****
  11. */
  12. #include "cal.h"
  13. #define FIXEDFONTWIDTH 0
  14. UINT wID;
  15. BOOL vfUpdate = TRUE; /* flag to disable setqdec() update fix. 27-Oct-1987 */
  16. /**** DayMode - Switch to day mode. */
  17. VOID APIENTRY DayMode (D3 *pd3)
  18. {
  19. RECT rect;
  20. HDC hDC;
  21. if (!vfDayMode)
  22. {
  23. /* Say we are in day mode. */
  24. vfDayMode = TRUE;
  25. /* Disable focus for now. If in notes area, leave it there,
  26. otherwise set up to give focus to appointment description.
  27. */
  28. CalSetFocus ((HWND)NULL);
  29. if (vhwndFocus != vhwnd2C)
  30. vhwndFocus = vhwnd3;
  31. /* Clear the window so we don't get a blank region appearing
  32. in the middle of the monthly calendar when we ShowWindow
  33. the appointment description edit control.
  34. */
  35. GetClientRect (vhwnd2B, (LPRECT)&rect);
  36. rect.bottom -= vcyBorder;
  37. hDC = CalGetDC (vhwnd2B);
  38. FillRect (hDC, (LPRECT)&rect, vhbrBackSub);
  39. ReleaseDC (vhwnd2B, hDC);
  40. /* Make the appointment description edit control visible. */
  41. SetEcText(vhwnd3, "");
  42. SetScrollRange (vhwnd2B, SB_HORZ, 0, 0, TRUE);
  43. SetScrollPos (vhwnd2B, SB_HORZ, 0,TRUE);
  44. /*InvalidateRect (vhwnd2B, (LPRECT)NULL, FALSE);*/
  45. UpdateWindow (vhwnd2B);
  46. ShowWindow (vhwnd3, SHOW_OPENWINDOW);
  47. }
  48. /* Switch to the specified date. Note that this gets done even if
  49. we were already in day mode. This means that the View Day command
  50. can be used to get back to the starting time of the currently
  51. displayed day. It also is necessary because there callers who
  52. want the day redisplayed even if already in day mode (like New).
  53. */
  54. SwitchToDate (pd3);
  55. }
  56. /**** SwitchToDate - the ONLY routine that changes the selected day in
  57. day mode.
  58. */
  59. VOID APIENTRY SwitchToDate ( D3 *pd3 )
  60. {
  61. RECT rect;
  62. register BOOL fNewMonth;
  63. if (FGetDateDr (DtFromPd3 (pd3)))
  64. {
  65. fNewMonth = vd3Sel.wMonth != pd3 -> wMonth
  66. || vd3Sel.wYear != pd3 -> wYear;
  67. vd3Sel = *pd3;
  68. if (fNewMonth)
  69. SetUpMonth ();
  70. }
  71. FillTld (vtmStart);
  72. SetQdEc (0);
  73. /* If focus is on notes area put it there. Otherwise it has already
  74. been set up by SetQdEc.
  75. */
  76. if (vhwndFocus == vhwnd2C)
  77. CalSetFocus (vhwnd2C);
  78. /* Set the scroll bar range and thumb position. (The scroll bar range
  79. depends on the number of TM in the day, so it must be set up each
  80. time the day is changed.)
  81. */
  82. SetDayScrollRange ();
  83. SetDayScrollPos (-1);
  84. /* Repaint Wnd2A to display "Schedule for: ..." message. */
  85. InvalidateRect (vhwnd2A, (LPRECT)NULL, TRUE);
  86. UpdateWindow (vhwnd2A);
  87. /* Redraw the appointments. */
  88. GetClientRect (vhwnd1, (LPRECT)&rect);
  89. rect.bottom = vycoWnd2C;
  90. rect.top = vcyWnd2A;
  91. InvalidateRect (vhwnd1, (LPRECT)&rect, TRUE);
  92. /* UpdateWindow (vhwnd1); */
  93. /* Set up the notes area. */
  94. SetNotesEc ();
  95. }
  96. /**** DayPaint */
  97. VOID APIENTRY DayPaint (HDC hDC)
  98. {
  99. CHAR sz [CCHTIMESZ];
  100. register INT ycoText;
  101. register INT ln;
  102. INT cch;
  103. TM tm;
  104. CHAR *pchQd;
  105. RECT rectQd;
  106. BYTE *pbTqr;
  107. DWORD iSelFirst;
  108. DWORD iSelLast;
  109. #ifdef DISABLE
  110. DWORD iSelFirstT;
  111. DWORD iSelLastT;
  112. #endif
  113. pbTqr = PbTqrLock ();
  114. rectQd.right = vxcoQdMax ;
  115. rectQd.left = vxcoQdFirst;
  116. for (ln = 0; ln < vcln; ln++)
  117. {
  118. ycoText = YcoFromLn (ln);
  119. if (FAlarm (ln))
  120. DrawAlarmBell (hDC, ycoText);
  121. cch = GetTimeSz (tm = vtld [ln].tm, sz);
  122. /* Display am or pm only for the first appointment in the window
  123. and for noon.
  124. */
  125. if (ln != 0 && tm != TMNOON)
  126. cch = 5;
  127. TextOut (hDC, vxcoApptTime, ycoText, (LPSTR)sz, cch);
  128. rectQd.top = YcoFromLn (ln);
  129. rectQd.bottom = rectQd.top + vcyFont;
  130. pchQd = "";
  131. if (vtld [ln].otqr != OTQRNIL)
  132. pchQd = (CHAR *)(pbTqr + vtld [ln].otqr + CBQRHEAD);
  133. DrawText (hDC, (LPSTR)pchQd, -1, (LPRECT)&rectQd,
  134. DT_NOPREFIX | DT_SINGLELINE | DT_LEFT | DT_TOP);
  135. if (ln == vlnCur)
  136. {
  137. /* We have just painted the appointment that has the
  138. edit control. In order to keep "flashing" to a minimum,
  139. we want to prevent the edit control from repainting,
  140. but we do need to get the highlight back up.
  141. So:
  142. 1) Validate the edit control to prevent repainting.
  143. 2) Disable redraw.
  144. 3) Fetch and save the current selection.
  145. 4) Set the selection to null (redraw is off, so this
  146. will not affect the highlight).
  147. 5) Enable redraw.
  148. 6) Set the selection back to the saved value. Since redraw
  149. is enabled this will highlight the selected characters.
  150. */
  151. #ifdef DISABLE
  152. ValidateRect (vhwnd3, (LPRECT)NULL);
  153. SendMessage (vhwnd3, WM_SETREDRAW, FALSE, 0L);
  154. MSendMsgEM_GETSEL(vhwnd3, &iSelFirst, &iSelLast);
  155. iselFirstT = iSelFirst;
  156. iselLastT = iSelLast;
  157. iselFirst = iSelLast = 0;
  158. SendMessage(vhwnd3, EM_SETSEL, iSelFirst, (LONG)iSelLast);
  159. SendMessage(vhwnd3, WM_SETREDRAW, TRUE, 0L);
  160. SendMessage(vhwnd3, EM_SETSEL, iSelFirstT, (LONG)iSelLastT);
  161. #else
  162. /* don't try to be fancy. If only part of hilight in update
  163. * region, there was bug with selection being half inverted,
  164. * half normal. This solved it. 10-Jun-1987.
  165. */
  166. MSendMsgEM_GETSEL(vhwnd3, &iSelFirst, &iSelLast);
  167. SendMessage(vhwnd3, EM_SETSEL, iSelFirst, (LONG)iSelLast);
  168. #endif
  169. }
  170. }
  171. DrUnlockCur ();
  172. }
  173. /**** FillTld */
  174. VOID APIENTRY FillTld (TM tmFirst)
  175. {
  176. LD *pldCur;
  177. LD *pldLast;
  178. INT cldEmpty;
  179. /* Find the first appointment less than or equal to the specified
  180. one. Note that since tmFirst must be greater than or equal to
  181. 0 (midnight), calling FGetPrevLd with tmFirst + 1 is guaranteed
  182. to find something, so there is no need to check the return value.
  183. */
  184. FGetPrevLd (tmFirst + 1, vtld);
  185. /* Work forward filling in the tld. Stop when the end of the
  186. table is reached or the end of the day is reached.
  187. */
  188. for (pldLast = (pldCur = vtld) + vlnLast; pldCur < pldLast
  189. && FGetNextLd (pldCur -> tm, pldCur + 1); pldCur++)
  190. ;
  191. /* If we stopped going forward because we reached the end of the day
  192. instead of the end of the tld, there are empty entries at the end
  193. of the tld. In this case, we scroll the tld down to put the
  194. empty space at the top, and then we fill in the empty space by
  195. getting the earlier appointment times. There will always be
  196. enough appointment times to fill the tld since the maximum interval
  197. (1 hour) gives 24 appointment times, and we don't have that many
  198. lines for displaying appointments. So there is no need to check
  199. the return value of FGetPrevLd below, and we can rest assured that
  200. the tld will get completely filled.
  201. */
  202. if ((cldEmpty = (INT)(pldLast - pldCur)) > 0)
  203. {
  204. ScrollDownTld (cldEmpty);
  205. for (pldCur = vtld + cldEmpty; pldCur > vtld; pldCur--)
  206. FGetPrevLd (pldCur -> tm, pldCur - 1);
  207. }
  208. }
  209. /**** ScrollDownTld - Scroll the tld down (towards the bottom of the screen,
  210. but higher in memory) the specified number of ld,
  211. making room for new lds at the top of the tld.
  212. */
  213. VOID APIENTRY ScrollDownTld (INT cld)
  214. {
  215. BltByte ((BYTE *)vtld, (BYTE *)(vtld + cld),
  216. (WORD)((vcln - cld) * sizeof (LD)));
  217. }
  218. /**** ScrollUpTld - Scroll the tld up (towards the top of the screen,
  219. but lower in memory) the specified number of ld,
  220. making room for new lds at the bottom of the tld.
  221. */
  222. VOID APIENTRY ScrollUpTld (INT cld)
  223. {
  224. BltByte ((BYTE *)(vtld + cld), (BYTE *)vtld,
  225. (WORD)((vcln - cld) * sizeof (LD)));
  226. }
  227. /**** FGetNextLd */
  228. BOOL APIENTRY FGetNextLd (
  229. TM tm,
  230. LD *pld)
  231. {
  232. TM tmFromTqr;
  233. DR *pdr;
  234. FSearchTqr (tm);
  235. tmFromTqr = TMNILHIGH;
  236. if (votqrNext != (pdr = PdrLockCur ()) -> cbTqr)
  237. tmFromTqr = ((PQR )(PbTqrFromPdr (pdr) + votqrNext)) -> tm;
  238. DrUnlockCur ();
  239. if ((tm = min (tmFromTqr, TmNextRegular (tm))) == TMNILHIGH)
  240. return (FALSE);
  241. pld -> tm = tm;
  242. pld -> otqr = tm == tmFromTqr ? votqrNext : OTQRNIL;
  243. return (TRUE);
  244. }
  245. /**** FGetPrevLd */
  246. BOOL APIENTRY FGetPrevLd (
  247. TM tm,
  248. LD *pld)
  249. {
  250. TM tmFromTqr;
  251. TM tmInterval;
  252. FSearchTqr (tm);
  253. tmFromTqr = TMNILLOW;
  254. if ((WORD)votqrPrev != OTQRNIL)
  255. {
  256. tmFromTqr = ((PQR )(PbTqrLock () + votqrPrev)) -> tm;
  257. DrUnlockCur ();
  258. }
  259. /* Calculate the previous regular appointment time. */
  260. tmInterval = tm - 1;
  261. if (tm == 0 || (tmInterval -= tmInterval % vcMinInterval) < 0)
  262. tmInterval = TMNILLOW;
  263. if ((tm = max (tmFromTqr, tmInterval)) == TMNILLOW)
  264. return (FALSE);
  265. pld -> tm = tm;
  266. pld -> otqr = tm == tmFromTqr ? votqrPrev : OTQRNIL;
  267. return (TRUE);
  268. }
  269. /**** FScrollDay */
  270. BOOL APIENTRY FScrollDay (
  271. INT code,
  272. UINT posNew)
  273. {
  274. wID=code;
  275. switch (code)
  276. {
  277. case SB_LINEUP:
  278. ScrollDownDay (1, TRUE, FALSE);
  279. break;
  280. case SB_LINEDOWN:
  281. ScrollUpDay (1, TRUE);
  282. break;
  283. case SB_PAGEUP:
  284. ScrollDownDay (vlnLast, TRUE, FALSE);
  285. break;
  286. case SB_PAGEDOWN:
  287. ScrollUpDay (vlnLast, TRUE);
  288. break;
  289. case SB_THUMBPOSITION:
  290. /* Record current edits (before changing the tld). */
  291. if (vhwndFocus == vhwnd3)
  292. CalSetFocus ((HWND)NULL);
  293. FillTld (TmFromItm (posNew));
  294. /* Move the call to SetQdEc() after the call to SetDayScrollPos(), and
  295. use GetScrollPos() to find out if the location passed was beyond the
  296. end of the scrollbar. If not, 0 will be passed as before. If true,
  297. the call to SetQdEc() will step down to the appropriate location on
  298. the display. Tracked down to solve Bug #2502.
  299. 16 July 1989 Clark Cyr */
  300. #if DISABLE
  301. SetQdEc (0);
  302. #endif
  303. SetDayScrollPos (posNew);
  304. SetQdEc(posNew - GetScrollPos(vhwnd2B, SB_VERT));
  305. InvalidateRect (vhwnd2B, (LPRECT)NULL, TRUE);
  306. break;
  307. default:
  308. return (FALSE);
  309. }
  310. return (TRUE);
  311. }
  312. /**** ScrollDownDay
  313. ctNew is number of lines to scroll. fScrollBar is true if we
  314. are not being scrolled by cursor movement. fSizing is true iff
  315. we are scrolling as a result of resizing. */
  316. VOID APIENTRY ScrollDownDay (
  317. INT ctmNew,
  318. BOOL fScrollBar,
  319. BOOL fSizing)
  320. {
  321. register INT ctm;
  322. register INT ln;
  323. LD ldTemp;
  324. RECT rect;
  325. HDC hDC;
  326. TM tmFirstOld;
  327. extern INT cchTimeMax;
  328. CHAR sz[CCHTIMESZ];
  329. INT cch;
  330. INT iHeight;
  331. INT iWidth;
  332. /* Register current changes and hide the caret. */
  333. if (vhwndFocus == vhwnd3)
  334. CalSetFocus ((HWND)NULL);
  335. tmFirstOld = vtld [0].tm;
  336. for (ctm = 0; ctm <(ctmNew) && FGetPrevLd (vtld [0].tm, &ldTemp) ; ctm++)
  337. {
  338. ScrollDownTld (1);
  339. vtld [0] = ldTemp;
  340. }
  341. if (ctm != 0)
  342. {
  343. /* Get rid of am or pm on top line of window if it's not noon.
  344. Note - it's OK to execute this code even if in 24 hour mode
  345. since we will just be putting spaces over spaces.
  346. */
  347. if (tmFirstOld != TMNOON)
  348. {
  349. hDC = CalGetDC (vhwnd2B);
  350. cch = GetTimeSz (tmFirstOld, sz);
  351. MGetTextExtent(hDC, sz, 5, &iHeight, &iWidth); /* width of time string
  352. + the blank following it */
  353. //- KLUDGE: TextOut (hDC, vxcoApptTime + iWidth, vycoQdFirst,
  354. //- KLUDGE: (LPSTR)vszBlankString,cchTimeMax+3);
  355. //- For some reason, the above code no longer blanks out the
  356. //- correct area. It puts a space in the center of the time.
  357. TextOut (hDC, vxcoApptTime + iWidth + 19, vycoQdFirst,
  358. (LPSTR)" ",12);
  359. ReleaseDC (vhwnd2B, hDC);
  360. }
  361. GetClientRect (vhwnd2B, (LPRECT)&rect);
  362. rect.top = vycoQdFirst;
  363. rect.bottom = vycoQdMax;
  364. ScrollWindow (vhwnd2B, 0, ctm * vcyLineToLine, &rect,&rect);
  365. }
  366. /* Need to reset focus even if nothing has scrolled since
  367. the focus got turned off above.
  368. */
  369. ln = 0;
  370. if (fScrollBar)
  371. ln = min (vlnCur + ctm , vlnLast);
  372. vfUpdate = FALSE;
  373. SetQdEc (ln);
  374. vfUpdate = TRUE;
  375. /* When SetQdEc validates the appointment edit control, the
  376. corresponding rectangle of its parent (wnd2B) gets validated
  377. too. If this is in the portion of wnd2B that was invalidated
  378. by the scroll, we must invalidate it now so it gets painted
  379. by DayPaint.
  380. We brought in ctm new lines at the top of wnd2B, so if the
  381. new ln (the position of the appointment edit control) is
  382. less than ctm, it's in the invalidated portion of wnd2B.
  383. Note that if ctm == 0, ln can't be less, so this case is OK.
  384. If we are resizing, whole window will be repainted.
  385. */
  386. if (ln < ctm || fSizing)
  387. InvalidateParentQdEc (ln);
  388. if (ctm != 0)
  389. {
  390. UpdateWindow (vhwnd2B);
  391. AdjustDayScrollPos (-ctm);
  392. /* Need to update edit ctl window incase obscurred by popup. */
  393. if (AnyPopup() && vhwnd3)
  394. {
  395. InvalidateRect(vhwnd3, (LPRECT)NULL, TRUE);
  396. UpdateWindow(vhwnd3);
  397. }
  398. }
  399. }
  400. /**** ScrollUpDay */
  401. VOID APIENTRY ScrollUpDay (
  402. INT ctmNew,
  403. BOOL fScrollBar)
  404. {
  405. register INT ctm;
  406. register INT ln;
  407. LD ldTemp;
  408. RECT rect;
  409. HDC hDC;
  410. /* Register current edits and hide the caret. */
  411. if (vhwndFocus == vhwnd3)
  412. CalSetFocus ((HWND)NULL);
  413. for (ctm = 0; ctm < (ctmNew) && FGetNextLd (vtld [vlnLast].tm, &ldTemp);
  414. ctm++)
  415. {
  416. ScrollUpTld (1);
  417. vtld [vlnLast] = ldTemp;
  418. }
  419. if (ctm != 0)
  420. {
  421. GetClientRect (vhwnd2B, (LPRECT)&rect);
  422. rect.top = vycoQdFirst;
  423. rect.bottom = vycoQdMax;
  424. ScrollWindow (vhwnd2B, 0, -ctm * vcyLineToLine, &rect, &rect);
  425. if (wID==SB_PAGEDOWN)
  426. {
  427. /* Fix the problem of not repainting some times when scrolling */
  428. rect.top=vycoQdFirst;
  429. rect.bottom =vycoQdMax-(ctm*vcyLineToLine);
  430. rect.right=vxcoQdMax;
  431. rect.left=0;
  432. InvalidateRect(vhwnd2B, &rect, TRUE);
  433. }
  434. /* If in 12 hour mode, put am/pm on first appointment in the window. */
  435. if (!vfHour24)
  436. {
  437. #if FIXEDFONTWIDTH
  438. CHAR *sz;
  439. extern CHAR sz1159[];
  440. extern CHAR sz2359[];
  441. #else
  442. CHAR sz[CCHTIMESZ];
  443. INT cch;
  444. #endif
  445. hDC = CalGetDC (vhwnd2B);
  446. /* This has the problem that spaces do not have the same width as numbers
  447. in the new system fonts. Depending on vxcoAmPm as the constant position
  448. for where AM and PM should be offset is no longer safe. This is just a
  449. bandaid and should be written correctly later. 17 July 1989 Clark Cyr */
  450. #if FIXEDFONTWIDTH
  451. sz=(vtld[0].tm < TMNOON ? sz1159 : sz2359);
  452. TextOut(hDC, vxcoAmPm, vycoQdFirst, sz , lstrlen(sz));
  453. #else
  454. cch = GetTimeSz (vtld[0].tm, sz);
  455. TextOut (hDC, vxcoApptTime, vycoQdFirst, (LPSTR)sz, cch);
  456. #endif
  457. ReleaseDC (vhwnd2B, hDC);
  458. }
  459. }
  460. /* Need to reset focus even if nothing has scrolled since
  461. the focus got turned off above.
  462. */
  463. ln = vlnLast;
  464. if (fScrollBar)
  465. ln = max (vlnCur - ctm, 0);
  466. vfUpdate = FALSE;
  467. SetQdEc (ln);
  468. vfUpdate = TRUE;
  469. /* When SetQdEc validates the appointment edit control, the
  470. corresponding rectangle of its parent (wnd2B) gets validated
  471. too. If this is in the portion of wnd2B that was invalidated
  472. by the scroll, we must invalidate it now so it gets painted
  473. by DayPaint.
  474. We brought in ctm new lines at the bottom of wnd2B, so if the
  475. new ln (the position of the appointment edit control) is
  476. greater than vlnLast - ctm, it's in the invalidated portion of wnd2B.
  477. Note that if ctm == 0, ln can't be greater, so this case is OK.
  478. */
  479. if (ln > vlnLast - ctm)
  480. InvalidateParentQdEc (ln);
  481. if (ctm != 0)
  482. {
  483. rect.top = YcoFromLn(vlnLast);
  484. rect.bottom = rect.top + vcyLineToLine;
  485. InvalidateRect(vhwnd2B, (LPRECT)&rect, TRUE);
  486. UpdateWindow (vhwnd2B);
  487. AdjustDayScrollPos (ctm);
  488. /* Need to update edit ctl window incase obscurred by popup. */
  489. if (AnyPopup() && vhwnd3)
  490. {
  491. InvalidateRect(vhwnd3, (LPRECT)NULL, TRUE);
  492. UpdateWindow(vhwnd3);
  493. }
  494. }
  495. }
  496. /**** InvalidateParentQdEc */
  497. VOID APIENTRY InvalidateParentQdEc (INT ln)
  498. {
  499. RECT rect;
  500. rect.top = YcoFromLn (ln);
  501. rect.bottom = rect.top + vcyFont;
  502. rect.left = vxcoQdFirst;
  503. rect.right = vxcoQdMax;
  504. InvalidateRect (vhwnd2B, &rect, TRUE);
  505. OffsetRect(&rect, 0, vcyWnd2A);
  506. InvalidateRect (vhwnd1, &rect, TRUE);
  507. }
  508. /**** YcoFromLn - given line number, return yco within Wnd2B */
  509. INT APIENTRY YcoFromLn (INT ln)
  510. {
  511. return (vycoQdFirst + ln * vcyLineToLine);
  512. }
  513. /**** LnFromYco - given yco within Wnd2B, return line number. */
  514. INT APIENTRY LnFromYco (INT yco)
  515. {
  516. return (min (max (yco - vycoQdFirst, 0) / vcyLineToLine, vlnLast));
  517. }
  518. /**** SetQdEc - Position and set the text of the appointment description
  519. edit control.
  520. */
  521. VOID APIENTRY SetQdEc (INT ln)
  522. {
  523. register BYTE *pbTqr;
  524. register CHAR *pchQd;
  525. RECT rc;
  526. /* Store edits for current appointment description. */
  527. if (vhwndFocus == vhwnd3)
  528. CalSetFocus ((HWND)NULL);
  529. /* Set the new current ln. */
  530. vlnCur = ln;
  531. /* do this to fix bug when scrolling before window is
  532. * actually painted on screen. the movewindow below
  533. * forces the parents update region to clip out where
  534. * the child window was, and it would not get erased.
  535. * if in the scrollup/dn code, don't do the update or
  536. * you get an unnecessary flash. vfUpdate will be false.
  537. * 27-Oct-1987. davidhab.
  538. */
  539. if (vfUpdate && GetUpdateRect(vhwnd2B, (LPRECT)&rc, FALSE)) {
  540. GetWindowRect(vhwnd3, (LPRECT)&rc);
  541. UpdateWindow(vhwnd2B);
  542. }
  543. ShowWindow(vhwnd3, SW_HIDE);
  544. MoveWindow (vhwnd3, vxcoQdFirst, YcoFromLn (ln),
  545. vxcoQdMax - vxcoQdFirst , vcyFont, FALSE);
  546. pbTqr = PbTqrLock ();
  547. pchQd = "";
  548. if (vtld [ln].otqr != OTQRNIL)
  549. pchQd = (CHAR *)(pbTqr + vtld [ln].otqr + CBQRHEAD);
  550. /*SendMessage (vhwnd3, WM_SETREDRAW, FALSE, 0L);*/
  551. SetEcText(vhwnd3, pchQd);
  552. ShowWindow(vhwnd3, SW_SHOW);
  553. /*SendMessage (vhwnd3, WM_SETREDRAW, TRUE, 0L);
  554. ValidateRect (vhwnd3, (LPRECT)NULL);*/
  555. DrUnlockCur ();
  556. /* If not in the notes area, give the focus to the appointment
  557. description edit control.
  558. */
  559. if (vhwndFocus == vhwnd3)
  560. CalSetFocus (vhwnd3);
  561. }