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.
607 lines
16 KiB
607 lines
16 KiB
/************************************************************/
|
|
/* 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
|
|
}
|
|
|