/************************************************************/ /* 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 #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); } }