NT4/private/mvdm/wow16/write/search.c
2020-09-30 17:12:29 +02:00

2016 lines
62 KiB
C

/************************************************************/
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
/************************************************************/
/* search.c Search/Replace */
/* Brodie Nov 25 83 */
/* Lipkie Nov 15 83 */
#define NOATOM
#define NOBITMAP
#define NOBRUSH
#define NOCLIPBOARD
#define NOCOLOR
#define NOCOMM
#define NOCREATESTRUCT
#define NODRAWTEXT
#define NOFONT
#define NOGDI
#define NOGDICAPMASKS
#define NOHDC
#define NOICON
#define NOKEYSTATE
#define NOMEMMGR
#define NOMENUS
#define NOMETAFILE
#define NOOPENFILE
#define NOPEN
#define NORASTEROPS
#define NORECT
#define NOREGION
#define NOSCROLL
#define NOSHOWWINDOW
#define NOSOUND
#define NOSYSCOMMANDS
#define NOSYSMETRICS
#define NOTEXTMETRIC
#define NOWH
#define NOWINSTYLES
#define NOWNDCLASS
#include <windows.h>
#define NOIDISAVEPRINT
#include "mw.h"
#include "dlgdefs.h"
#include "cmddefs.h"
#include "docdefs.h"
#include "str.h"
#define NOKCCODES
#include "ch.h"
#include "editdefs.h"
#include "propdefs.h"
#include "filedefs.h"
#include "dispdefs.h"
#include "wwdefs.h"
#include "fkpdefs.h"
#include "fmtdefs.h"
#ifdef INEFFLOCKDOWN
extern FARPROC lpDialogFind;
extern FARPROC lpDialogChange;
#else
FARPROC lpDialogFind = NULL;
FARPROC lpDialogChange = NULL;
BOOL far PASCAL DialogFind(HWND, unsigned, WORD, LONG);
BOOL far PASCAL DialogChange(HWND, unsigned, WORD, LONG);
#endif
extern HANDLE hMmwModInstance;
extern HWND vhDlgFind;
extern HWND vhDlgChange;
extern HANDLE hParentWw; /* Handle to the parent window */
extern int vfCursorVisible;
extern int vfOutOfMemory;
extern struct WWD rgwwd[];
extern int wwMac;
#ifdef ENABLE /* no pDialogCur and ActiveWindow */
extern WINDOWPTR windowSearch;
extern WINDOWPTR windowRep;
extern WINDOWPTR pDialogCur;
extern WINDOWPTR ActiveWindow;
extern int cxEditScroll;/* not sure how cxEditScroll is used */
extern struct SEL selSearch;
#endif
extern struct FKPD vfkpdParaIns;
extern struct PAP *vppapNormal;
extern typeFC fcMacPapIns;
extern int wwCur;
extern struct WWD *pwwdCur;
extern struct CHP vchpInsert;
extern struct PAP vpapPrevIns;
extern int vfSelecting;
extern typeCP cpMacCur;
extern typeCP cpMinCur;
extern int vfSeeSel;
extern int vfSeeEdgeSel;
extern int docCur;
extern struct SEL selCur;
extern typeCP vcpFetch;
extern int vccpFetch;
extern CHAR *vpchFetch;
extern struct UAB vuab;
extern int vfSysFull;
extern struct PAP vpapAbs;
extern struct CHP vchpFetch;
extern int ferror;
extern typeCP cpWall;
/* Globals used to store settings of flags. Used to propose responses. */
extern BOOL fParaReplace /* = false initially */;
extern BOOL fReplConfirm /* = TRUE initially */;
extern BOOL fSearchWord /* = false initially */;
extern BOOL fSearchCase /* = false initially */;
extern BOOL fSpecialMatch;
extern BOOL fMatchedWhite /* = false initially */;
extern CHAR (**hszSearch)[]; /* Default search string */
extern CHAR (**hszReplace)[]; /* Default replace string */
extern CHAR (**hszFlatSearch)[]; /* All lower case version of search string */
extern CHAR (**hszRealReplace)[]; /* used for building replacement text */
extern CHAR (**hszCaseReplace)[]; /* used for building replacement text with
appropriate capitalization. */
extern typeCP cpMatchLim;
extern int vfDidSearch;
extern CHAR *szSearch;
extern CHAR (**HszCreate())[];
extern HWND vhWndMsgBoxParent;
extern HCURSOR vhcIBeam;
extern HCURSOR vhcArrow;
#ifdef INTL
extern CHAR szAppName[];
extern CHAR szSepName[];
#endif
NEAR DoSearch(void);
NEAR DoReplace(int, int);
typeCP NEAR CpSearchSz(typeCP, typeCP, CHAR *);
NEAR FMakeFlat(int);
NEAR SetSpecialMatch(void);
NEAR FSetParaReplace(int);
NEAR WCaseCp(typeCP, typeCP);
NEAR SetChangeString(HANDLE, int);
NEAR PutCpInWwVertSrch(typeCP);
#ifndef NOLA
BOOL (NEAR FAbort(void));
#endif
BOOL (NEAR FWordCp(typeCP, typeCP));
BOOL (NEAR FChMatch(int, int *, BOOL));
NEAR InsertPapsForReplace(typeFC);
NEAR DestroyModeless(HWND *);
NEAR FDlgSzTooLong(HWND, int, CHAR *, int);
NEAR idiMsgResponse(HWND, int, int);
BOOL CheckEnableButton(HANDLE, HANDLE);
BOOL bInSearchReplace = FALSE; // avoid close when we are searching!
#define CmdReplace(fThenFind) bInSearchReplace = TRUE; \
DoReplace(false, fThenFind); \
bInSearchReplace = FALSE
#define CmdReplaceAll() bInSearchReplace = TRUE; \
DoReplace(true, false); \
bInSearchReplace = FALSE
#ifndef NOLA
static int fAbortSearch = FALSE;
#endif
static int fChangeSel;
static int fSelSave = FALSE;
static struct SEL selSave;
#ifdef DBCS
/* Additional variables to handle white-space matching
for the DBCS space. */
#ifndef KOREA
static int cbLastMatch;
#endif
/* Since CpFirstSty(, styChar) calls on FetchCp(), any assumption
made about the validity of global variables set by FetchCp()
is no longer valid. We explicitly save those variables after
each FetchCp and use those instead. (Used in CpSearchSz().)*/
static typeCP cpFetchSave;
static int ccpFetchSave;
static CHAR *pchFetchSave;
/* Also, we move some of the local variables out from
CpSearchSz() so that they can be changed by FChMatch(). */
/*
int ichDoc;
int cchMatched;
typeCP cpFetchNext;
*/
#endif
NEAR DoSearch()
{
int cch;
typeCP cpSearch;
typeCP cpSearchLim;
typeCP cpSearchNext;
typeCP cpWallActual;
typeCP cpMatchFirst;
typeCP CpMin();
int idpmt;
int fDidSearch;
if (docCur == docNil)
return;
cch = CchSz(**hszSearch)-1;
if(cch == 0)
{
/* this should only occur if the user execute Repeat last find without having
previously defined a search string. */
Error(IDPMTNotFound);
return;
}
SetSpecialMatch();
if(!FMakeFlat(cch))
return;
fDidSearch = vfDidSearch;
cpWallActual = fDidSearch ? CpMin(cpWall, cpMacCur) : cpMacCur;
cpSearchNext = fDidSearch ? selCur.cpLim : selCur.cpFirst;
cpSearchLim = (cpSearchNext <= cpWallActual) ? cpWallActual : cpMacCur;
{
do
{
ContinueSearch:
cpSearch=CpSearchSz(cpSearchNext,cpSearchLim,**hszFlatSearch);
if (cpSearch == cpNil)
{
#ifndef NOLA
if (fAbortSearch)
{
Error(IDPMTCancelSearch);
fAbortSearch = FALSE;
vfDidSearch = FALSE;
FreeH(hszFlatSearch);
return;
}
#endif
if (cpSearchLim == cpWall && fDidSearch)
{
SearchFail: Error(vfDidSearch ? IDPMTSearchDone :
IDPMTNotFound);
if (vfDidSearch) /* did we previously have a match?*/
{ /* Yes, do setup for next pass */
/* clear flag so we can search some more */
vfDidSearch = false;
/* set "Wall" to immediately after last match */
cpWall = selCur.cpLim;
/* ask that selection be displayed */
vfSeeSel = vfSeeEdgeSel = TRUE;
}
FreeH(hszFlatSearch);
return;
}
else
{
cpSearchNext = cpMinCur;
cpSearchLim = cpWall;
fDidSearch = true;
goto ContinueSearch;
}
}
#ifdef DBCS /* was in JAPAN */
cpSearchNext = CpLastStyChar( cpSearch ) + 1;
#else
cpSearchNext = CpLastStyChar( cpSearch + 1 );
#endif
}
/*--- while (fSearchWord && !FWordCp(cpSearch, cpMatchLim-cpSearch));--*/
while (!FCpValid(cpSearch, cpMatchLim - cpSearch));
}
if (!vfDidSearch)
{
cpWall = cpSearch;
vfDidSearch = true;
}
/*Select( CpFirstSty( cpSearch, styChar ), CpLastStyChar( cpMatchLim ) );*/
if ( (cpMatchFirst = CpFirstSty( cpSearch, styChar )) != cpMatchLim )
Select( cpMatchFirst, cpMatchLim );
PutCpInWwVertSrch(selCur.cpFirst);
vfSeeSel = vfSeeEdgeSel = TRUE;
FreeH(hszFlatSearch);
}
NEAR DoReplace(fReplaceAll, fThenFind)
int fReplaceAll;
int fThenFind;
{
/* Replace now works as follows:
if the current selection is the search text, then replace it with
the replace text and jump to the next occurrence of the search text.
Otherwise, just jump to the next occurrence of the search text.
If fReplaceAll is true, then repeat this operation until the end
of the document. */
int cch;
typeCP cpSearchStart;
typeCP cpSearch;
typeCP cpSearchNext;
typeCP cpSearchLim;
typeCP cpSearchNow;
typeCP cpSearchLimNow;
typeCP dcp;
BOOL f1CharSel;
BOOL fFirstTime;
int ich;
int cchReplace;
int cwReplace;
int iCurCase;
int iLastCase;
typeFC fcCaseSz;
typeCP cpMacTextT;
typeCP cpWallActual;
int fDidSearch = vfDidSearch;
struct CHP chp;
typeCP cpMacSave;
iLastCase = -1; /* indicate that the string pointed to by hszCaseReplace
has not been given a value yet. */
if (!FWriteOk(fwcNil) || docCur == docNil)
/* Out of memory, read only document, etc */
return;
cch = CchSz(**hszSearch)-1;
if(cch == 0)
{
Error(IDPMTNotFound);
return;
}
SetSpecialMatch();
if(!FMakeFlat(cch))
return;
cwReplace = CwFromCch(cchReplace = CchSz(**hszReplace));
if(FNoHeap(hszRealReplace = (CHAR (**) [])HAllocate(cwReplace)))
{
FreeH(hszFlatSearch);
return;
}
bltbyte(**hszReplace, **hszRealReplace, cchReplace);
if(FNoHeap(hszCaseReplace = (CHAR (**) [])HAllocate(cwReplace)))
{
FreeH(hszFlatSearch);
FreeH(hszRealReplace);
return;
}
if(!FSetParaReplace(cchReplace))
{
FreeH(hszFlatSearch);
FreeH(hszCaseReplace);
FreeH(hszRealReplace);
return;
}
cch = CchSz(**hszRealReplace)-1;
fFirstTime = TRUE;
cpWallActual = fDidSearch ? CpMin(cpWall, cpMacCur) : cpMacCur;
cpSearchNow = cpSearchStart = selCur.cpFirst;
if (fReplaceAll || !fThenFind)
cpSearchLim = selCur.cpLim;
else
cpSearchLim = (cpSearchStart < cpWallActual) ? cpWallActual : cpMacCur;
cpSearchLimNow = selCur.cpLim;
if (fReplaceAll)
{
cpWallActual = cpSearchLim;
fDidSearch = true;
}
NoUndo(); /* Prevent the SetUndo from getting merged with adjacent stuff */
cpMacTextT = CpMacText(docCur);
if(cpSearchLimNow > cpMacTextT)
SetUndo(uacDelNS, docCur, cp0, cpMacTextT, docNil, cpNil, cp0, 0);
else
SetUndo(uacDelNS, docCur, cpSearchStart, cpSearchLimNow - cpSearchStart,
docNil, cpNil, cp0, 0);
if (ferror) goto MemoryError;
cpSearchNext = cpSearchStart;
{
do
{
/* ForcePmt(IDPMTSearching);*/
do
{
ContinueSearch:
cpSearch = CpSearchSz(cpSearchNext, cpSearchLim, **hszFlatSearch);
if (cpSearch == cpNil)
if ((cpSearchLim == cpWallActual && fDidSearch) || fAbortSearch)
DoneReplacingN:
{
DoneReplacingP:
FreeH(hszFlatSearch);
FreeH(hszCaseReplace);
FreeH(hszRealReplace);
cpMacTextT = CpMacText(docCur);
if (fReplaceAll || fFirstTime)
{
if(cpSearchLimNow > cpMacTextT)
SetUndo(uacInsert,docCur,cp0,
cpMacTextT,docNil,cpNil,cp0,0);
else
SetUndo(uacInsert,docCur,cpSearchStart,
cpSearchLimNow - cpSearchStart,
docNil,cpNil,cp0,0);
if (ferror) goto MemoryError;
vuab.uac = uacReplGlobal;
SetUndoMenuStr(IDSTRUndoBase);
/*Select( CpFirstSty( cpSearchStart, styChar ),
CpLastStyChar( cpSearchLimNow ) );*/
Select( CpFirstSty( cpSearchStart, styChar ),
(fReplaceAll ? cpSearchStart : cpSearchLimNow) );
vfSeeSel = fReplaceAll;
if (fReplaceAll)
{ /* reestablish the search after a changeall in case of a F3 next time */
vfDidSearch = false;
cpWall = selCur.cpLim;
}
}
else if (!fReplaceAll)
{
if (cpSearch == cpNil)
/*Select( CpFirstSty( cpSearchStart, styChar ),
CpLastStyChar( cpSearchLimNow ) );*/
Select( CpFirstSty( cpSearchStart, styChar ),
cpSearchLimNow );
else if (!fFirstTime)
/*Select( CpFirstSty( cpSearch, styChar ),
CpLastStyChar( cpMatchLim ) );*/
Select( CpFirstSty( cpSearch, styChar ),
cpMatchLim );
PutCpInWwVertSrch(selCur.cpFirst);
vfSeeSel = vfSeeEdgeSel = TRUE;
}
if (fAbortSearch)
{
fAbortSearch = FALSE;
Error(IDPMTCancelSearch);
}
else if (fFirstTime)
Error(fReplaceAll ? IDPMTNoReplace : (vfDidSearch ? IDPMTSearchDone : IDPMTNotFound));
return;
}
else
{
cpSearchNext = cpMinCur;
cpSearchLim = cpWallActual;
fDidSearch = true;
goto ContinueSearch;
}
#ifdef DBCS /* was in JAPAN */
cpSearchNext = CpLastStyChar( cpSearch ) + 1;
#else
cpSearchNext = CpLastStyChar( cpSearch + 1 );
#endif
}
/* while(fSearchWord && !FWordCp(cpSearch,cpMatchLim - cpSearch));*/
while(!FCpValid(cpSearch, cpMatchLim - cpSearch));
if (!fReplaceAll && (cpSearch != cpSearchNow || cpMatchLim != cpSearchLimNow))
{
if (fThenFind)
{ /* Get here if: Did a Change, then Find. Could not
do the change, but did find a next occurence */
cpSearchNow = cpSearchNext = cpSearchStart = cpSearch;
cpSearchLimNow = cpMatchLim;
fFirstTime = false; /* suppress error message */
SetUndo(uacInsert, docCur, cpSearchStart,
cpSearchLimNow - cpSearchStart, docNil, cpNil, cp0, 0);
if (ferror) goto MemoryError;
if (!vfDidSearch)
{
cpWall = cpSearch;
vfDidSearch = true;
}
/*---- continue;----*/
goto DoneReplacingN;
}
fFirstTime = true; /* Cause error message */
cpSearchStart = cpSearchNow;
cpSearchLim = cpSearchLimNow;
goto DoneReplacingN;
}
/*----- vfDidSearch = true;----*/
#ifdef FOOTNOTES
if(FEditFtn(cpSearch, cpMatchLim))
{
ferror = false; /* Reset error condition so that we don't
deallocate strings twice (KJS) */
continue;
}
#endif
fFirstTime = FALSE;
if (vfOutOfMemory || vfSysFull)
{ /* Out of memory (heap or disk) */
Error(IDPMTNoMemory);
FreeH(hszFlatSearch);
FreeH(hszRealReplace);
FreeH(hszCaseReplace);
cpMacTextT = CpMacText(docCur);
if(cpSearchLim > cpMacTextT)
SetUndo(uacInsert,docCur,cp0,cpMacTextT,docNil,cpNil,cp0,0);
else
SetUndo(uacInsert,docCur,cpSearchStart,
cpSearchLimNow - cpSearchStart,docNil,cpNil,cp0,0);
if (ferror)
NoUndo();
else
vuab.uac = uacReplGlobal;
return;
}
FetchCp(docCur, cpSearch, 0, fcmProps); /* Get props of first char
that we are replacing */
blt(&vchpFetch, &chp, cwCHP);
chp.fSpecial = false;
iCurCase = 0; /* assume that the replacement string doesn't
require special capitalization */
/* if we're not matching upper/lower case call WCaseCp to determine
the capitalization pattern of the matched string */
if (!fSearchCase)
iCurCase = WCaseCp(cpSearch, cpMatchLim - cpSearch);
/* if the new capitalization pattern of the matched string
doesn't match the current contents of hszCaseReplace,
copy the replacement string to hszCaseReplace and transform
hszCaseReplace to conform to the new pattern */
if (iCurCase != iLastCase)
switch (iCurCase)
{
default:
case 0: /* no special capitalization required */
bltbyte(**hszRealReplace, **hszCaseReplace, cch+1);
break;
case 1: /* first character of string must be capitalized */
bltbyte(**hszRealReplace, **hszCaseReplace, cch+1);
***hszCaseReplace = ChUpper(***hszRealReplace);
break;
case 2: /* all characters must be capitalized */
for (ich = 0; ich < cch; ich++)
(**hszCaseReplace)[ich] = ChUpper((**hszRealReplace)[ich]);
break;
}
/* do CachePara to find the current para props. CachePara has the
side effect of setting vpapAbs */
CachePara(docCur, cpSearch);
/* if the capitalization pattern has changed OR
the character properties of the replacement text don't match
those of the last insert OR
the paragraph properties of the replacement text don't match
those of the last insert, THEN
1) call NewChpIns to write a run describing the character
properties of the previous insertion text,
2) call FcWScratch to write the characters of the replacement
string to the scratch file,
3) if we are replacing paragraph marks, call InsertPapsForReplace
to write runs describing each paragraph in the replacement
string */
if (iCurCase != iLastCase ||
CchDiffer(&vchpInsert,&chp,cchCHP) != 0 ||
(fParaReplace && CchDiffer(&vpapPrevIns, &vpapAbs, cchPAP) != 0))
{
NewChpIns(&chp);
fcCaseSz = FcWScratch(**hszCaseReplace,cch);
if (fParaReplace)
InsertPapsForReplace(fcCaseSz);
}
/* Now since we have written the proper replacement text to
the scratch file and have setup the character and paragraph runs to
describe that text, simply do a replace to insert the replacement
text into the piece table */
Replace(docCur, cpSearch, cp0, fnScratch, fcCaseSz, (typeFC) cch);
if (ferror) goto MemoryError;
iLastCase = iCurCase; /* record new capitalization pattern */
/* Now delete the found text from the piece table*/
cpMacSave = cpMacCur;
Replace(docCur, cpSearch+cch, cpMatchLim - cpSearch, fnNil, fc0, fc0);
dcp = cpMacSave - cpMacCur; /* Calculate dcp here because picture
paragraphs may have interfered with deleting */
if (ferror) goto MemoryError;
if (!fReplaceAll)
{
SetUndo(uacInsert, docCur, cpSearch, (typeCP) cch,
docNil, cpNil, cp0, 0);
if (ferror) goto MemoryError;
SetUndoMenuStr(IDSTRUndoBase);
}
cpSearchLim += cch - dcp;
cpMatchLim += cch - dcp;
cpWallActual += cch - dcp;
#ifdef DBCS /* was in JAPAN */
cpSearchNext = cpMatchLim;
#else
cpSearchNext = CpLastStyChar( cpMatchLim );
#endif
if (fReplaceAll)
cpSearchLimNow = cpSearchLim;
}
while (fReplaceAll);
}
if (fThenFind)
{
do
{
ContinueSearch2:
if ((cpSearch = CpSearchSz(cpSearchNext, cpSearchLim,
**hszFlatSearch)) == cpNil)
{
if ((cpSearchLim == cpWallActual && fDidSearch) ||
fAbortSearch)
{
fFirstTime = false; /* Supress error message */
/*Select( CpFirstSty( cpSearchStart, styChar ),
CpLastStyChar( cpMatchLim ) );*/
Select( CpFirstSty( cpSearchStart, styChar ),
cpMatchLim );
PutCpInWwVertSrch(selCur.cpFirst);
cpSearchLimNow = cpMatchLim;
Error(fAbortSearch ?
IDPMTCancelSearch : IDPMTSearchDone);
fAbortSearch = FALSE;
vfDidSearch = false;
cpWall = selCur.cpLim;
goto DoneReplacingP;
}
else
{
cpSearchNext = cpMinCur;
cpSearchLim = cpWallActual;
fDidSearch = true;
goto ContinueSearch2;
}
}
#ifdef DBCS /* was in JAPAN */
cpSearchNext = CpLastStyChar( cpSearch ) + 1;
#else
cpSearchNext = CpLastStyChar( cpSearch + 1 );
#endif
}
/*-- while(fSearchWord && !FWordCp(cpSearch,cpMatchLim - cpSearch));*/
while(!FCpValid(cpSearch, cpMatchLim - cpSearch));
if (!vfDidSearch)
{
cpWall = cpSearch;
vfDidSearch = true;
}
}
goto DoneReplacingP;
MemoryError:
FreeH(hszFlatSearch);
FreeH(hszCaseReplace);
FreeH(hszRealReplace);
NoUndo();
/* counter off the losing insertion point after incomplete change all */
if (fReplaceAll && fSelSave)
{
selCur.cpFirst = selSave.cpFirst;
selCur.cpLim = selSave.cpLim;
}
}
#ifdef DBCS
BOOL fDBCS = FALSE;
#endif
typeCP NEAR CpSearchSz(cpFirst, cpMacSearch, sz)
typeCP cpFirst;
typeCP cpMacSearch;
CHAR *sz;
{{ /* Finds first occurrence of sz in docCur starting at cpFirst */
/* Returns cpNil if not found */
/* Ignore case of letters if fSearchCase is FALSE. This assumes that the
pattern has already been folded to lower case. */
CHAR ch;
BOOL fMatched;
int ichPat = 0;
int ichDoc = 0;
int cchMatched = 0;
typeCP cpFetchNext;
/*EVENT event;*/
#ifdef DBCS
typeCP cpFound;
CHAR rgchT[dcpAvgSent];
#endif
szSearch = sz;
#ifdef DBCS
/* Initialize those local variables moved out from this
function. */
ichDoc = 0;
cchMatched = 0;
pchFetchSave = &rgchT[0];
#ifndef KOREA
cbLastMatch = 1;
#endif
#endif
#ifdef DBCS
FetchCp(docCur, cpFirst, 0, fcmChars + fcmNoExpand);
cpFetchSave = vcpFetch;
bltbyte(vpchFetch, rgchT,
ccpFetchSave = ((vccpFetch > dcpAvgSent) ? dcpAvgSent : vccpFetch));
Assert(cpFetchSave == cpFirst);
cpFetchNext = cpFetchSave + ccpFetchSave;
#else
FetchCp(docCur, cpFirst, 0, fcmChars + fcmNoExpand);
Assert(vcpFetch == cpFirst);
cpFetchNext = vcpFetch + vccpFetch;
#endif
fMatchedWhite = false;
for (; ;)
{
if (szSearch[ichPat] == '\0' )
{{ /* Found it */
#ifdef DBCS
typeCP cpFound;
cpMatchLim = vcpFetch+ichDoc - (fMatchedWhite ? 1 : 0);
cpFound = cpFetchSave + ichDoc - cchMatched;
if (CpFirstSty(cpFound, styChar) == cpFound) {
/* It is on a Kanji boundary. We really found it. */
return (cpFound);
}
else {
/* The last character did not match, try again
excluding the last byte match. */
#ifndef KOREA
cchMatched -= cbLastMatch;
cbLastMatch = 1;
#endif
fMatchedWhite = false;
goto lblNextMatch;
}
#else
cpMatchLim = vcpFetch+ichDoc - (fMatchedWhite ? 1 : 0);
return vcpFetch + ichDoc - cchMatched;
#endif
}}
#ifdef DBCS
if (cpFetchSave + ichDoc >= cpMacSearch)
#else
if (vcpFetch + ichDoc >= cpMacSearch)
#endif
{{ /* Not found */
if(fMatchedWhite && szSearch[ichPat+2] == '\0')
{ /* Found it */
#ifdef DBCS
cpMatchLim = cpFetchSave + ichDoc;
cpFound = cpFetchSave + ichDoc - cchMatched;
if (CpFirstSty(cpFound, styChar) == cpFound) {
/* It is on a Kanji boundary, We really found it. */
return (cpFound);
}
else {
/* The last character did not match, try again
excluding the last byte match. */
#ifndef KOREA
cchMatched -= cbLastMatch;
cbLastMatch = 1;
#endif
fMatchedWhite = false;
goto lblNextMatch;
}
#else
cpMatchLim = vcpFetch+ichDoc;
return vcpFetch + ichDoc - cchMatched;
#endif
}
else
return cpNil;
}}
#if defined(DBCS) && !defined(KOREA)
if (ichDoc + cbLastMatch - 1 >= ccpFetchSave)
#else
if (ichDoc >= vccpFetch)
#endif
{ /* Need more cp's */
{{
#ifndef NOLA /* no look ahead */
/* check if abort search */
if (FAbort())
{
fAbortSearch = TRUE;
return cpNil;
}
#endif /* NOLA */
/* FetchCp(docNil, cpNil, 0, fcmChars + fcmNoExpand); */
/* we changed from a sequential fetch to a random fetch because a resize of the
window may cause another FetchCp before we reach here */
#ifdef DBCS
FetchCp(docCur, cpFetchNext, 0, fcmChars + fcmNoExpand);
cpFetchSave = vcpFetch;
bltbyte(vpchFetch, rgchT,
ccpFetchSave = ((vccpFetch > dcpAvgSent) ?
dcpAvgSent : vccpFetch));
cpFetchNext = cpFetchSave + ccpFetchSave;
#else
FetchCp(docCur, cpFetchNext, 0, fcmChars + fcmNoExpand);
cpFetchNext = vcpFetch + vccpFetch;
#endif
ichDoc = 0;
}}
continue;
}
#ifdef DBCS
ch = pchFetchSave[ichDoc++];
#ifndef KOREA
cbLastMatch = 1;
#endif
#else
ch = vpchFetch[ichDoc++];
#endif
if(!fSpecialMatch)
{
/* NOTE: this is just ChLower() brought in-line for speed */
#ifdef DBCS
if( fDBCS )
fDBCS = FALSE;
else
if(!fSearchCase)
#ifdef TAIWAN
if ( !( fDBCS = IsDBCSLeadByte( ch )))
#endif
{ /* avoid proc call for common cases */
if(ch >= 'A' && ch <= 'Z') ch += 'a' - 'A';
else if(ch < 'a' || ch > 'z') ch = ChLower(ch);
}
#else
if(!fSearchCase)
{ /* avoid proc call for common cases */
if(ch >= 'A' && ch <= 'Z') ch += 'a' - 'A';
else if(ch < 'a' || ch > 'z') ch = ChLower(ch);
}
#endif
if(szSearch[ichPat] == ch)
{
ichPat++;
fMatched = true;
}
else if(ch == chReturn || ch == chNRHFile)
fMatched = true;
else
fMatched = false;
}
else
fMatched = FChMatch(ch, &ichPat, true);
#ifdef DBCS
fDBCS = IsDBCSLeadByte( ch );
#endif
if(fMatched)
{
#if defined(DBCS) && !defined(KOREA)
cchMatched += cbLastMatch;
#else
cchMatched++;
#endif
}
else
{ /* No match; try again */
#ifdef DBCS
lblNextMatch:
#endif
if ((ichDoc -= cchMatched) < 0) /* Go back # of matched chars */
{{ /* Overshot the mark */
#ifdef DBCS
FetchCp(docCur, cpFetchSave + ichDoc, 0, fcmChars + fcmNoExpand);
cpFetchSave = vcpFetch;
bltbyte(vpchFetch, rgchT,
ccpFetchSave = ((vccpFetch > dcpAvgSent) ?
dcpAvgSent : vccpFetch));
cpFetchNext = cpFetchSave + ccpFetchSave;
#else
FetchCp(docCur, vcpFetch + ichDoc, 0, fcmChars + fcmNoExpand);
/* this is for the next FetchCp in this forever loop that used to depend
on a sequential fetch */
cpFetchNext = vcpFetch + vccpFetch;
#endif
ichDoc = 0;
}}
ichPat = 0;
cchMatched = 0;
}
}
}}
/* set up in hszFlatSearch a copy of hszSearch that is all lower case.
Note that we assume the old contents of hszFlatSearch were freed.
Return True if success, False if out of memory.
*/
NEAR FMakeFlat(cch)
int cch; /*CchSz(**hszSearch)-1*/
{
CHAR *pch1;
CHAR *pch2;
hszFlatSearch = (CHAR (**) [])HAllocate(CwFromCch(cch+1));
if(FNoHeap(hszFlatSearch))
return(FALSE);
if(!fSearchCase)
{
#ifdef DBCS
for(pch1= **hszSearch, pch2 = **hszFlatSearch;*pch1!='\0';)
if( IsDBCSLeadByte(*pch1) ) {
*pch2++ = *pch1++;
*pch2++ = *pch1++;
} else
*pch2++ = ChLower(*pch1++);
#else
for(pch1= **hszSearch, pch2 = **hszFlatSearch;*pch1!='\0';pch1++,pch2++)
*pch2 = ChLower(*pch1);
#endif
*pch2 = '\0';
}
else
bltbyte(**hszSearch, **hszFlatSearch, cch+1);
return(TRUE);
}
/* sets the global fSpecialMatch if the more complicated character matching
code is needed */
NEAR SetSpecialMatch()
{
CHAR *pch = **hszSearch;
CHAR ch;
#ifdef DBCS
for( ch = *pch ; ch != '\0'; pch = AnsiNext(pch), ch = *pch )
#else
while((ch = *pch++) != '\0')
#endif
{
switch(ch)
{
default:
continue;
case chMatchAny:
case chPrefixMatch:
case chSpace:
case chHyphen:
fSpecialMatch = true;
return;
}
}
fSpecialMatch = false;
return;
}
/* Sets the global fParaReplace if the user wants to insert Paragraph breaks
(since special insertion code must be run). Also sets up the global
hszRealReplace to reflect any meta characters in hszReplace */
NEAR FSetParaReplace(cch)
int cch; /*CchSz(**hszReplace)*/
{
CHAR *rgch = **hszRealReplace;
int ich = 0;
CHAR ch;
CHAR chNew;
fParaReplace = false;
while((ch = rgch[ich]) != '\0')
{
#ifdef DBCS
if(IsDBCSLeadByte(ch)){
ich +=2;
continue;
}
#endif
switch(ch)
{
default:
break;
case chPrefixMatch:
switch(rgch[ich+1])
{
default:
/* just escaping the next char */
if(rgch[ich+1] == '\0')
chNew = chPrefixMatch;
else
chNew = rgch[ich+1];
break;
case chMatchNBSFile:
chNew = chNBSFile;
break;
case chMatchTab:
chNew = chTab;
break;
case chMatchNewLine:
chNew = chNewLine;
break;
case chMatchNRHFile:
chNew = chNRHFile;
break;
case chMatchSect:
chNew = chSect;
break;
case chMatchEol:
chNew = chEol;
break;
}
#ifdef CRLF
if(chNew != chEol)
bltbyte(&(rgch[ich+1]),&(rgch[ich]), cch-ich-1);
#else
bltbyte(&(rgch[ich+1]),&(rgch[ich]), cch-ich-1);
#endif /*CRLF*/
if(chNew == chEol)
{
fParaReplace = true;
#ifdef CRLF
rgch[ich++] = chReturn;
#endif /*CRLF*/
}
rgch[ich] = chNew;
break;
case chEol:
#ifdef CRLF
if(ich == 0 || rgch[ich-1] != chReturn)
/* they didn't put in a return! */
{
CHAR (**hsz)[];
hsz = (CHAR (**) [])HAllocate(CwFromCch(cch+1));
if(FNoHeap(hsz))
{
return false;
}
bltbyte(**hszRealReplace, **hsz, ich);
(**hsz)[ich] = chReturn;
bltbyte((**hszRealReplace)+ich, (**hsz)+ich+1,
cch - ich);
FreeH(hszRealReplace);
hszRealReplace = hsz;
rgch = **hszRealReplace;
cch++;
ich++;
}
#endif /*CRLF*/
fParaReplace = true;
break;
}
ich++;
}
return true;
}
NEAR WCaseCp(cp,dcp)
typeCP cp;
typeCP dcp;
{
/* Determines capitalization pattern in a piece of text. Used when doing
replace to match existing pattern. returns an int which is one of:
0 - Not initial capital
1 - Initial Capital but lower case appears later
2 - Initial Capital and no lower case in the string
Assumes a valid cp, dcp pair.
*/
int ichDoc;
FetchCp(docCur, cp, 0, fcmChars + fcmNoExpand);
if(!isupper(vpchFetch[0]))
return(0);
/* we now know there is an initial cap. Are there any lower case chars? */
for(ichDoc=1; vcpFetch+ichDoc < cp + dcp;)
{
if(ichDoc >= vccpFetch)
{
FetchCp(docNil, cpNil, 0, fcmChars + fcmNoExpand);
ichDoc = 0;
continue;
}
if(islower(vpchFetch[ichDoc++]))
return(1);
}
/* No lower case letters were found. */
return(2);
}
int
FCpValid(cp, dcp)
typeCP cp, dcp;
{
CachePara(docCur, cp);
if (vpapAbs.fGraphics)
return false;
if (fSearchWord)
return FWordCp(cp, dcp);
return true;
}
NEAR DestroyModeless(phDlg)
HWND * phDlg;
{
HWND hDlg = *phDlg;
*phDlg = (HWND)NULL;
vhWndMsgBoxParent = (HANDLE)NULL;
DestroyWindow(hDlg);
} /* end of DestroyModeless */
BOOL far PASCAL DialogFind( hDlg, message, wParam, lParam )
HWND hDlg; /* Handle to the dialog box */
unsigned message;
WORD wParam;
LONG lParam;
{
CHAR szBuf[257];
int cch = 0;
HANDLE hCtlFindNext = GetDlgItem(hDlg, idiFindNext);
/* This routine handles input to the Find dialog box. */
switch (message)
{
case WM_INITDIALOG:
#ifdef ENABLE /* not sure how cxEditScroll is used */
cxEditScroll = 0;
#endif
CheckDlgButton(hDlg, idiWholeWord, fSearchWord);
CheckDlgButton(hDlg, idiMatchCase, fSearchCase);
cch = CchCopySz(**hszSearch, szBuf);
if (cch == 0)
{
EnableWindow(hCtlFindNext, false);
}
else
{
SetDlgItemText(hDlg, idiFind, (LPSTR)szBuf);
SelectIdiText(hDlg, idiFind);
}
vfDidSearch = false;
cpWall = selCur.cpLim;
return( TRUE ); /* ask windows to set focus to the first item also */
case WM_ACTIVATE:
if (wParam) /* turns active */
{
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)
{
case idiFind:
if (HIWORD(lParam) == EN_CHANGE)
{
vfDidSearch = false;
cpWall = selCur.cpLim;
CheckEnableButton(LOWORD(lParam), hCtlFindNext);
}
break;
case idiWholeWord:
case idiMatchCase:
CheckDlgButton(hDlg, wParam, !IsDlgButtonChecked(hDlg, wParam));
break;
case idiFindNext:
if (IsWindowEnabled(hCtlFindNext))
{
CHAR (**hszSearchT)[] ;
if (FDlgSzTooLong(hDlg, idiFind, szBuf, 257))
{
switch (idiMsgResponse(hDlg, idiFind, IDPMTTruncateSz))
{
case idiOk:
/* show truncated text to user */
SetDlgItemText(hDlg, idiFind, (LPSTR)szBuf);
break;
case idiCancel:
default:
return(TRUE);
}
}
if (FNoHeap(hszSearchT = HszCreate(szBuf)))
break;
/* fSearchForward = 1; search direction -- always forward */
PostStatusInCaption(IDSTRSearching);
StartLongOp();
FreeH(hszSearch);
hszSearch = hszSearchT;
fSearchCase = IsDlgButtonChecked(hDlg, idiMatchCase);
fSearchWord = IsDlgButtonChecked(hDlg, idiWholeWord);
EnableExcept(vhDlgFind, FALSE);
DoSearch();
EnableExcept(vhDlgFind, TRUE);
EndLongOp(vhcIBeam);
PostStatusInCaption(NULL);
}
break;
case idiCancel:
LCancelFind:
DestroyModeless(&vhDlgFind);
break;
default:
return(FALSE);
}
break;
case WM_CLOSE:
if (bInSearchReplace)
return TRUE;
goto LCancelFind;
#ifndef INEFFLOCKDOWN
case WM_NCDESTROY:
FreeProcInstance(lpDialogFind);
lpDialogFind = NULL;
/* fall through to return false */
#endif
default:
return(FALSE);
}
return(TRUE);
} /* end of DialogFind */
BOOL far PASCAL DialogChange( hDlg, message, wParam, lParam )
HWND hDlg; /* Handle to the dialog box */
unsigned message;
WORD wParam;
LONG lParam;
{
CHAR szBuf[257]; /* max 255 char + '\0' + 1 so as to detact too long string */
int cch = 0;
HANDLE hCtlFindNext = GetDlgItem(hDlg, idiFindNext);
CHAR (**hszSearchT)[];
CHAR (**hszReplaceT)[];
/* This routine handles input to the Change dialog box. */
switch (message)
{
case WM_INITDIALOG:
#ifdef ENABLE /* not sure how cxEditScroll is used */
cxEditScroll = 0;
#endif
szBuf[0] = '\0';
CheckDlgButton(hDlg, idiWholeWord, fSearchWord);
CheckDlgButton(hDlg, idiMatchCase, fSearchCase);
cch = CchCopySz(**hszSearch, szBuf);
SetDlgItemText(hDlg, idiFind, (LPSTR)szBuf);
if (cch > 0)
{
SelectIdiText(hDlg, idiFind);
}
else
{
EnableWindow(hCtlFindNext, false);
EnableWindow(GetDlgItem(hDlg, idiChangeThenFind), false);
//EnableWindow(GetDlgItem(hDlg, idiChange), false);
EnableWindow(GetDlgItem(hDlg, idiChangeAll), false);
}
cch = CchCopySz(**hszReplace, szBuf);
SetDlgItemText(hDlg, idiChangeTo, (LPSTR)szBuf);
fChangeSel = false;
vfDidSearch = false;
SetChangeString(hDlg, selCur.cpFirst == selCur.cpLim);
cpWall = selCur.cpLim;
return( TRUE ); /* ask windows to set focus to the first item also */
case WM_ACTIVATE:
if (wParam)
{
vhWndMsgBoxParent = hDlg;
SetChangeString(hDlg, (selCur.cpFirst == selCur.cpLim) || vfDidSearch);
}
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)
{
case idiFind: /* edittext */
if (HIWORD(lParam) == EN_CHANGE)
{
vfDidSearch = false;
cpWall = selCur.cpLim;
if (!CheckEnableButton(LOWORD(lParam), hCtlFindNext))
{
EnableWindow(GetDlgItem(hDlg, idiChangeThenFind), false);
//EnableWindow(GetDlgItem(hDlg, idiChange), false);
EnableWindow(GetDlgItem(hDlg, idiChangeAll), false);
}
else
{
EnableWindow(GetDlgItem(hDlg, idiChangeThenFind), true);
//EnableWindow(GetDlgItem(hDlg, idiChange), true);
EnableWindow(GetDlgItem(hDlg, idiChangeAll), true);
}
return(TRUE);
}
else
return(FALSE);
case idiChangeTo: /* edittext */
return(FALSE);
case idiFindNext: /* Button for Find Next */
/* Windows did not check if the default button is disabled
or not, so we have to check that! */
if (!IsWindowEnabled(hCtlFindNext))
break;
//case idiChange: /* Change, and stay put */
case idiChangeThenFind: /* Change, then Find button */
case idiChangeAll: /* Button for Replace All */
if (wwCur < 0)
break;
if (FDlgSzTooLong(hDlg, idiFind, szBuf, 257))
{
switch (idiMsgResponse(hDlg, idiFind, IDPMTTruncateSz))
{
case idiOk:
/* show truncated text to user */
SetDlgItemText(hDlg, idiFind, (LPSTR)szBuf);
break;
case idiCancel:
default:
return(TRUE);
}
}
if (FNoHeap(hszSearchT = HszCreate(szBuf)))
break;
if (FDlgSzTooLong(hDlg, idiChangeTo, szBuf, 257))
{
switch (idiMsgResponse(hDlg, idiChangeTo, IDPMTTruncateSz))
{
case idiOk:
/* show truncated text to user */
SetDlgItemText(hDlg, idiChangeTo, (LPSTR)szBuf);
break;
case idiCancel:
default:
return(TRUE);
}
}
if (FNoHeap(hszReplaceT = HszCreate(szBuf)))
break;
PostStatusInCaption(IDSTRSearching);
StartLongOp();
FreeH(hszSearch);
hszSearch = hszSearchT;
FreeH(hszReplace);
hszReplace = hszReplaceT;
/* fReplConfirm = 1;*/
fSearchCase = IsDlgButtonChecked(hDlg, idiMatchCase);
fSearchWord = IsDlgButtonChecked(hDlg, idiWholeWord);
EnableExcept(vhDlgChange, FALSE);
switch (wParam)
{
case idiFindNext:
DoSearch();
break;
//case idiChange:
case idiChangeThenFind:
CmdReplace(wParam == idiChangeThenFind);
break;
case idiChangeAll:
TurnOffSel();
if (!fChangeSel)
{
fSelSave = TRUE;
selSave.cpFirst = selCur.cpFirst;
selSave.cpLim = selCur.cpLim;
selCur.cpFirst = cpMinCur;
selCur.cpLim = cpMacCur;
}
CmdReplaceAll();
fSelSave = FALSE; /* reset */
break;
default:
Assert(FALSE);
break;
}
EnableExcept(vhDlgChange, TRUE);
SetChangeString(hDlg, vfDidSearch ? true : selCur.cpFirst == selCur.cpLim);
EndLongOp(vhcIBeam);
PostStatusInCaption(NULL);
break;
case idiWholeWord:
case idiMatchCase:
CheckDlgButton(hDlg, wParam, !IsDlgButtonChecked(hDlg, wParam));
break;
case idiCancel:
LCancelChange:
DestroyModeless(&vhDlgChange);
break;
default:
return(FALSE);
}
break;
#if WINVER < 0x300
/* Don't really need to process this */
case WM_CLOSE:
goto LCancelChange;
#endif
#ifndef INEFFLOCKDOWN
case WM_NCDESTROY:
FreeProcInstance(lpDialogChange);
lpDialogChange = NULL;
/* fall through to return false */
#endif
default:
return(FALSE);
}
return(TRUE);
} /* end of DialogChange */
NEAR SetChangeString(hDlg, fAll)
HANDLE hDlg;
int fAll;
{ /* set the last control button in CHANGE to "Change All" or "Change Selection" */
CHAR sz[256];
if (fAll == fChangeSel)
{
PchFillPchId(sz, (fAll ? IDSTRChangeAll : IDSTRChangeSel), sizeof(sz));
SetDlgItemText(hDlg, idiChangeAll, (LPSTR)sz);
fChangeSel = !fAll;
}
}
fnFindText()
{/* create dialog window only when it is not already created. */
if (!IsWindow(vhDlgFind))
{
#ifndef INEFFLOCKDOWN
if (!lpDialogFind)
if (!(lpDialogFind = MakeProcInstance(DialogFind, hMmwModInstance)))
{
WinFailure();
return;
}
#endif
vhDlgFind = CreateDialog(hMmwModInstance, MAKEINTRESOURCE(dlgFind),
hParentWw, lpDialogFind);
if (!vhDlgFind)
#ifdef WIN30
WinFailure();
#else
Error(IDPMTNoMemory);
#endif
}
else
{
SendMessage(vhDlgFind, WM_ACTIVATE, true, (LONG)NULL);
}
}
fnFindAgain()
{
register HWND hDlg = wwdCurrentDoc.wwptr;
register HWND hWndFrom;
hWndFrom = GetActiveWindow();
/* Find out where the F3 was executed from */
/* assemble hszSearch if called from Find or Change dialog box */
if (vhDlgFind || vhDlgChange)
{
if (((hDlg = vhDlgFind) && (vhDlgFind == hWndFrom ||
vhDlgFind == (HANDLE)GetWindowWord(hWndFrom, GWW_HWNDPARENT)))
||
((hDlg = vhDlgChange) && (vhDlgChange == hWndFrom ||
vhDlgChange == (HANDLE)GetWindowWord(hWndFrom, GWW_HWNDPARENT))))
{
SendMessage(hDlg, WM_COMMAND, idiFindNext, (LONG)0);
goto Out;
}
}
PostStatusInCaption(IDSTRSearching);
StartLongOp();
DoSearch();
EndLongOp(vhcIBeam);
PostStatusInCaption(NULL);
Out:
if (!IsWindowEnabled(wwdCurrentDoc.wwptr))
EnableWindow(wwdCurrentDoc.wwptr, true);
if (!IsWindowEnabled(hParentWw))
EnableWindow(hParentWw, true);
SendMessage(hParentWw, WM_ACTIVATE, true, (LONG)NULL);
} /* end of fnFindAgain */
fnReplaceText()
{/* create dialog window only when it is not already created. */
if (!IsWindow(vhDlgChange))
{
#ifndef INEFFLOCKDOWN
if (!lpDialogChange)
if (!(lpDialogChange = MakeProcInstance(DialogChange, hMmwModInstance)))
{
WinFailure();
return;
}
#endif
vhDlgChange = CreateDialog(hMmwModInstance, MAKEINTRESOURCE(dlgChange),
hParentWw, lpDialogChange);
if (!vhDlgChange)
#ifdef WIN30
WinFailure();
#else
Error(IDPMTNoMemory);
#endif
}
else
{
SendMessage(vhDlgChange, WM_ACTIVATE, true, (LONG)NULL);
}
}
/* P U T C P I N W W V E R T S R C H*/
NEAR PutCpInWwVertSrch(cp)
typeCP cp;
{
/* vertical case */
typeCP cpMac;
int ypMac;
struct EDL *pedl;
int dl;
int dlMac;
UpdateWw(wwCur, false);
dlMac = pwwdCur->dlMac - (vfSelecting ? 0 : 1);
if (dlMac <= 0)
return;
pedl = &(**(pwwdCur->hdndl))[dlMac - 1];
if (cp < pwwdCur->cpFirst ||
cp > (cpMac = pedl->cpMin + pedl->dcpMac) ||
cp == cpMac && pedl->fIchCpIncr)
{
DirtyCache(pwwdCur->cpFirst = cp);
pwwdCur->ichCpFirst = 0;
/* This call places the search cp vertically on the screen
by scrolling. */
CtrBackDypCtr( (pwwdCur->ypMac - pwwdCur->ypMin) >> 1, 2 );
#ifdef ENABLE /* no ActiveWindow concept yet */
if (pwwdCur->wwptr != ActiveWindow)
#endif
TrashWw(wwCur);
}
else
{
ypMac = pwwdCur->ypMac / 2;
/* Make sure that cp is still visible (scrolling if neccesary) */
pedl = &(**(pwwdCur->hdndl))[dl = DlFromYp(ypMac, pwwdCur)];
if (cp >= pedl->cpMin + pedl->dcpMac)
{
ScrollDownCtr( max( 1, dl ) );
TrashWw(wwCur);
UpdateWw(wwCur, false);
}
/* If cp is on bottom dl of the window and the dl is split by the
split bar, scroll down in doc by one line, to make insertion point
completely visible */
else if (cp >= pedl->cpMin & pedl->yp > ypMac)
{
ScrollDownCtr( 1 );
TrashWw(wwCur);
UpdateWw(wwCur,false);
}
}
}
#ifndef NOLA /* no look ahead */
BOOL (NEAR FAbort())
{
MSG msg;
register WORD vk_key;
register HANDLE hwndMsg;
HANDLE hwndPeek = (vhWndMsgBoxParent) ? vhWndMsgBoxParent : hParentWw;
if (PeekMessage((LPMSG)&msg, (HANDLE)NULL, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE))
{
hwndMsg = msg.hwnd;
if ((hwndPeek == (HANDLE)GetWindowWord(hwndMsg, GWW_HWNDPARENT)) ||
(hwndMsg == hwndPeek))
{
#ifdef DBCS
// It can be true at DBCS that WM_CHAR is the last message.
//
PeekMessage((LPMSG)&msg, hwndMsg, WM_KEYFIRST,WM_KEYLAST,PM_REMOVE);
#else
GetMessage((LPMSG)&msg, hwndMsg, WM_KEYFIRST, WM_KEYLAST);
#endif
if (msg.message == WM_KEYDOWN &&
(((vk_key = msg.wParam) == VK_ESCAPE) || (vk_key == VK_CANCEL)))
{
while (true)
{
GetMessage((LPMSG)&msg, hwndMsg, WM_KEYFIRST, WM_KEYLAST);
if (msg.message == WM_KEYUP && msg.wParam == vk_key)
return(TRUE);
}
}
else if (msg.message >= WM_SYSKEYDOWN && msg.message <= WM_SYSDEADCHAR)
DispatchMessage((LPMSG)&msg);
}
}
return(FALSE);
} /* end of FAbort */
#endif /* NOLA */
BOOL (NEAR FWordCp(cp, dcp))
typeCP cp;
typeCP dcp;
{
/* sees if the word starting at cp (with dcp chars) is a separate
word. */
int ich;
/* check the start of the word */
if(cp != cp0)
{
int wbPrev;
int wbStart;
FetchCp(docCur,cp-1,0,fcmChars + fcmNoExpand);
ich = 0;
wbPrev = WbFromCh(vpchFetch[ich]);
if(vcpFetch+vccpFetch <= cp)
{
FetchCp(docCur,cp,0,fcmChars + fcmNoExpand);
ich = 0;
}
else
ich++;
#ifdef DBCS /* was in JAPAN; KenjiK '90-12-20 */
/* word break is meanless. */
if(!IsDBCSLeadByte(vpchFetch[ich]))
#endif
if(wbPrev == (wbStart = WbFromCh(vpchFetch[ich])))
{
if (wbPrev != wbWhite && wbStart != wbWhite)
return(false);
}
}
/* check the end of the word */
if(cp+dcp-1 != cp0)
{
int wbEnd;
int wbLim;
if(vcpFetch+vccpFetch <= cp+dcp-1 || vcpFetch > cp+dcp-1)
{
FetchCp(docCur,cp+dcp-1,0,fcmChars + fcmNoExpand);
ich = 0;
}
else
ich = (dcp-1) - (vcpFetch-cp);
wbEnd = WbFromCh(vpchFetch[ich]);
if(vcpFetch+vccpFetch <= cp+dcp)
{
FetchCp(docCur,cp+dcp,0,fcmChars + fcmNoExpand);
ich = 0;
}
else
ich++;
#ifdef DBCS /* was in JAPAN; KenjiK '90-12-20 */
/* word break is meanless. */
if(!IsDBCSLeadByte(vpchFetch[ich]))
#endif
if(vccpFetch != 0 && (wbEnd == (wbLim = WbFromCh(vpchFetch[ich]))))
{
if (wbEnd != wbWhite && wbLim != wbWhite)
return(false);
}
}
return(true);
}
BOOL (NEAR FChMatch(ch, pichPat, fFwd))
int ch;
int *pichPat;
BOOL fFwd;
{
int ich = *pichPat;
int chSearch = szSearch[ich];
BOOL fPrefixed = false;
BOOL fMatched = false;
#ifdef DEBUG
Assert(fSpecialMatch);
#endif /*DEBUG*/
#ifdef DBCS
Assert(fFwd);
#ifndef KOREA
cbLastMatch = 1; /* Unless DBCS space. */
#endif
#endif
/* NOTE: this is just ChLower() brought in-line for speed */
#ifdef DBCS
// No need to make lower char for DBCS second byte
if(!fDBCS && !fSearchCase && ch >= 'A' && ch <= 'Z' )
#else
if(!fSearchCase && ch >= 'A' && ch <= 'Z' )
#endif
ch += 'a' - 'A';
if(!fFwd && ich > 0 && szSearch[ich-1] == chPrefixMatch)
/* see if the char is prefixed by a chPrefixMatch */
{
chSearch = chPrefixMatch;
--ich;
}
for(;;)
{
switch(chSearch)
{
default:
#if defined(DBCS) && !defined(KOREA)
if(IsDBCSLeadByte(chSearch))
cbLastMatch = 2;
#endif
if(ch == chSearch)
goto GoodMatch;
else if(ch == chReturn || ch == chNRHFile)
goto EasyMatch;
break;
case chSpace:
if(ch == chSpace || ch == chNBSFile)
goto GoodMatch;
break;
case chHyphen:
if(ch == chHyphen || ch == chNRHFile || ch == chNBH)
goto GoodMatch;
break;
case chMatchAny:
if(ch == chReturn || ch == chNRHFile)
goto EasyMatch;
if(!fPrefixed || ch == chMatchAny)
goto GoodMatch;
break;
case chPrefixMatch:
if(fPrefixed)
{
if(ch == chPrefixMatch)
goto GoodMatch;
else
break;
}
else
{
chSearch = szSearch[ich+1];
if(fFwd)
++ich;
fPrefixed = true;
switch(chSearch)
{
default:
continue;
case chMatchEol:
chSearch = chEol;
continue;
case chMatchTab:
chSearch = chTab;
continue;
case chMatchWhite:
switch(ch)
{
default:
#ifdef DBCS
lblNonWhite:
#endif
if(fMatchedWhite)
{
if(fFwd)
{
if(szSearch[++ich] =='\0')
{
*pichPat = ich;
goto EasyMatch;
}
}
else
{
ich -= 1;
if(ich < 0)
{
*pichPat = ich;
goto EasyMatch;
}
}
*pichPat = ich;
fMatchedWhite = false;
chSearch = szSearch[ich];
continue;
}
break;
case chSpace:
case chReturn:
case chEol:
case chTab:
case chNBSFile:
case chNewLine:
case chSect:
fMatchedWhite = true;
goto EasyMatch;
}
break;
case chMatchNBSFile:
chSearch = chNBSFile;
continue;
case chMatchNewLine:
chSearch = chNewLine;
continue;
case chMatchNRHFile:
chSearch = chNRHFile;
continue;
case chMatchSect:
chSearch = chSect;
continue;
}
}
break;
}
fMatchedWhite = false;
return false;
}
GoodMatch:
*pichPat = ich + ((fFwd) ? 1 : (-1));
EasyMatch:
return true;
}
/* I N S E R T P A P S F O R R E P L A C E */
/* do AddRunScratch for every distinct paragraph in hszCaseReplace */
/* This is only needed when hszCaseReplace contains one or more chEols */
NEAR InsertPapsForReplace(fc)
typeFC fc;
{
int cchInsTotal = 0;
CHAR *pchTail;
CHAR *pchHead;
for(;;)
{
int cch;
pchHead = **hszCaseReplace + cchInsTotal;
pchTail = (CHAR *)index(pchHead, chEol);
if (pchTail == 0) return;
cch = pchTail - pchHead + 1; /* cch is count including chEol */
fc += cch;
cchInsTotal += cch;
AddRunScratch(&vfkpdParaIns, &vpapAbs, vppapNormal,
FParaEq(&vpapAbs, &vpapPrevIns) && vfkpdParaIns.brun != 0 ? -cchPAP : cchPAP,
fcMacPapIns = fc);
blt(&vpapAbs, &vpapPrevIns, cwPAP);
}
}
NEAR FDlgSzTooLong(hDlg, idi, pch, cchMax)
HWND hDlg;
int idi;
CHAR *pch;
int cchMax;
{
int cchGet = GetDlgItemText(hDlg, idi, (LPSTR)pch, cchMax);
*(pch+cchMax-2) = '\0'; /* just in case the string is too long */
if (cchGet > (cchMax - 2))
return(TRUE);
else
return(FALSE);
}
NEAR idiMsgResponse(hDlg, idi, idpmt)
HWND hDlg;
int idi;
int idpmt;
{
CHAR szT[cchMaxSz];
PchFillPchId(szT, idpmt, sizeof(szT));
SetFocus(GetDlgItem(hDlg, idi));
SendDlgItemMessage(hDlg, idi, EM_SETSEL, (WORD)NULL, MAKELONG(255, 32767));
return(IdPromptBoxSz(hDlg, szT, MB_OKCANCEL | MB_ICONASTERISK));
}
PostStatusInCaption(idstr)
int idstr;
{
extern HWND hParentWw;
extern CHAR szCaptionSave[];
CHAR *pchCaption = &szCaptionSave[0];
CHAR *pchLast;
int cch;
CHAR szT[256];
if (idstr == NULL)
{
/* restore the caption */
SetWindowText(hParentWw, (LPSTR)pchCaption);
}
else
{
/* save caption */
GetWindowText(hParentWw, (LPSTR)pchCaption, cchMaxFile);
/* append status message after app name */
#ifndef INTL
pchLast = pchCaption + CchSz(pchCaption) - 1;
while (pchLast-- > pchCaption)
{
if (*pchLast == ' ')
break;
}
PchFillPchId(bltbyte(pchCaption, szT, (cch = pchLast - pchCaption + 1)),
IDSTRSearching, 13);
#else
pchLast = pchCaption + CchSz(szAppName) + CchSz(szSepName) - 2;
PchFillPchId(bltbyte(pchCaption, szT, (cch = pchLast - pchCaption)),
IDSTRSearching, 13);
#endif
SetWindowText(hParentWw, (LPSTR)szT);
}
}