2016 lines
62 KiB
C
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);
|
|
}
|
|
}
|
|
|