607 lines
15 KiB
C
607 lines
15 KiB
C
/************************************************************/
|
||
/* 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
|
||
}
|
||
|