windows-nt/Source/XPSP1/NT/base/mvdm/wow16/write/diasubs.c
2020-09-26 16:20:57 +08:00

607 lines
15 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/************************************************************/
/* 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 <windows.h>
#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
}