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.

903 lines
24 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. ****** calcmd2.c
  7. *
  8. */
  9. #include "cal.h"
  10. #define ATTRDIR 0xC010 /* added for the revised SaveAs dialog */
  11. #include <ctype.h>
  12. #include <fcntl.h> /* Get O_RDONLY definition for open call. */
  13. CHAR rgch[256]; /* moved out of FnSaveAs because of 512 byte limit of local variables */
  14. CHAR szFullPathName[120];
  15. INT CheckMarginNums(HWND hWnd);
  16. BOOL APIENTRY CallSaveAsDialog ()
  17. {
  18. CHAR szSaveFileSpec [CCHFILESPECMAX] = "";
  19. CHAR szAnsiFileSpec [CCHFILESPECMAX];
  20. extern CHAR szLastDir[];
  21. /* default selection in edit window */
  22. lstrcpy (szSaveFileSpec, OFStruct[IDFILEORIGINAL].szPathName);
  23. /* set up the variable fields of the OPENFILENAME struct. (the constant
  24. * fields have been sel in CalInit()
  25. */
  26. vOFN.lpstrFile = szSaveFileSpec;
  27. vOFN.lpstrInitialDir = szLastDir;
  28. vOFN.lpstrTitle = vszSaveasCaption;
  29. vOFN.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; /* always 0 for SaveAs */
  30. /* All long pointers should be defined immediately before the call.
  31. * L.Raman - 2/12/91
  32. */
  33. vOFN.lpstrFilter = vszFilterSpec;
  34. vOFN.lpstrCustomFilter = vszCustFilterSpec;
  35. vOFN.lpstrDefExt = vszFileExtension + 1; /* point to "CAL" */
  36. if ( GetSaveFileName ((LPOPENFILENAME)&vOFN))
  37. {
  38. // on NT, don't do the oemtoansi, just copy the file into new buffer.
  39. // OemToAnsi(vOFN.lpstrFile, szAnsiFileSpec);
  40. strcpy(szAnsiFileSpec, vOFN.lpstrFile);
  41. return FSaveFile (szAnsiFileSpec, FALSE);
  42. }
  43. return FALSE;
  44. }
  45. /****************************************************************************
  46. *
  47. * INT_PTR FnPageSetup (hwnd, message, wParam, lParam)
  48. *
  49. * purpose : Dialog function for page setup dialog. Accepts header/footer
  50. * formatting instructions and margin lengths.
  51. *
  52. * params : same as for all dialog functions
  53. *
  54. *
  55. ***************************************************************************/
  56. INT_PTR CALLBACK FnPageSetup (
  57. HWND hwnd,
  58. UINT message,
  59. WPARAM wParam,
  60. LPARAM lParam)
  61. {
  62. int id;
  63. WORD2DWORD iSelFirst;
  64. WORD2DWORD iSelLast;
  65. switch (message)
  66. {
  67. case WM_INITDIALOG :
  68. EnableWindow (GetDlgItem (hwnd, IDOK), TRUE);
  69. /* Set the Dialog Items to what they were before. Also handles case
  70. * when Page Setup is chosen for the first time. */
  71. for (id=IDCN_EDITHEADER; id < IDCN_EDITHEADER+6; id++)
  72. {
  73. SendDlgItemMessage(hwnd, id, EM_LIMITTEXT, PT_LEN-1, 0L);
  74. SetDlgItemText(hwnd, id, chPageText[id-IDCN_EDITHEADER]);
  75. }
  76. iSelLast = PT_LEN-1;
  77. iSelFirst = 0;
  78. MSendMsgEM_GETSEL(GetDlgItem(hwnd, IDCN_EDITHEADER),
  79. &iSelFirst, &iSelLast);
  80. CalSetFocus (GetDlgItem (hwnd, IDCN_EDITHEADER));
  81. break;
  82. case WM_COMMAND:
  83. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  84. case IDOK:
  85. /* Store the changes made only if margins are valid nums. */
  86. id = CheckMarginNums(hwnd);
  87. if (id <= 0) /* invalid margins */
  88. {
  89. MessageBox(hwnd, vszIncorrectSyntax, vszCalendar, MB_OK | MB_ICONEXCLAMATION);
  90. if (id == 0) /* can't guess invalid margin */
  91. return TRUE; /* continue the dialog */
  92. else
  93. {
  94. CalSetFocus(GetDlgItem (hwnd, -id));
  95. return FALSE;
  96. }
  97. }
  98. /* store the margin values */
  99. for (id = IDCN_EDITHEADER; id <= IDCN_EDITHEADER+6; id++)
  100. GetDlgItemText(hwnd, id, chPageText[id-IDCN_EDITHEADER], PT_LEN-1);
  101. EndDialog (hwnd, TRUE);
  102. break;
  103. case IDCANCEL :
  104. EndDialog (hwnd, FALSE);
  105. break;
  106. }
  107. return TRUE;
  108. }
  109. return FALSE;
  110. }
  111. /* Check valididity of margin values specified.
  112. * return TRUE if margins are valid.
  113. *
  114. * returns -IDCN_EDITMARGINLEFT if Left margin is invalid,
  115. * -IDCN_EDITMARGINRIGHT if Right margin is invalid
  116. * -IDCN_EDITMARGINTOP if Top margin is invalid
  117. * -IDCN_EDITMARGINBOTTOM if Bottom margin is invalid
  118. * 0/FALSE if it cannot guess the invalid margin
  119. */
  120. INT CheckMarginNums(HWND hWnd)
  121. {
  122. SHORT n;
  123. CHAR *pStr;
  124. CHAR szStr[PT_LEN];
  125. UINT Left, Right, Top, Bottom;
  126. HDC hPrintDC;
  127. UINT xPixInch, yPixInch, xPrintRes, yPrintRes;
  128. for (n = IDCN_EDITHEADER+2; n < IDCN_EDITHEADER+6; n++)
  129. {
  130. GetDlgItemText(hWnd, n, szStr, PT_LEN);
  131. pStr = szStr;
  132. while (*pStr)
  133. if (isdigit(*pStr) || *pStr == szDec[0])
  134. pStr = AnsiNext(pStr);
  135. else
  136. return (-n);
  137. }
  138. if (!(hPrintDC = GetPrinterDC()))
  139. return FALSE;
  140. xPrintRes = GetDeviceCaps(hPrintDC, HORZRES);
  141. yPrintRes = GetDeviceCaps(hPrintDC, VERTRES);
  142. xPixInch = GetDeviceCaps(hPrintDC, LOGPIXELSX);
  143. yPixInch = GetDeviceCaps(hPrintDC, LOGPIXELSY);
  144. DeleteDC(hPrintDC);
  145. /* margin values have int/float values. Do range check */
  146. GetDlgItemText(hWnd, IDCN_EDITMARGINLEFT, szStr, PT_LEN);
  147. Left = atopix(szStr,xPixInch);
  148. GetDlgItemText(hWnd, IDCN_EDITMARGINRIGHT, szStr, PT_LEN);
  149. Right = atopix(szStr, xPixInch);
  150. GetDlgItemText(hWnd, IDCN_EDITMARGINTOP, szStr, PT_LEN);
  151. Top = atopix(szStr, yPixInch);
  152. GetDlgItemText(hWnd, IDCN_EDITMARGINBOT, szStr, PT_LEN);
  153. Bottom = atopix(szStr, yPixInch);
  154. /* try to guess the invalid margin */
  155. if (Left >= xPrintRes)
  156. return -IDCN_EDITMARGINLEFT; /* Left margin is invalid */
  157. else if (Right >= xPrintRes)
  158. return -IDCN_EDITMARGINRIGHT; /* Right margin is invalid */
  159. else if (Top >= yPrintRes)
  160. return -IDCN_EDITMARGINTOP; /* Top margin is invalid */
  161. else if (Bottom >= yPrintRes)
  162. return -IDCN_EDITMARGINBOT; /* Bottom margin is invalid */
  163. else if (Left >= (xPrintRes-Right))
  164. return FALSE; /* can't guess, return FALSE */
  165. else if (Top >= (yPrintRes-Bottom))
  166. return FALSE; /* can't guess, return FALSE */
  167. return TRUE;
  168. }
  169. /**** FnDate */
  170. INT_PTR CALLBACK FnDate (
  171. HWND hwnd,
  172. UINT message,
  173. WPARAM wParam,
  174. LPARAM lParam)
  175. {
  176. CHAR szDate [CCHDASHDATE];
  177. INT iErr;
  178. switch (message)
  179. {
  180. case WM_INITDIALOG:
  181. /* Remember the window handle of the dialog for AlertBox. */
  182. vhwndDialog = hwnd;
  183. SetDlgItemText (hwnd, IDCN_TODATE, "");
  184. return (TRUE);
  185. case WM_COMMAND:
  186. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  187. case IDOK:
  188. GetDlgItemText (hwnd, IDCN_TODATE, szDate, CCHDASHDATE);
  189. if ((iErr = FD3FromDateSz (szDate, &vd3To)) == 0)
  190. EndDialog (hwnd, TRUE);
  191. else
  192. {
  193. /* Error in date - put up message box. */
  194. DateTimeAlert(TRUE, iErr);
  195. /* line added to fix keyboard hang problem
  196. when running under 1.11 */
  197. CalSetFocus (GetDlgItem(hwnd, IDCN_TODATE));
  198. /* Select entire contents of edit control. */
  199. /* 16 July 1989 Clark Cyr */
  200. SendDlgItemMessage(hwnd, IDCN_TODATE, EM_SETSEL,
  201. 0, (DWORD)(-1L));
  202. }
  203. break;
  204. case IDCANCEL:
  205. EndDialog (hwnd, FALSE);
  206. break;
  207. }
  208. return (TRUE);
  209. }
  210. /* Tell Windows we did not process the message. */
  211. return (FALSE);
  212. }
  213. /**** FnControls */
  214. INT_PTR CALLBACK FnControls (
  215. HWND hwnd,
  216. UINT message,
  217. WPARAM wParam,
  218. LPARAM lParam)
  219. {
  220. static BOOL fSound;
  221. static UINT cMinEarlyRing;
  222. BOOL fOk;
  223. switch (message)
  224. {
  225. case WM_INITDIALOG:
  226. /* Remember the window handle of the dialog for AlertBox. */
  227. vhwndDialog = hwnd;
  228. CheckDlgButton (hwnd, IDCN_SOUND, fSound = vfSound);
  229. SetDlgItemInt (hwnd, IDCN_EARLYRING,
  230. cMinEarlyRing = vcMinEarlyRing, FALSE);
  231. return (TRUE);
  232. case WM_COMMAND:
  233. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  234. case IDOK:
  235. cMinEarlyRing = GetDlgItemInt (hwnd, IDCN_EARLYRING,
  236. &fOk, FALSE);
  237. if (!fOk || cMinEarlyRing > 10)
  238. {
  239. /* The value didn't parse or it's not within
  240. range. Put up an error message.
  241. */
  242. AlertBox (vszBadEarlyRing,
  243. (CHAR *)NULL,
  244. MB_APPLMODAL | MB_OK | MB_ICONASTERISK);
  245. /* Don't end the dialog - they will have to
  246. enter a proper time or cancel.
  247. */
  248. /* line added to fix keyboard hanging problem
  249. in ver 1.11 */
  250. CalSetFocus (GetDlgItem( hwnd, IDCN_EARLYRING));
  251. break;
  252. }
  253. /* Assign the new values. */
  254. vfSound = fSound;
  255. vcMinEarlyRing = cMinEarlyRing;
  256. EndDialog (hwnd, TRUE);
  257. break;
  258. case IDCANCEL:
  259. EndDialog (hwnd, FALSE);
  260. break;
  261. case IDCN_SOUND:
  262. CheckDlgButton (hwnd, IDCN_SOUND,
  263. !IsDlgButtonChecked (hwnd, IDCN_SOUND));
  264. fSound = !fSound;
  265. break;
  266. }
  267. return (TRUE);
  268. }
  269. /* Tell Windows we did not process the message. */
  270. return (FALSE);
  271. }
  272. /**** FnSpecialTime */
  273. INT_PTR CALLBACK FnSpecialTime (
  274. HWND hwnd,
  275. UINT message,
  276. WPARAM wParam,
  277. LPARAM lParam)
  278. {
  279. static INT idcheck;
  280. CHAR szTime [CCHTIMESZ];
  281. register CHAR *szError;
  282. register TM tm;
  283. INT iErr;
  284. switch (message)
  285. {
  286. case WM_INITDIALOG:
  287. /* Remember the window handle of the dialog for AlertBox. */
  288. vhwndDialog = hwnd;
  289. /* If the currently selected appointment is not for a regular
  290. time, put the time into the edit control as the default.
  291. This makes it easy for the user to delete the special time.
  292. */
  293. if ((tm = vtld [vlnCur].tm) % vcMinInterval != 0)
  294. {
  295. GetTimeSz (tm, szTime);
  296. SetDlgItemText (hwnd, IDCN_EDIT, szTime);
  297. }
  298. /* Enable or disable the Insert and Delete buttons. */
  299. CheckButtonEnable (hwnd, IDCN_INSERT, EN_CHANGE);
  300. CheckButtonEnable (hwnd, IDCN_DELETE, EN_CHANGE);
  301. /* Check if the display is in 24Hr format; If so, disable the
  302. * AM/PM radio buttons;
  303. * Fix for Bug #5447 --SANKAR-- 10-19-89;
  304. */
  305. if(vfHour24)
  306. {
  307. EnableWindow(GetDlgItem(hwnd, IDCN_AM), FALSE);
  308. EnableWindow(GetDlgItem(hwnd, IDCN_PM), FALSE);
  309. }
  310. else
  311. CheckRadioButton (hwnd, IDCN_AM, IDCN_PM, viAMorPM);
  312. return (TRUE);
  313. case WM_COMMAND:
  314. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  315. case IDCN_EDIT:
  316. CheckButtonEnable (hwnd, IDCN_INSERT, EN_CHANGE);
  317. //- FnSpecialTime: Changed GetParam to EN_CHANGE.
  318. //- Not sure why the old one ever worked.
  319. //- GET_WM_COMMAND_ID(wParam, lParam));
  320. CheckButtonEnable (hwnd, IDCN_DELETE, EN_CHANGE);
  321. //- FnSpecialTime: Changed GetParam to EN_CHANGE.
  322. //- GET_WM_COMMAND_ID(wParam, lParam));
  323. break;
  324. case IDCANCEL:
  325. EndDialog (hwnd, FALSE);
  326. break;
  327. case IDCN_AM:
  328. case IDCN_PM:
  329. viAMorPM = GET_WM_COMMAND_ID(wParam, lParam);
  330. CheckRadioButton (hwnd, IDCN_AM, IDCN_PM, viAMorPM);
  331. break;
  332. case IDOK:
  333. case IDCN_INSERT:
  334. vfInsert = TRUE;
  335. szError = vszTimeAlreadyInUse;
  336. goto InsDel;
  337. case IDCN_DELETE:
  338. vfInsert = FALSE;
  339. szError = vszNoSuchTime;
  340. InsDel:
  341. GetDlgItemText (hwnd, IDCN_EDIT,
  342. szTime, CCHTIMESZ);
  343. if ((iErr = FGetTmFromTimeSz (szTime, &vtmSpecial)) < 0)
  344. {
  345. /* Error in time - put up message box. */
  346. DateTimeAlert(FALSE, iErr);
  347. /* Don't end the dialog - they will have to
  348. enter a proper time or cancel.
  349. */
  350. CalSetFocus (GetDlgItem (hwnd, IDCN_EDIT));
  351. break;
  352. }
  353. /* If we are in 24Hr format, then we should not allow
  354. * the AM/PM radiobuttons to override;
  355. * Fix for Bug #5447 --SANKAR-- 10-19-89
  356. */
  357. if(!vfHour24)
  358. {
  359. /* AM or PM value on radiobutton overrides
  360. text text in edit window */
  361. if (vtmSpecial < TWELVEHOURS)
  362. {
  363. if (viAMorPM == IDCN_PM)
  364. vtmSpecial += TWELVEHOURS;
  365. }
  366. else if (vtmSpecial > TWELVEHOURS)
  367. {
  368. if (viAMorPM == IDCN_AM)
  369. vtmSpecial -= TWELVEHOURS;
  370. }
  371. }
  372. /* Don't allow a regular time to be inserted or
  373. deleted. Note
  374. that it's possible for the special time bit for
  375. a regular time to be set, but it still can't
  376. be deleted. For example, while the interval
  377. in 60, insert a special time of 8:30. Then
  378. switch the interval to 30. While the interval
  379. is 30 (or 15), the 8:30 time cannot be deleted.
  380. */
  381. if (vtmSpecial % vcMinInterval == 0)
  382. {
  383. /* Not a special time. */
  384. AlertBox (vszNotSpecialTime,
  385. (CHAR *)NULL, MB_APPLMODAL | MB_OK
  386. | MB_ICONASTERISK);
  387. break;
  388. }
  389. /* Don't allow insert if time already in tqr.
  390. Don't allow delete if time not in tqr.
  391. OK to use bitwise xor since TRUE == 1 and
  392. FALSE == 0.
  393. */
  394. if (!(FSearchTqr (vtmSpecial) ^ vfInsert))
  395. {
  396. AlertBox (szError, (CHAR *)NULL,
  397. MB_APPLMODAL | MB_OK| MB_ICONASTERISK);
  398. break;
  399. }
  400. EndDialog (hwnd, TRUE);
  401. break;
  402. }
  403. return (TRUE);
  404. }
  405. /* Tell Windows we did not process the message. */
  406. return (FALSE);
  407. }
  408. /**** FnDaySettings */
  409. INT_PTR CALLBACK FnDaySettings (
  410. HWND hwnd,
  411. UINT message,
  412. WPARAM wParam,
  413. LPARAM lParam)
  414. {
  415. static INT idcnInterval;
  416. static INT idcnHourFormat;
  417. INT vfHour24New;
  418. INT iErr;
  419. CHAR szTime [CCHTIMESZ];
  420. switch (message)
  421. {
  422. case WM_INITDIALOG:
  423. /* Remember the window handle of the dialog for AlertBox. */
  424. vhwndDialog = hwnd;
  425. CheckRadioButton (hwnd, IDCN_HOUR12, IDCN_HOUR24,
  426. idcnHourFormat = IDCN_HOUR12 + vfHour24);
  427. GetTimeSz (vtmStart, szTime);
  428. SetDlgItemText (hwnd, IDCN_STARTINGTIME, szTime);
  429. /* We want the current setting of interval to be checked,
  430. and we want the interval group of radio buttons to have
  431. the focus. It doesn't work to call CheckRadioButton
  432. here and then let Windows set the focus to the first
  433. TABGRP in the dialog box, since when it sets the focus,
  434. it also sends us a message to check the first button in
  435. the group (so we would always get 15 checked instead
  436. of the current setting). So we do our own SetFocus
  437. to the interval button we want to check. We then return
  438. FALSE to tell Windows that we have done our own SetFocus.
  439. */
  440. CalSetFocus (GetDlgItem (hwnd, idcnInterval = IDCN_MIN15 +
  441. vmdInterval));
  442. return (FALSE);
  443. case WM_COMMAND:
  444. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  445. case IDOK:
  446. GetDlgItemText (hwnd, IDCN_STARTINGTIME,
  447. szTime, CCHTIMESZ);
  448. /* Note - FGetTmFromTimeSz does not affect
  449. vtmStart if it returns FALSE (i.e., if it detects
  450. an error in the time string).
  451. */
  452. if ((iErr = FGetTmFromTimeSz (szTime, &vtmStart)) < 0)
  453. {
  454. /* Error in time - put up message box. */
  455. DateTimeAlert(FALSE, iErr);
  456. /* Don't end the dialog - they will have to
  457. enter a proper time or cancel.
  458. */
  459. /* line added to fix keyboard hang problem
  460. while running under 3.0 ver 1.11 */
  461. CalSetFocus (GetDlgItem (hwnd, IDCN_STARTINGTIME));
  462. break;
  463. }
  464. vfHour24New = idcnHourFormat - IDCN_HOUR12;
  465. if (vfHour24 != vfHour24New)
  466. {
  467. vfHour24 = vfHour24New;
  468. InitTimeDate(vhInstance, vfHour24 ? GTS_24HOUR : GTS_12HOUR);
  469. }
  470. switch (vmdInterval = idcnInterval - IDCN_MIN15)
  471. {
  472. case MDINTERVAL15:
  473. vcMinInterval = 15;
  474. break;
  475. case MDINTERVAL30:
  476. vcMinInterval = 30;
  477. break;
  478. case MDINTERVAL60:
  479. vcMinInterval = 60;
  480. break;
  481. }
  482. EndDialog (hwnd, TRUE);
  483. break;
  484. case IDCANCEL:
  485. EndDialog (hwnd, FALSE);
  486. break;
  487. case IDCN_MIN15:
  488. case IDCN_MIN30:
  489. case IDCN_MIN60:
  490. CheckRadioButton (hwnd, IDCN_MIN15, IDCN_MIN60,
  491. idcnInterval = GET_WM_COMMAND_ID(wParam, lParam));
  492. break;
  493. case IDCN_HOUR12:
  494. case IDCN_HOUR24:
  495. CheckRadioButton (hwnd, IDCN_HOUR12, IDCN_HOUR24,
  496. idcnHourFormat = GET_WM_COMMAND_ID(wParam, lParam));
  497. break;
  498. }
  499. return (TRUE);
  500. }
  501. /* Tell Windows we did not process the message. */
  502. return (FALSE);
  503. }
  504. /****************************************************************
  505. *
  506. * INT_PTR FAR PASCAL FnMarkDay ( hwnd, message, wParam, lParam)
  507. *
  508. * purpose : puts up Options Mark dialog box and receives the
  509. * marks that are to be put up against the current day.
  510. *
  511. ***************************************************************/
  512. INT_PTR APIENTRY FnMarkDay (
  513. HWND hwnd,
  514. UINT message,
  515. WPARAM wParam,
  516. LPARAM lParam)
  517. {
  518. BOOL checkbutton = FALSE;
  519. switch (message)
  520. {
  521. case WM_INITDIALOG:
  522. /* check buttons corresp. to active marks on selected day */
  523. CheckDlgButton( hwnd, IDCN_MARKBOX, (viMarkSymbol & MARK_BOX));
  524. CheckDlgButton( hwnd, IDCN_MARKPARENTHESES, (viMarkSymbol & MARK_PARENTHESES));
  525. CheckDlgButton( hwnd, IDCN_MARKCIRCLE, (viMarkSymbol & MARK_CIRCLE));
  526. CheckDlgButton( hwnd, IDCN_MARKCROSS, (viMarkSymbol & MARK_CROSS));
  527. CheckDlgButton( hwnd, IDCN_MARKUNDERSCORE, (viMarkSymbol & MARK_UNDERSCORE));
  528. CalSetFocus (GetDlgItem (hwnd, IDCN_MARKBOX));
  529. return FALSE;
  530. case WM_COMMAND:
  531. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  532. case IDOK:
  533. viMarkSymbol = 0; /* clear existing bit pattern. This
  534. is done so that only the marks specified
  535. in dialog will appear on current day */
  536. /* bits corresp. to selected mark symbols are set in MarkSymbol */
  537. if (IsDlgButtonChecked(hwnd, IDCN_MARKBOX))
  538. viMarkSymbol |= MARK_BOX;
  539. if (IsDlgButtonChecked(hwnd, IDCN_MARKPARENTHESES))
  540. viMarkSymbol |= MARK_PARENTHESES;
  541. if (IsDlgButtonChecked(hwnd, IDCN_MARKCIRCLE))
  542. viMarkSymbol |= MARK_CIRCLE;
  543. if (IsDlgButtonChecked(hwnd, IDCN_MARKCROSS))
  544. viMarkSymbol |= MARK_CROSS;
  545. if (IsDlgButtonChecked(hwnd, IDCN_MARKUNDERSCORE))
  546. viMarkSymbol |= MARK_UNDERSCORE;
  547. EndDialog (hwnd, TRUE);
  548. break;
  549. case IDCANCEL:
  550. EndDialog (hwnd, FALSE);
  551. break;
  552. default :
  553. return FALSE;
  554. } /* switch wParam */
  555. break;
  556. default :
  557. return FALSE;
  558. } /* switch message */
  559. return TRUE;
  560. } /* FnMark */
  561. /**** AlertBox */
  562. INT APIENTRY AlertBox (
  563. CHAR *szText1,
  564. CHAR *szText2,
  565. UINT wStyle)
  566. {
  567. CHAR szMessage [160+128];
  568. register CHAR *pch;
  569. register HWND hwnd;
  570. MergeStrings(szText1, szText2, szMessage);
  571. MessageBeep (wStyle);
  572. /* The parent window is the active dialog if there is one. If no
  573. active dialog, the parent window is Calendar's tiled window.
  574. */
  575. if ((hwnd = vhwndDialog) == NULL)
  576. hwnd = vhwnd0;
  577. return (MessageBox (hwnd, szMessage, vszCalendar, wStyle));
  578. }
  579. /**** Scan sz1 for merge spec. If found, insert string sz2 at that point.
  580. Then append rest of sz1 NOTE! Merge spec guaranteed to be two chars.
  581. returns TRUE if it does a merge, false otherwise. */
  582. BOOL APIENTRY MergeStrings(
  583. CHAR *szSrc,
  584. CHAR *szMerge,
  585. CHAR *szDst)
  586. {
  587. register CHAR *pchSrc;
  588. register CHAR *pchDst;
  589. pchSrc = szSrc;
  590. pchDst = szDst;
  591. #ifdef DBCS
  592. /* Find merge spec if there is one. */
  593. //- Merge Bytes: Changed to string to avoid word boundry crossing.
  594. while (*pchSrc != *vszMergeStr || *(pchSrc + 1) != *(vszMergeStr + 1))
  595. {
  596. if( IsDBCSLeadByte( *pchSrc ) )
  597. *pchDst++ = *pchSrc++;
  598. *pchDst++ = *pchSrc;
  599. /* If we reach end of string before merge spec, just return. */
  600. if(!*pchSrc++)
  601. return FALSE;
  602. }
  603. #else
  604. /* Find merge spec if there is one. */
  605. //- Merge Bytes: Changed to string to avoid word boundry crossing.
  606. while (*pchSrc != *vszMergeStr || *(pchSrc + 1) != *(vszMergeStr + 1))
  607. {
  608. *pchDst++ = *pchSrc;
  609. /* If we reach end of string before merge spec, just return. */
  610. if (!*pchSrc++)
  611. return FALSE;
  612. }
  613. #endif
  614. /* If merge spec found, insert sz2 there. (check for null merge string */
  615. if (szMerge)
  616. while (*szMerge)
  617. *pchDst++ = *szMerge++;
  618. /* Jump over merge spec */
  619. pchSrc++,pchSrc++;
  620. /* Now append rest of Src String */
  621. while (*pchDst++ = *pchSrc++);
  622. return TRUE;
  623. }
  624. /**** If sz does not have extension, append ".TXT" */
  625. VOID APIENTRY AddDefExt (LPSTR sz)
  626. {
  627. LPSTR pch1;
  628. register INT ch;
  629. pch1 = sz + lstrlen(sz);
  630. while ((ch = *pch1) != '.' && ch != '\\' && ch != ':' && pch1 > sz)
  631. pch1 = AnsiPrev(sz, pch1);
  632. if (*pch1 != '.')
  633. lstrcat(sz, vrgsz[IDS_FILEEXTENSION]);
  634. }
  635. /**** CheckButtonEnable - Enable specified button if edit field not null,
  636. disable the button if the edit field is null.
  637. */
  638. VOID APIENTRY CheckButtonEnable (
  639. HWND hwnd,
  640. INT idButton,
  641. WORD message)
  642. {
  643. if (message == EN_CHANGE)
  644. {
  645. EnableWindow (GetDlgItem (hwnd, idButton),
  646. (BOOL)(SendMessage (GetDlgItem (hwnd, IDCN_EDIT),
  647. WM_GETTEXTLENGTH, 0, 0L)));
  648. }
  649. }
  650. /* FCheckSave - if the calendar is dirty see if the user wants to Save the
  651. the changes.
  652. */
  653. BOOL APIENTRY FCheckSave (BOOL fSysModal)
  654. {
  655. /* Force current edits to be recorded right away since this may cause
  656. the file to be dirty.
  657. */
  658. RecordEdits ();
  659. if (vfDirty)
  660. {
  661. /* if file has been opened as read only, warn user and return */
  662. if (vfOpenFileReadOnly)
  663. {
  664. AlertBox (vszFileReadOnly, (CHAR *)NULL, MB_APPLMODAL|MB_OK|
  665. MB_ICONEXCLAMATION);
  666. /* Force the Save As dialog letting user save under a
  667. * different name, thus not losing changes. */
  668. CallSaveAsDialog();
  669. return (TRUE);
  670. }
  671. switch (AlertBox (vszSaveChanges, vszFileSpec,
  672. (fSysModal ? MB_SYSTEMMODAL : MB_APPLMODAL) | MB_YESNOCANCEL
  673. | MB_ICONEXCLAMATION))
  674. {
  675. case IDYES:
  676. if (vfOriginalFile)
  677. return (FSaveFile (vszFileSpec, TRUE));
  678. else
  679. return CallSaveAsDialog();
  680. case IDCANCEL:
  681. return (FALSE);
  682. /* The IDNO case falls through to return TRUE. */
  683. }
  684. }
  685. return (TRUE);
  686. }
  687. /**** RecordEdits - if the notes or the appointment description edit
  688. control has the focus, record the contents of the edit control
  689. without changing the focus.
  690. */
  691. VOID APIENTRY RecordEdits ()
  692. {
  693. register HWND hwndFocus;
  694. if ((hwndFocus = GetFocus ()) == vhwnd2C)
  695. StoreNotes ();
  696. else if (hwndFocus == vhwnd3)
  697. StoreQd ();
  698. }
  699. /**** Display error when user types date or time in wrong Format */
  700. VOID APIENTRY DateTimeAlert(
  701. BOOL fDate,
  702. INT iErr)
  703. {
  704. CHAR sz[256];
  705. CHAR *pch1;
  706. CHAR *pch2 = 0;
  707. DOSDATE dd;
  708. switch (iErr)
  709. {
  710. /* Range error only occurs for dates */
  711. case PD_ERRRANGE:
  712. pch1 = vrgsz[IDS_DATERANGE];
  713. break;
  714. case PD_ERRSUBRANGE:
  715. pch1 = vrgsz[fDate ? IDS_DATESUBRANGE : IDS_TIMESUBRANGE];
  716. break;
  717. case PD_ERRFORMAT:
  718. pch1 = fDate ? vrgsz[IDS_BADDATE] : vrgsz[IDS_BADTIME];
  719. pch2 = sz;
  720. if (fDate)
  721. {
  722. dd.month = vd3Sel.wMonth + 1;
  723. dd.day = vd3Sel.wDay + 1;
  724. dd.year = vd3Sel.wYear + 1980;
  725. GetDateString(&dd, pch2, GDS_SHORT);
  726. }
  727. else
  728. GetTimeSz(vftCur.tm, pch2);
  729. break;
  730. }
  731. AlertBox (pch1, pch2, MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION);
  732. }