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