home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / MULTIPAD.PAK / SEARCH.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  7.4 KB  |  290 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993-1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE: search.c
  9. //
  10. //  PURPOSE: Implement search and replace on an edit buffer.
  11. //
  12. //  FUNCTIONS:
  13. //    FindReplace- Find and/or replace text in the current document.
  14. //    Find       - Search for a string in the edit text.
  15. //    Replace    - Replace the current selection.
  16. //    ReplaceAll - To replace all of the matches found in the edit text.
  17. //    FWholeWord - Check to see if the match is a whole word.
  18. //
  19. //  COMMENTS:
  20. //
  21.  
  22.  
  23. #include <windows.h>            // required for all Windows applications
  24. #include "globals.h"            // prototypes specific to this application
  25. //#include <string.h>
  26. //#include <ctype.h>
  27.  
  28. BOOL Find(char *, BOOL, BOOL, BOOL, BOOL);
  29. VOID Replace(char *);
  30. VOID ReplaceAll(char *, char *, BOOL, BOOL);
  31. BOOL FWholeWord(char *, char *, char *, int);
  32.  
  33. //
  34. //  FUNCTION: FindReplace(char*,char*,BOOL,BOOL,BOOL,BOOL,BOOL,BOOL)
  35. //
  36. //  PURPOSE: Find and/or replace text in the current document.
  37. //
  38. //  PARAMETERS:
  39. //    szFind       - The string to find.
  40. //    szReplace    - The string used to replace.
  41. //    frt -
  42. //      frtFind    - Find the string szFind
  43. //      frtReplace - Replace the current selection with szReplace
  44. //      frtRepAll  - Replace all occurances of szFind with szReplace
  45. //    fDown        - Search down if true, up if false.
  46. //    fMatchCase   - Match case on a search.
  47. //    fWholeWord   - Match whole words only.
  48. //
  49. //  RETURN VALUE:
  50. //    NONE.
  51. //
  52. //  COMMENTS:
  53. //
  54. //
  55.  
  56. VOID FindReplace(char *szFind, 
  57.                  char *szReplace,
  58.                  FRT frt,
  59.                  BOOL fDown, 
  60.                  BOOL fMatchCase, 
  61.                  BOOL fWholeWord)
  62. {
  63.     switch (frt)
  64.     {
  65.         case frtFind:
  66.             Find(szFind, fDown, fMatchCase, fWholeWord, FALSE);
  67.             break;
  68.         case frtReplace:
  69.             Replace(szReplace);
  70.             break;
  71.         case frtRepAll:
  72.             ReplaceAll(szFind, szReplace, fMatchCase, fWholeWord);
  73.     }
  74. }
  75.  
  76.  
  77. //
  78. //  FUNCTION: Find(char *, BOOL, BOOL, BOOL, BOOL)
  79. //
  80. //  PURPOSE: Search for a string in the edit text.
  81. //
  82. //  PARAMETERS:
  83. //    szFind    - The string to search for.
  84. //    fDown     - Search from current position to the end of the text.
  85. //    fMatchCase- Match the case of the search string.
  86. //    fWholeWord- Target must have white space on both sides.
  87. //    fNoScroll - Don't scroll the window to the selection.
  88. //
  89. //  RETURN VALUE:
  90. //    TRUE - String was found.
  91. //    FALSE - Search was not sucessful.
  92. //
  93. //  COMMENTS:
  94. //
  95. //
  96.  
  97. BOOL Find(char *szFind, 
  98.           BOOL fDown, 
  99.           BOOL fMatchCase, 
  100.           BOOL fWholeWord, 
  101.           BOOL fNoScroll)
  102. {
  103.     char  *szText;          // Pointer to edit text
  104.     UINT   ichStart;        // Index of start of selection
  105.     UINT   ichEnd;          // Index of end of selection
  106.     UINT   cch;             // Number of charaters in edit text
  107.     int    dch;             // Number of characters to move (+/-1)
  108.     int    dchComp;
  109.     char  *szTerm;          // Pointer to terminal point in search
  110.     char  *sz;              // Pointer to current character
  111.     UINT   cchFind;         // Length of find string
  112.     BOOL   fFound = FALSE;  // Found flag
  113.     int    dchOnFind;       //
  114.  
  115.     szText  = LockEditText(GetEditWindow(NULL));
  116.     cchFind = strlen(szFind);
  117.  
  118.     SendMessage(GetEditWindow(NULL), 
  119.                 EM_GETSEL, 
  120.                 (WPARAM)&ichStart, 
  121.                 (LPARAM)&ichEnd);
  122.  
  123.     cch = strlen(szText);
  124.  
  125.     if (
  126.         ichEnd-ichStart == cchFind &&
  127.         !strnicmp(szText+ichStart,szFind,cchFind)
  128.     )
  129.         dchOnFind = 1;
  130.     else
  131.         dchOnFind = 0;
  132.  
  133.     if (fDown)
  134.     {
  135.         dch = 1;
  136.         dchComp = 0;
  137.         sz = szText + ichStart + dchOnFind;
  138.         szTerm = szText + cch;
  139.     }
  140.     else
  141.     {
  142.         dch = -1;
  143.         dchComp = 1;
  144.         sz = szText + ichStart - dchOnFind;
  145.         szTerm = szText;
  146.     }
  147.  
  148.     for (; sz + dchComp != szTerm; sz += dch)
  149.     {
  150.         if (
  151.             tolower(*sz) == tolower(*szFind) &&
  152.             (fMatchCase ?
  153.                 !strncmp(sz,szFind,cchFind) :
  154.                 !strnicmp(sz,szFind,cchFind)
  155.             ) &&
  156.             (!fWholeWord || FWholeWord(sz, szText, szTerm, cchFind)))
  157.         {
  158.             SendMessage(GetEditWindow(NULL),
  159.                         EM_SETSEL, 
  160.                         sz-szText, 
  161.                         sz-szText+cchFind);
  162.             if (!fNoScroll)
  163.                 SendMessage(GetEditWindow(NULL), EM_SCROLLCARET, 0, 0L);
  164.             fFound = TRUE;
  165.             break;
  166.         }
  167.     }
  168.  
  169.     if (!fNoScroll && !fFound)
  170.         MessageBox(NULL, szFind, "String not found", MB_OK);
  171.  
  172.     return fFound;
  173. }
  174.  
  175.  
  176. //
  177. //  FUNCTION: Replace(char *)
  178. //
  179. //  PURPOSE: Replace the current selection.
  180. //
  181. //  PARAMETERS:
  182. //    szReplace - The string to replace with.
  183. //
  184. //  RETURN VALUE:
  185. //    NONE
  186. //
  187. //  COMMENTS:
  188. //
  189. //
  190.  
  191. VOID Replace(char *szReplace)
  192. {
  193.  
  194.     SendMessage(GetEditWindow(NULL), 
  195.                 EM_REPLACESEL, 
  196.                 0, 
  197.                 (LPARAM) (LPSTR) szReplace);
  198. }
  199.  
  200. //
  201. //  FUNCTION: ReplaceAll(char *, char *, BOOL, BOOL)
  202. //
  203. //  PURPOSE: To replace all of the matches found in the edit text.
  204. //
  205. //  PARAMETERS:
  206. //    szFind     - The string to replace.
  207. //    szReplace  - The string to replace with.
  208. //    fMatchCase - Replace only exact matches.
  209. //    fWholeWord - Replace only whole word matches.
  210. //
  211. //  RETURN VALUE:
  212. //
  213. //  COMMENTS:
  214. //
  215. //
  216.  
  217. VOID ReplaceAll(char *szFind, 
  218.                 char *szReplace, 
  219.                 BOOL fMatchCase, 
  220.                 BOOL fWholeWord)
  221. {
  222.     UINT ichStart;
  223.     UINT ichEnd;
  224.  
  225.     SendMessage(GetEditWindow(NULL), 
  226.                 EM_GETSEL, 
  227.                 (WPARAM)&ichStart, 
  228.                 (LPARAM)&ichEnd);
  229.  
  230.     SendMessage(GetEditWindow(NULL), EM_SETSEL, (WPARAM)0, (LPARAM)0);
  231.  
  232.     while (Find(szFind, TRUE, fMatchCase, fWholeWord, TRUE))
  233.     {
  234.        Replace(szReplace);
  235.     }
  236.  
  237.     SendMessage(GetEditWindow(NULL),
  238.                 EM_SETSEL, 
  239.                 (WPARAM)ichStart, 
  240.                 (LPARAM)ichEnd);
  241. }
  242.  
  243.  
  244. //
  245. //  FUNCTION: FWholeWord(char *, char*, char *, int)
  246. //
  247. //  PURPOSE: Check to see if the match is a whole word.
  248. //
  249. //  PARAMETERS:
  250. //    sz     - A pointer to the found string.
  251. //    szStart- A pointer to the beginning of the buffer.
  252. //    szEnd  - A pointer to the end of the buffer.
  253. //    cch    - The lenght of the found string.
  254. //
  255. //  RETURN VALUE:
  256. //    TRUE  - Whole word.
  257. //    FALSE - No a whole word.
  258. //
  259. //  COMMENTS:
  260. //
  261.  
  262. BOOL FWholeWord(char *sz, char *szStart, char *szEnd, int cch)
  263. {
  264.     // Is the start of the found text preceded by whitespace?
  265.     if (
  266.         sz != szStart &&
  267.         *(sz-1) != ' ' &&
  268.         *(sz-1) != '\t' &&
  269.         *(sz-1) != ',' &&
  270.         *(sz-1) != '.' &&
  271.         *(sz-1) != '\r'
  272.     ) {
  273.         return FALSE;
  274.     }
  275.  
  276.     // Is the end of the found text followed by whitespace?
  277.     if (
  278.         sz + cch != szEnd &&
  279.         *(sz+cch) != ' ' &&
  280.         *(sz+cch) != '\t' &&
  281.         *(sz+cch) != ',' &&
  282.         *(sz+cch) != '.' &&
  283.         *(sz+cch) != '\r'
  284.     ) {
  285.         return FALSE;
  286.     }
  287.  
  288.     return TRUE;
  289. }
  290.