/************************************************************/ /* Windows Write, Copyright 1985-1992 Microsoft Corporation */ /************************************************************/ #define NOGDICAPMASKS #define NORASTEROPS #define NOVIRTUALKEYCODES #define NOWINSTYLES #define NOCLIPBOARD #define NOGDI #define NOSCROLL #define NOOPENFILE #define NOWNDCLASS #define NOSYSMETRICS #define NOTEXTMETRIC #define NOICON #define NOSHOWWINDOW #define NOATOM #define NOBITMAP #define NOPEN #define NOBRUSH #define NODRAWTEXT #define NOFONT #define NOMETAFILE #define NOSOUND #define NOCOLOR #define NOCOMM #include #include "mw.h" #include "cmddefs.h" #include "str.h" #include "editdefs.h" #define NOKCCODES #include "ch.h" #include "dlgdefs.h" /*extern int idstrUndoBase;*/ extern struct UAB vuab; extern int vfCursorVisible; extern HCURSOR vhcArrow; #ifdef BOGUS /* use WPwFromItW3Id */ BOOL FValidIntFromDlg(hDlg, idi, fSigned, wMin, wMax, pw, idpmt) HANDLE hDlg; /* handle to dialog box */ int idi; /* id of control in dialog box */ BOOL fSigned; /* check for sign if true */ int wMin, wMax; /* range of valid integer value */ int * pw; /* location to put the int */ int idpmt; /* error message number */ { REG1 int wVal; BOOL fValOk; *pw = wVal = GetDlgItemInt(hDlg, idi, (BOOL far *)&fValOk, fSigned); if (fValOk) { /* check range */ if ((wVal < wMin) || (wVal > wMax)) fValOk = false; } if (!fValOk) { Error(idpmt); SelectIdiText(hDlg, idi); SetFocus(GetDlgItem(hDlg, idi)); } return fValOk; } /* FValidIntFromDlg */ #endif FPwPosIt(pw, hDlg, it) HWND hDlg; /* handle to desired dialog box */ int *pw; int it; { /*------------------------------------------------------------------- Purpose: Positive integer dialog item. --------------------------------------------------------------mck--*/ return(WPwFromItW3IdFUt(pw, hDlg, it, 0, 32767, wNormal, IDPMTNPI, fFalse, 0)); } WPwFromItW3Id(pw, hDlg, it, wMin, wMax, wMask, id) HWND hDlg; /* handle to desired dialog box */ int *pw; /* Return value */ int it; /* Item number */ int wMin; /* Smallest and largest allowed values */ int wMax; int wMask; /* Bit mask for allowed variations */ int id; /* Id of error string if bad */ { /*------------------------------------------------------------------- Purpose: General integer dialog item. --------------------------------------------------------------mck--*/ return(WPwFromItW3IdFUt(pw, hDlg, it, wMin, wMax, wMask, id, fFalse, 0)); } FPdxaPosIt(pdxa, hDlg, it) HWND hDlg; /* handle to desired dialog box */ int *pdxa; int it; { /*------------------------------------------------------------------- Purpose: Positive dxa dialog item. --------------------------------------------------------------mck--*/ extern int utCur; return(WPwFromItW3IdFUt(pdxa, hDlg, it, 0, 32767, wNormal, IDPMTNPDXA, fTrue, utCur)); } FPdxaPosBIt(pdxa, hDlg, it) HWND hDlg; /* handle to desired dialog box */ int *pdxa; int it; { /*------------------------------------------------------------------- Purpose: Positive dxa dialog item (blank allowed). --------------------------------------------------------------mck--*/ extern int utCur; return(WPwFromItW3IdFUt(pdxa, hDlg, it, 0, 32767, wBlank | wSpaces, IDPMTNPDXA, fTrue, utCur)); } WPdxaFromItDxa2WId(pdxa, hDlg, it, dxaMin, dxaMax, wMask, id) HWND hDlg; /* handle to desired dialog box */ int *pdxa; /* Return value */ int it; /* Dialog item number */ int dxaMin; /* Range of allowable measurements */ int dxaMax; int wMask; /* Bit mask for allowed variations */ int id; /* Error id */ { /*------------------------------------------------------------------- Purpose: General dxa dialog item. --------------------------------------------------------------mck--*/ extern int utCur; return(WPwFromItW3IdFUt(pdxa, hDlg, it, dxaMin, dxaMax, wMask, id, fTrue, utCur)); } WPwFromItW3IdFUt(pw, hDlg, it, wMin, wMax, wMask, id, fDxa, ut) int *pw; /* Return value */ HWND hDlg; /* handle to desired dialog box */ int it; /* Item number */ int wMin; /* Smallest and largest allowed values */ int wMax; int wMask; /* Bit mask for allowed variations */ int id; /* Id of error string if out of range */ int fDxa; /* Parse as dxa (otherwise int) */ int ut; /* Units to use as default if fDxa */ { /*------------------------------------------------------------------- Purpose: Parse the item in the current dialog. Must be a valid integer or dxa in the given range. Method: - Get the text string. - Try parse as "". - Try parse as string of all spaces - Parse as a int/dxa (generic error if can't). - Test for ".5". - Compare with min and max. - Try parse as "Auto". - If out of bounds, use id to put up specific error (with strings of min and max as parameters). Returns: The return value may be used as a boolean or as a word. fFalse (0) -> not parsed wNormal (1) -> parsed normally wBlank (2) -> parsed a null line (*pw is valNil) wAuto (4) -> parsed as "Auto" (*pw is 0) wSpaces (16) -> parsed a line of all spaces (*pw is valNil) !fDxa only: wDouble (8) -> parsed with ".5" trailing Note: The interval [wMin..wMax] is closed. Note: Return value is doubld the parsed value when wDouble. Note: When wDouble, 2*wMin and 2*wMax must be valid ints. Note: Numbers ending in .5 may have no trailing spaces. History: 6/18/86: Adapted for trailing kanji spaces --- yxy 07/03/85: Added wSpaces return 10/23/84: Fixed wAuto to return with *pw == 0. 10/ 5/84: Added ut parameter. 10/ 5/84: Added wMask and combined dxa and w parsing. 9/26/84: Created. --------------------------------------------------------------mck--*/ CHAR *pch; /* Parse pointer */ CHAR *pchEnd; /* End of buffer */ CHAR *pchError; /* Position of parse error */ int fParsed; /* Parses as number/dxa */ int fOverflow = fFalse; /* True if the number is parsed but it overflow */ int wGood = wNormal;/* return after good range check */ CHAR stItem[32]; #ifdef AUTO_SPACING CHAR szAuto[32]; /* Hold "Auto" string */ #endif /* Get the dialog text */ stItem[0] = GetDlgItemText(hDlg, it, (LPSTR)&stItem[1], sizeof(stItem)-1); /* See if blank (null line) */ if (wMask & wBlank && stItem[0] == 0) { *pw = valNil; return(wBlank); } pch = &stItem[1]; /* See if all spaces */ if (wMask & wBlank && wMask & wSpaces) { int fAllSpaces = fTrue; while (*pch != 0) if (*pch++ != ' ') { fAllSpaces = fFalse; break; } if (fAllSpaces == fTrue) { *pw = valNil; return(wSpaces); } } pch = &stItem[1]; pchEnd = pch + stItem[0]; /* It parses as a number ... */ fParsed = fDxa ? FZaFromSs(pw, stItem+1, *stItem, ut) : FPwParsePpchPch(pw, &pch, pchEnd, &fOverflow); if (!fDxa && wMask & wDouble) { (*pw) *= 2; wMin *= 2; wMax *= 2; if (!fParsed) { /* Check if ".5" was reason for bad parse. */ if (pch != pchEnd && *pch == '.') { pch++; /* Allow "ddddd.0*" */ pchError = pch; if (FAllZeroPpchPch(&pchError, pchEnd)) fParsed = fTrue; /* Allow "ddddd.50*" */ else if (pch != pchEnd && *pch == '5' && (pch++, FAllZeroPpchPch(&pch, pchEnd))) { (*pw)++; fParsed = fTrue; wGood = wDouble; } /* Mark furthest error condition */ else if (pchError > pch) pch = pchError; } } } if (fParsed && !fOverflow) { /* ... and in range */ if (*pw >= wMin && *pw <= wMax) return(wGood); #ifdef ENABLE /* ... but out of range - no matter what, we will use the supplied id for the error message to be consistant */ else { SelectIdiText(hDlg, it); SetFocus(GetDlgItem(hDlg, it)); Error(id); return(fFalse); } #endif /* ENABLE */ } #ifdef AUTO_SPACING /* Invariant: Field does not parse as a number */ /* Try "Auto" */ if (wMask & wAuto) { pch = PchFillPchId(szAuto, IDSTRVaries, sizeof(szAuto)); *pch = '\0'; stItem[stItem[0]+1] = '\0'; if (WCompSz(szAuto, &stItem[1]) == 0) { *pw = 0; return(wAuto); } } #endif /* AUTO_SPACING */ /* All attempts failed - show user where he went wrong vis the attempted number parse. */ { unsigned cchStart = fParsed ? 0 : pch - &stItem[1]; unsigned cchEnd = 32767; int idError = fDxa ? IDPMTNOTDXA : IDPMTNOTNUM; if (fParsed) idError = id; /* reset idError if we just overflow or fail the range test */ SendDlgItemMessage(hDlg, it, EM_SETSEL, (WORD)NULL, MAKELONG(cchStart, cchEnd)); SetFocus(GetDlgItem(hDlg, it)); Error(idError); return(fFalse); } } FAllZeroPpchPch(ppch, pchMax) CHAR **ppch; /* Bound of character buffer */ CHAR *pchMax; { /*------------------------------------------------------------------- Purpose: Make sure all characters in buffer are spaces or 0's. Returns: *ppch contains first bad character if fFalse returned. History: 6/18/86: Adapted for Kanji chars --- yxy 10/ 9/84: Created. --------------------------------------------------------------mck--*/ CHAR *pch = *ppch; while (pch < pchMax) { if (*pch == '0' || *pch == ' ') pch++; else { *ppch = pch; return(fFalse); } } return(fTrue); } FPwParsePpchPch(pw, ppch, pchMax, pfOverflow) int *pw; CHAR **ppch; CHAR *pchMax; int *pfOverflow; { /*------------------------------------------------------------------- Purpose: Parse a number in the given buffer. Method: Scan for digits and ignore white space. Returns: Character pointer past last one read in *ppch. Number parsed is returned. Note that if only a prefix is a valid number we return false, with *ppch set to the first offending character. Modification History: 06/18/86 ---- Adapted for a kanji space char. --- yxy --------------------------------------------------------------mck--*/ #define smInit 0 #define smDig 1 #define smBody 2 CHAR *pch = *ppch; /* Local buffer pointer */ unsigned int ch; /* Character being examined */ int fNeg = fFalse; DWORD dwNum = 0L; int fError = fFalse; int sm = smInit; *pfOverflow = fFalse; while (!fError && !(*pfOverflow) && pch < pchMax) { ch = *pch; if (ch == chSpace) pch++; else switch (sm) { case smInit: if (ch == '-') { fNeg = fTrue; pch++; } sm = smDig; break; case smDig: if (isdigit(ch)) sm = smBody; else fError = fTrue; break; case smBody: if (isdigit(ch)) { /* Overflow? */ if ((dwNum = 10*dwNum + WFromCh(ch)) > 0x7FFF) *pfOverflow = fTrue; else pch++; } else fError = fTrue; break; } } *ppch = pch; *pw = (int)(fNeg ? -dwNum : dwNum); return(!fError); } EnableOtherModeless(fEnable) BOOL fEnable; { extern HWND vhDlgChange; extern HWND vhDlgFind; extern HWND vhDlgRunningHead; /* Disable or enable other modeless dialog boxes according to fEnable */ if (IsWindow(vhDlgFind)) { EnableWindow(vhDlgFind, fEnable); } if (IsWindow(vhDlgChange)) { EnableWindow(vhDlgChange, fEnable); } if (IsWindow(vhDlgRunningHead)) { EnableWindow(vhDlgRunningHead, fEnable); } } SelectIdiText(hDlg, idi) HWND hDlg; int idi; { /* For the dialog box with handle hDlg, highlight the text of the control with ID idi */ unsigned cchStart = 0; unsigned cchEnd = 0x7fff; SendDlgItemMessage(hDlg, idi, EM_SETSEL, (WORD)NULL, MAKELONG(cchStart, cchEnd)); } /* end of SelectIdiText */ #ifdef ENABLE SetRgvalAgain(rgvalLocal, uac) VAL rgvalLocal[]; int uac; { extern VAL rgvalAgain[]; blt(rgvalLocal, rgvalAgain, ivalMax * cwVal); switch (vuab.uac = uac) { case uacFormatPara: case uacFormatChar: case uacFormatSection: /* idstrUndoBase = IDSTRUndoBase;*/ /* SetUndoMenuStr(IDSTRUndoCom);*/ SetUndoMenuStr(IDSTRUndoBase); break; } } #endif #ifdef CASHMERE PushRadioButton(hDlg, idiFirst, idiLast, idiPushed) HWND hDlg; int idiFirst, idiLast, idiPushed; { /* Push radio button idiPushed and unpush all others in the radio group bounded by idiFirst and idiLast. */ int idi; for (idi = idiFirst; idi <= idiLast; idi++) CheckDlgButton(hDlg, idi, idi == idiPushed); } SetRadValue(hDlg, idiFirst, idiLast, idiRad) HWND hDlg; int idiFirst, idiLast, idiRad; { /* Set the (zero-based) idiRad'th item in the radio group bounded by idiFirst and idiLast. */ PushRadioButton(hDlg, idiFirst, idiLast, idiFirst + idiRad); } #endif /* CASHMERE */ #ifdef ENABLE BOOL far PASCAL DialogConfirm(hDlg, message, wParam, lParam) HWND hDlg; unsigned message; WORD wParam; LONG lParam; { /* This is the Dialog function for all dialog boxes with only "Yes", "No", and "Cancel" boxes; this includes: Save Large Scrap */ extern HWND vhWndMsgBoxParent; switch (message) { case WM_INITDIALOG: EnableOtherModeless(FALSE); break; case WM_SETVISIBLE: if (wParam) EndLongOp(vhcArrow); return(FALSE); case WM_ACTIVATE: if (wParam) { vhWndMsgBoxParent = hDlg; } if (vfCursorVisible) ShowCursor(wParam); return(FALSE); /* so that we leave the activate message to the dialog manager to take care of setting the focus correctly */ case WM_COMMAND: switch (wParam) { /* The default button is NO, make sure the call routine realized that idiOk should be treated as idiNo. */ case idiOk: case idiCancel: case idiYes: case idiNo: OurEndDialog(hDlg, wParam); break; default: Assert(FALSE); break; } break; default: return(FALSE); } return(TRUE); } /* end of DialogConfirm */ #endif /* ENABLE */ #ifndef WIN30 /* DialogBox has been fixed so it automatically brings up the hourglass! */ OurDialogBox(hInst, lpstr, hWndParent, lpProc) HANDLE hInst; LPSTR lpstr; HWND hWndParent; FARPROC lpProc; { StartLongOp(); return(DialogBox(hInst, lpstr, hWndParent, lpProc)); } #endif OurEndDialog(hDlg, wParam) { /* This routine does the same standard things Write does everytime it closes a dialog box. */ extern HWND hParentWw; extern long ropErase; extern HWND vhWndMsgBoxParent; extern HCURSOR vhcIBeam; RECT rc; POINT pt; #ifdef NO_NEW_CALL /* Close down the dialog box and erase it from the screen. We tried to let Windows do the erasing, but... Its a long story. */ GetWindowRect(hDlg, (LPRECT)&rc); pt.x = pt.y = 0; ClientToScreen(hParentWw, (LPPOINT)&pt); #endif EndDialog(hDlg, wParam); #ifdef NO_NEW_CALL PatBlt(GetDC(hParentWw), rc.left - pt.x, rc.top - pt.y, rc.right - rc.left, rc.bottom - rc.top, ropErase); #endif /* Enable any existing dialog boxes and indicate that any error messages belong to the document window. */ EnableOtherModeless(TRUE); vhWndMsgBoxParent = (HWND)NULL; #ifndef WIN30 EndLongOp(vhcIBeam); /* See StartLongOp() above */ #endif }