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.

606 lines
15 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. #define NOGDICAPMASKS
  5. #define NORASTEROPS
  6. #define NOVIRTUALKEYCODES
  7. #define NOWINSTYLES
  8. #define NOCLIPBOARD
  9. #define NOGDI
  10. #define NOSCROLL
  11. #define NOOPENFILE
  12. #define NOWNDCLASS
  13. #define NOSYSMETRICS
  14. #define NOTEXTMETRIC
  15. #define NOICON
  16. #define NOSHOWWINDOW
  17. #define NOATOM
  18. #define NOBITMAP
  19. #define NOPEN
  20. #define NOBRUSH
  21. #define NODRAWTEXT
  22. #define NOFONT
  23. #define NOMETAFILE
  24. #define NOSOUND
  25. #define NOCOLOR
  26. #define NOCOMM
  27. #include <windows.h>
  28. #include "mw.h"
  29. #include "cmddefs.h"
  30. #include "str.h"
  31. #include "editdefs.h"
  32. #define NOKCCODES
  33. #include "ch.h"
  34. #include "dlgdefs.h"
  35. /*extern int idstrUndoBase;*/
  36. extern struct UAB vuab;
  37. extern int vfCursorVisible;
  38. extern HCURSOR vhcArrow;
  39. #ifdef BOGUS /* use WPwFromItW3Id */
  40. BOOL FValidIntFromDlg(hDlg, idi, fSigned, wMin, wMax, pw, idpmt)
  41. HANDLE hDlg; /* handle to dialog box */
  42. int idi; /* id of control in dialog box */
  43. BOOL fSigned; /* check for sign if true */
  44. int wMin, wMax; /* range of valid integer value */
  45. int * pw; /* location to put the int */
  46. int idpmt; /* error message number */
  47. {
  48. REG1 int wVal;
  49. BOOL fValOk;
  50. *pw = wVal = GetDlgItemInt(hDlg, idi, (BOOL far *)&fValOk, fSigned);
  51. if (fValOk)
  52. { /* check range */
  53. if ((wVal < wMin) || (wVal > wMax))
  54. fValOk = false;
  55. }
  56. if (!fValOk)
  57. {
  58. Error(idpmt);
  59. SelectIdiText(hDlg, idi);
  60. SetFocus(GetDlgItem(hDlg, idi));
  61. }
  62. return fValOk;
  63. } /* FValidIntFromDlg */
  64. #endif
  65. FPwPosIt(pw, hDlg, it)
  66. HWND hDlg; /* handle to desired dialog box */
  67. int *pw;
  68. int it;
  69. {
  70. /*-------------------------------------------------------------------
  71. Purpose: Positive integer dialog item.
  72. --------------------------------------------------------------mck--*/
  73. return(WPwFromItW3IdFUt(pw, hDlg, it, 0, 32767, wNormal, IDPMTNPI, fFalse, 0));
  74. }
  75. WPwFromItW3Id(pw, hDlg, it, wMin, wMax, wMask, id)
  76. HWND hDlg; /* handle to desired dialog box */
  77. int *pw; /* Return value */
  78. int it; /* Item number */
  79. int wMin; /* Smallest and largest allowed values */
  80. int wMax;
  81. int wMask; /* Bit mask for allowed variations */
  82. int id; /* Id of error string if bad */
  83. {
  84. /*-------------------------------------------------------------------
  85. Purpose: General integer dialog item.
  86. --------------------------------------------------------------mck--*/
  87. return(WPwFromItW3IdFUt(pw, hDlg, it, wMin, wMax, wMask, id, fFalse, 0));
  88. }
  89. FPdxaPosIt(pdxa, hDlg, it)
  90. HWND hDlg; /* handle to desired dialog box */
  91. int *pdxa;
  92. int it;
  93. {
  94. /*-------------------------------------------------------------------
  95. Purpose: Positive dxa dialog item.
  96. --------------------------------------------------------------mck--*/
  97. extern int utCur;
  98. return(WPwFromItW3IdFUt(pdxa, hDlg, it, 0, 32767, wNormal, IDPMTNPDXA, fTrue, utCur));
  99. }
  100. FPdxaPosBIt(pdxa, hDlg, it)
  101. HWND hDlg; /* handle to desired dialog box */
  102. int *pdxa;
  103. int it;
  104. {
  105. /*-------------------------------------------------------------------
  106. Purpose: Positive dxa dialog item (blank allowed).
  107. --------------------------------------------------------------mck--*/
  108. extern int utCur;
  109. return(WPwFromItW3IdFUt(pdxa, hDlg, it, 0, 32767, wBlank | wSpaces, IDPMTNPDXA, fTrue, utCur));
  110. }
  111. WPdxaFromItDxa2WId(pdxa, hDlg, it, dxaMin, dxaMax, wMask, id)
  112. HWND hDlg; /* handle to desired dialog box */
  113. int *pdxa; /* Return value */
  114. int it; /* Dialog item number */
  115. int dxaMin; /* Range of allowable measurements */
  116. int dxaMax;
  117. int wMask; /* Bit mask for allowed variations */
  118. int id; /* Error id */
  119. {
  120. /*-------------------------------------------------------------------
  121. Purpose: General dxa dialog item.
  122. --------------------------------------------------------------mck--*/
  123. extern int utCur;
  124. return(WPwFromItW3IdFUt(pdxa, hDlg, it, dxaMin, dxaMax, wMask, id, fTrue, utCur));
  125. }
  126. WPwFromItW3IdFUt(pw, hDlg, it, wMin, wMax, wMask, id, fDxa, ut)
  127. int *pw; /* Return value */
  128. HWND hDlg; /* handle to desired dialog box */
  129. int it; /* Item number */
  130. int wMin; /* Smallest and largest allowed values */
  131. int wMax;
  132. int wMask; /* Bit mask for allowed variations */
  133. int id; /* Id of error string if out of range */
  134. int fDxa; /* Parse as dxa (otherwise int) */
  135. int ut; /* Units to use as default if fDxa */
  136. {
  137. /*-------------------------------------------------------------------
  138. Purpose: Parse the item in the current dialog. Must be a valid
  139. integer or dxa in the given range.
  140. Method: - Get the text string.
  141. - Try parse as "".
  142. - Try parse as string of all spaces
  143. - Parse as a int/dxa (generic error if can't).
  144. - Test for ".5".
  145. - Compare with min and max.
  146. - Try parse as "Auto".
  147. - If out of bounds, use id to put up specific error
  148. (with strings of min and max as parameters).
  149. Returns: The return value may be used as a boolean or as a word.
  150. fFalse (0) -> not parsed
  151. wNormal (1) -> parsed normally
  152. wBlank (2) -> parsed a null line
  153. (*pw is valNil)
  154. wAuto (4) -> parsed as "Auto" (*pw is 0)
  155. wSpaces (16) -> parsed a line of all
  156. spaces (*pw is valNil)
  157. !fDxa only:
  158. wDouble (8) -> parsed with ".5" trailing
  159. Note: The interval [wMin..wMax] is closed.
  160. Note: Return value is doubld the parsed value when wDouble.
  161. Note: When wDouble, 2*wMin and 2*wMax must be valid ints.
  162. Note: Numbers ending in .5 may have no trailing spaces.
  163. History:
  164. 6/18/86: Adapted for trailing kanji spaces --- yxy
  165. 07/03/85: Added wSpaces return
  166. 10/23/84: Fixed wAuto to return with *pw == 0.
  167. 10/ 5/84: Added ut parameter.
  168. 10/ 5/84: Added wMask and combined dxa and w parsing.
  169. 9/26/84: Created.
  170. --------------------------------------------------------------mck--*/
  171. CHAR *pch; /* Parse pointer */
  172. CHAR *pchEnd; /* End of buffer */
  173. CHAR *pchError; /* Position of parse error */
  174. int fParsed; /* Parses as number/dxa */
  175. int fOverflow = fFalse; /* True if the number is parsed but it overflow */
  176. int wGood = wNormal;/* return after good range check */
  177. CHAR stItem[32];
  178. #ifdef AUTO_SPACING
  179. CHAR szAuto[32]; /* Hold "Auto" string */
  180. #endif
  181. /* Get the dialog text */
  182. stItem[0] = GetDlgItemText(hDlg, it, (LPSTR)&stItem[1], sizeof(stItem)-1);
  183. /* See if blank (null line) */
  184. if (wMask & wBlank && stItem[0] == 0)
  185. {
  186. *pw = valNil;
  187. return(wBlank);
  188. }
  189. pch = &stItem[1];
  190. /* See if all spaces */
  191. if (wMask & wBlank && wMask & wSpaces)
  192. {
  193. int fAllSpaces = fTrue;
  194. while (*pch != 0)
  195. if (*pch++ != ' ')
  196. {
  197. fAllSpaces = fFalse;
  198. break;
  199. }
  200. if (fAllSpaces == fTrue)
  201. {
  202. *pw = valNil;
  203. return(wSpaces);
  204. }
  205. }
  206. pch = &stItem[1];
  207. pchEnd = pch + stItem[0];
  208. /* It parses as a number ... */
  209. fParsed = fDxa ? FZaFromSs(pw, stItem+1, *stItem, ut)
  210. : FPwParsePpchPch(pw, &pch, pchEnd, &fOverflow);
  211. if (!fDxa && wMask & wDouble)
  212. {
  213. (*pw) *= 2;
  214. wMin *= 2;
  215. wMax *= 2;
  216. if (!fParsed)
  217. {
  218. /* Check if ".5" was reason for bad parse. */
  219. if (pch != pchEnd && *pch == '.')
  220. {
  221. pch++;
  222. /* Allow "ddddd.0*" */
  223. pchError = pch;
  224. if (FAllZeroPpchPch(&pchError, pchEnd))
  225. fParsed = fTrue;
  226. /* Allow "ddddd.50*" */
  227. else if (pch != pchEnd && *pch == '5' &&
  228. (pch++, FAllZeroPpchPch(&pch, pchEnd)))
  229. {
  230. (*pw)++;
  231. fParsed = fTrue;
  232. wGood = wDouble;
  233. }
  234. /* Mark furthest error condition */
  235. else if (pchError > pch)
  236. pch = pchError;
  237. }
  238. }
  239. }
  240. if (fParsed && !fOverflow)
  241. {
  242. /* ... and in range */
  243. if (*pw >= wMin && *pw <= wMax)
  244. return(wGood);
  245. #ifdef ENABLE
  246. /* ... but out of range - no matter what, we will use the supplied
  247. id for the error message to be consistant */
  248. else
  249. {
  250. SelectIdiText(hDlg, it);
  251. SetFocus(GetDlgItem(hDlg, it));
  252. Error(id);
  253. return(fFalse);
  254. }
  255. #endif /* ENABLE */
  256. }
  257. #ifdef AUTO_SPACING
  258. /* Invariant: Field does not parse as a number */
  259. /* Try "Auto" */
  260. if (wMask & wAuto)
  261. {
  262. pch = PchFillPchId(szAuto, IDSTRVaries, sizeof(szAuto));
  263. *pch = '\0';
  264. stItem[stItem[0]+1] = '\0';
  265. if (WCompSz(szAuto, &stItem[1]) == 0)
  266. {
  267. *pw = 0;
  268. return(wAuto);
  269. }
  270. }
  271. #endif /* AUTO_SPACING */
  272. /* All attempts failed - show user where he went wrong vis the attempted
  273. number parse. */
  274. {
  275. unsigned cchStart = fParsed ? 0 : pch - &stItem[1];
  276. unsigned cchEnd = 32767;
  277. int idError = fDxa ? IDPMTNOTDXA : IDPMTNOTNUM;
  278. if (fParsed)
  279. idError = id; /* reset idError if we just overflow or fail the range test */
  280. SendDlgItemMessage(hDlg, it, EM_SETSEL, (WORD)NULL, MAKELONG(cchStart, cchEnd));
  281. SetFocus(GetDlgItem(hDlg, it));
  282. Error(idError);
  283. return(fFalse);
  284. }
  285. }
  286. FAllZeroPpchPch(ppch, pchMax)
  287. CHAR **ppch; /* Bound of character buffer */
  288. CHAR *pchMax;
  289. {
  290. /*-------------------------------------------------------------------
  291. Purpose: Make sure all characters in buffer are spaces or 0's.
  292. Returns: *ppch contains first bad character if fFalse returned.
  293. History:
  294. 6/18/86: Adapted for Kanji chars --- yxy
  295. 10/ 9/84: Created.
  296. --------------------------------------------------------------mck--*/
  297. CHAR *pch = *ppch;
  298. while (pch < pchMax) {
  299. if (*pch == '0' || *pch == ' ')
  300. pch++;
  301. else {
  302. *ppch = pch;
  303. return(fFalse);
  304. }
  305. }
  306. return(fTrue);
  307. }
  308. FPwParsePpchPch(pw, ppch, pchMax, pfOverflow)
  309. int *pw;
  310. CHAR **ppch;
  311. CHAR *pchMax;
  312. int *pfOverflow;
  313. {
  314. /*-------------------------------------------------------------------
  315. Purpose: Parse a number in the given buffer.
  316. Method: Scan for digits and ignore white space.
  317. Returns: Character pointer past last one read in *ppch.
  318. Number parsed is returned. Note that if only a prefix is
  319. a valid number we return false, with *ppch set to the
  320. first offending character.
  321. Modification History:
  322. 06/18/86 ---- Adapted for a kanji space char. --- yxy
  323. --------------------------------------------------------------mck--*/
  324. #define smInit 0
  325. #define smDig 1
  326. #define smBody 2
  327. CHAR *pch = *ppch; /* Local buffer pointer */
  328. unsigned int ch; /* Character being examined */
  329. int fNeg = fFalse;
  330. DWORD dwNum = 0L;
  331. int fError = fFalse;
  332. int sm = smInit;
  333. *pfOverflow = fFalse;
  334. while (!fError && !(*pfOverflow) && pch < pchMax) {
  335. ch = *pch;
  336. if (ch == chSpace)
  337. pch++;
  338. else
  339. switch (sm) {
  340. case smInit:
  341. if (ch == '-') {
  342. fNeg = fTrue;
  343. pch++;
  344. }
  345. sm = smDig;
  346. break;
  347. case smDig:
  348. if (isdigit(ch))
  349. sm = smBody;
  350. else
  351. fError = fTrue;
  352. break;
  353. case smBody:
  354. if (isdigit(ch)) {
  355. /* Overflow? */
  356. if ((dwNum = 10*dwNum + WFromCh(ch)) > 0x7FFF)
  357. *pfOverflow = fTrue;
  358. else
  359. pch++;
  360. }
  361. else
  362. fError = fTrue;
  363. break;
  364. }
  365. }
  366. *ppch = pch;
  367. *pw = (int)(fNeg ? -dwNum : dwNum);
  368. return(!fError);
  369. }
  370. EnableOtherModeless(fEnable)
  371. BOOL fEnable;
  372. {
  373. extern HWND vhDlgChange;
  374. extern HWND vhDlgFind;
  375. extern HWND vhDlgRunningHead;
  376. /* Disable or enable other modeless dialog boxes according to fEnable */
  377. if (IsWindow(vhDlgFind))
  378. {
  379. EnableWindow(vhDlgFind, fEnable);
  380. }
  381. if (IsWindow(vhDlgChange))
  382. {
  383. EnableWindow(vhDlgChange, fEnable);
  384. }
  385. if (IsWindow(vhDlgRunningHead))
  386. {
  387. EnableWindow(vhDlgRunningHead, fEnable);
  388. }
  389. }
  390. SelectIdiText(hDlg, idi)
  391. HWND hDlg;
  392. int idi;
  393. { /* For the dialog box with handle hDlg, highlight the text of the control
  394. with ID idi */
  395. unsigned cchStart = 0;
  396. unsigned cchEnd = 0x7fff;
  397. SendDlgItemMessage(hDlg, idi, EM_SETSEL, (WORD)NULL, MAKELONG(cchStart, cchEnd));
  398. } /* end of SelectIdiText */
  399. #ifdef ENABLE
  400. SetRgvalAgain(rgvalLocal, uac)
  401. VAL rgvalLocal[];
  402. int uac;
  403. {
  404. extern VAL rgvalAgain[];
  405. blt(rgvalLocal, rgvalAgain, ivalMax * cwVal);
  406. switch (vuab.uac = uac)
  407. {
  408. case uacFormatPara:
  409. case uacFormatChar:
  410. case uacFormatSection:
  411. /* idstrUndoBase = IDSTRUndoBase;*/
  412. /* SetUndoMenuStr(IDSTRUndoCom);*/
  413. SetUndoMenuStr(IDSTRUndoBase);
  414. break;
  415. }
  416. }
  417. #endif
  418. #ifdef CASHMERE
  419. PushRadioButton(hDlg, idiFirst, idiLast, idiPushed)
  420. HWND hDlg;
  421. int idiFirst, idiLast, idiPushed;
  422. {
  423. /*
  424. Push radio button idiPushed and unpush all others in the radio group
  425. bounded by idiFirst and idiLast.
  426. */
  427. int idi;
  428. for (idi = idiFirst; idi <= idiLast; idi++)
  429. CheckDlgButton(hDlg, idi, idi == idiPushed);
  430. }
  431. SetRadValue(hDlg, idiFirst, idiLast, idiRad)
  432. HWND hDlg;
  433. int idiFirst, idiLast, idiRad;
  434. {
  435. /*
  436. Set the (zero-based) idiRad'th item in the radio group
  437. bounded by idiFirst and idiLast.
  438. */
  439. PushRadioButton(hDlg, idiFirst, idiLast, idiFirst + idiRad);
  440. }
  441. #endif /* CASHMERE */
  442. #ifdef ENABLE
  443. BOOL far PASCAL DialogConfirm(hDlg, message, wParam, lParam)
  444. HWND hDlg;
  445. unsigned message;
  446. WORD wParam;
  447. LONG lParam;
  448. {
  449. /* This is the Dialog function for all dialog boxes with only "Yes", "No",
  450. and "Cancel" boxes; this includes: Save Large Scrap */
  451. extern HWND vhWndMsgBoxParent;
  452. switch (message)
  453. {
  454. case WM_INITDIALOG:
  455. EnableOtherModeless(FALSE);
  456. break;
  457. case WM_SETVISIBLE:
  458. if (wParam)
  459. EndLongOp(vhcArrow);
  460. return(FALSE);
  461. case WM_ACTIVATE:
  462. if (wParam)
  463. {
  464. vhWndMsgBoxParent = hDlg;
  465. }
  466. if (vfCursorVisible)
  467. ShowCursor(wParam);
  468. return(FALSE); /* so that we leave the activate message to
  469. the dialog manager to take care of setting the focus correctly */
  470. case WM_COMMAND:
  471. switch (wParam)
  472. {
  473. /* The default button is NO, make sure the call routine realized
  474. that idiOk should be treated as idiNo. */
  475. case idiOk:
  476. case idiCancel:
  477. case idiYes:
  478. case idiNo:
  479. OurEndDialog(hDlg, wParam);
  480. break;
  481. default:
  482. Assert(FALSE);
  483. break;
  484. }
  485. break;
  486. default:
  487. return(FALSE);
  488. }
  489. return(TRUE);
  490. } /* end of DialogConfirm */
  491. #endif /* ENABLE */
  492. #ifndef WIN30
  493. /* DialogBox has been fixed so it automatically brings up the hourglass! */
  494. OurDialogBox(hInst, lpstr, hWndParent, lpProc)
  495. HANDLE hInst;
  496. LPSTR lpstr;
  497. HWND hWndParent;
  498. FARPROC lpProc;
  499. {
  500. StartLongOp();
  501. return(DialogBox(hInst, lpstr, hWndParent, lpProc));
  502. }
  503. #endif
  504. OurEndDialog(hDlg, wParam)
  505. {
  506. /* This routine does the same standard things Write does everytime it closes
  507. a dialog box. */
  508. extern HWND hParentWw;
  509. extern long ropErase;
  510. extern HWND vhWndMsgBoxParent;
  511. extern HCURSOR vhcIBeam;
  512. RECT rc;
  513. POINT pt;
  514. #ifdef NO_NEW_CALL
  515. /* Close down the dialog box and erase it from the screen. We tried to let
  516. Windows do the erasing, but... Its a long story. */
  517. GetWindowRect(hDlg, (LPRECT)&rc);
  518. pt.x = pt.y = 0;
  519. ClientToScreen(hParentWw, (LPPOINT)&pt);
  520. #endif
  521. EndDialog(hDlg, wParam);
  522. #ifdef NO_NEW_CALL
  523. PatBlt(GetDC(hParentWw), rc.left - pt.x, rc.top - pt.y, rc.right - rc.left,
  524. rc.bottom - rc.top, ropErase);
  525. #endif
  526. /* Enable any existing dialog boxes and indicate that any error messages
  527. belong to the document window. */
  528. EnableOtherModeless(TRUE);
  529. vhWndMsgBoxParent = (HWND)NULL;
  530. #ifndef WIN30
  531. EndLongOp(vhcIBeam); /* See StartLongOp() above */
  532. #endif
  533. }
  534.