home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / vrac / mpad32.zip / MPFIND.C < prev    next >
C/C++ Source or Header  |  1994-04-15  |  12KB  |  282 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. /***************************************************************************
  13.  *                                                                         *
  14.  *  MODULE      : MpFind.c                                                 *
  15.  *                                                                         *
  16.  *  PURPOSE     : Code to do text searches in MultiPad.                    *
  17.  *                                                                         *
  18.  *  FUNCTIONS   : RealSlowCompare () - Compares subject string with target *
  19.  *                                     string.                             *
  20.  *                                                                         *
  21.  *                Local_FindText ()          - Looks for the search string in the  *
  22.  *                                     active window.                      *
  23.  *                                                                         *
  24.  *                FindPrev ()        - Find previous occurence of search   *
  25.  *                                     string.                             *
  26.  *                                                                         *
  27.  *                FindNext ()        - Find next occurence of search string*
  28.  *                                                                         *
  29.  *                FindDlgProc ()     - Dialog function for Search/Find.    *
  30.  *                                                                         *
  31.  *                Find ()            - Invokes FindDlgProc ()              *
  32.  *                                                                         *
  33.  ***************************************************************************/
  34. #include "multipad.h"
  35.  
  36. #undef HIWORD
  37. #undef LOWORD
  38.  
  39. #define HIWORD(l) (((WORD*)&(l))[1])
  40. #define LOWORD(l) (((WORD*)&(l))[0])
  41.  
  42. BOOL fCase         = FALSE;    /* Turn case sensitivity off */
  43. CHAR szSearch[160] = "";       /* Initialize search string  */
  44.  
  45. //LPSTR WINAPI AnsiLower (LPSTR);
  46.  
  47. /****************************************************************************
  48.  *                                                                          *
  49.  *  FUNCTION   : RealSlowCompare ()                                         *
  50.  *                                                                          *
  51.  *  PURPOSE    : Compares subject string with the target string. This fn/   *
  52.  *               is called repeatedly so that all substrings are compared,  *
  53.  *               which makes it O(n ** 2), hence it's name.                 *
  54.  *                                                                          *
  55.  *  RETURNS    : TRUE  - If pSubject is identical to pTarget.               *
  56.  *               FALSE - otherwise.                                         *
  57.  *                                                                          *
  58.  ****************************************************************************/
  59.  
  60. BOOL NEAR PASCAL RealSlowCompare (
  61.         register PSTR pSubject,
  62.         register PSTR pTarget)
  63. {
  64.     if (fCase){
  65.         while (*pTarget)
  66.             if (*pTarget++ != *pSubject++)
  67.                 return FALSE;
  68.     }
  69.     else{
  70.         /* If case-insensitive, convert both subject and target to lowercase
  71.          * before comparing.
  72.          */
  73.         AnsiLower ((LPSTR)pTarget);
  74.         while (*pTarget)
  75.             if (*pTarget++ != (CHAR)(DWORD)AnsiLower ((LPSTR)(DWORD)(BYTE)*pSubject++))
  76.                 return FALSE;
  77.     }
  78.     return TRUE;
  79. }
  80.  
  81. /****************************************************************************
  82.  *                                                                          *
  83.  *  FUNCTION   : Local_FindText ()                                                  *
  84.  *                                                                          *
  85.  *  PURPOSE    : Finds the search string in the active window according to  *
  86.  *               search direction (dch) specified ( -1 for reverse and 1 for*
  87.  *               forward searches).                                         *
  88.  *                                                                          *
  89.  ****************************************************************************/
  90. VOID NEAR PASCAL Local_FindText(register INT dch)
  91. {
  92.     register PSTR pText;
  93.     HANDLE        hT;
  94.     LONG          l;
  95.     WORD          cch;
  96.     INT           i;
  97.  
  98.     if (!*szSearch)
  99.         return;
  100.  
  101.     /* Find the current selection range */
  102.     l = (LONG)SendMessage(hwndActiveEdit, EM_GETSEL, 0, 0);
  103.  
  104.     /* Get the handle to the text buffer and lock it */
  105.     hT    = (HANDLE)SendMessage (hwndActiveEdit, EM_GETHANDLE, 0, 0L);
  106.     pText = LocalLock(hT);
  107.  
  108.     /* Get the length of the text */
  109.     cch = (WORD)SendMessage (hwndActiveEdit, WM_GETTEXTLENGTH, 0, 0L);
  110.  
  111.     /* Start with the next char. in selected range ... */
  112.     pText += LOWORD (l) + dch;
  113.  
  114.     /* Compute how many characters are before/after the current selection*/
  115.     if (dch < 0)
  116.         i = LOWORD (l);
  117.     else
  118.         i = cch - LOWORD (l) + 1 - lstrlen (szSearch);
  119.  
  120.     /* While there are uncompared substrings... */
  121.     while ( i > 0){
  122.         LOWORD(l)+=dch;
  123.  
  124.         /* Does this substring match? */
  125.         if (RealSlowCompare(pText,szSearch)){
  126.  
  127.             /* Yes, unlock the buffer.*/
  128.             LocalUnlock(hT);
  129.  
  130.             /* Select the located string */
  131.             HIWORD(l) = LOWORD(l) + (WORD)lstrlen (szSearch);
  132.             SendMessage(hwndActiveEdit, EM_SETSEL, GET_EM_SETSEL_MPS(LOWORD(l), HIWORD(l)));
  133.             return;
  134.         }
  135.         i--;
  136.  
  137.         /* increment/decrement start position by 1 */
  138.         pText += dch;
  139.     }
  140.  
  141.     /* Not found... unlock buffer. */
  142.     LocalUnlock (hT);
  143.  
  144.     /* Give a message */
  145.     MPError (hwndFrame, MB_OK | MB_ICONEXCLAMATION, IDS_CANTFIND, (LPSTR)szSearch);
  146.  
  147.     return;
  148. }
  149.  
  150. /****************************************************************************
  151.  *                                                                          *
  152.  *  FUNCTION   : FindPrev ()                                                *
  153.  *                                                                          *
  154.  *  PURPOSE    : Finds the previous occurence of the search string. Calls   *
  155.  *               Local_FindText () with a negative search direction.                *
  156.  *                                                                          *
  157.  ****************************************************************************/
  158. VOID APIENTRY FindPrev()
  159. {
  160.     Local_FindText(-1);
  161. }
  162.  
  163. /****************************************************************************
  164.  *                                                                          *
  165.  *  FUNCTION   : FindNext ()                                                *
  166.  *                                                                          *
  167.  *  PURPOSE    : Finds the next occurence of search string. Calls           *
  168.  *               Local_FindText () with a positive search direction.                *
  169.  *                                                                          *
  170.  ****************************************************************************/
  171. VOID APIENTRY FindNext()
  172. {
  173.     Local_FindText(1);
  174. }
  175.  
  176. /****************************************************************************
  177.  *                                                                          *
  178.  *  FUNCTION   : FindDlgProc(hwnd, message, wParam, lParam)                 *
  179.  *                                                                          *
  180.  *  PURPOSE    : Dialog function for the Search/Find command. Prompts user  *
  181.  *               for target string, case flag and search direction.         *
  182.  *                                                                          *
  183.  ****************************************************************************/
  184. BOOL APIENTRY FindDlgProc(
  185.         HWND hwnd,
  186.         UINT msg,
  187.         UINT wParam,
  188.         LONG lParam)
  189. {
  190.     switch (msg){
  191.         case WM_INITDIALOG:{
  192.  
  193.             /* Check/uncheck case button */
  194.             CheckDlgButton (hwnd, (int)IDD_CASE, (WORD)fCase);
  195.  
  196.             /* Set default search string to most recently searched string */
  197.             SetDlgItemText (hwnd, IDD_SEARCH, szSearch);
  198.  
  199.             /* Allow search only if target is nonempty */
  200.             if (!lstrlen (szSearch)){
  201.                 EnableWindow (GetDlgItem (hwnd, IDOK), FALSE);
  202.                 EnableWindow (GetDlgItem (hwnd, IDD_PREV), FALSE);
  203.             }
  204.             break;
  205.         }
  206.  
  207.         case WM_COMMAND:
  208.         {
  209.  
  210.             /* Search forward by default (see IDOK below) */
  211.             INT i = 1;
  212.  
  213.             switch (LOWORD(wParam)){
  214.                 /* if the search target becomes non-empty, enable searching */
  215.                 case IDD_SEARCH:
  216.                     if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE){
  217.                         if (!(WORD) SendDlgItemMessage (hwnd,
  218.                                                         IDD_SEARCH,
  219.                                                         WM_GETTEXTLENGTH,
  220.                                                         0,
  221.                                                         0L))
  222.                             i = FALSE;
  223.                         else
  224.                             i = TRUE;
  225.                         EnableWindow (GetDlgItem (hwnd, IDOK), i);
  226.                         EnableWindow (GetDlgItem (hwnd, IDD_PREV), i);
  227.                     }
  228.                     break;
  229.  
  230.                 case IDD_CASE:
  231.                     /* Toggle state of case button */
  232.                     CheckDlgButton (hwnd,
  233.                                     (int)IDD_CASE,
  234.                                     (WORD)!IsDlgButtonChecked (hwnd, (int)IDD_CASE));
  235.                     break;
  236.  
  237.                 case IDD_PREV:
  238.                     /* Set direction to backwards */
  239.                     i=-1;
  240.                     /*** FALL THRU ***/
  241.  
  242.                 case IDOK:
  243.                     /* Save case selection */
  244.                     fCase = IsDlgButtonChecked( hwnd, IDD_CASE);
  245.  
  246.                     /* Get search string */
  247.                     GetDlgItemText (hwnd, IDD_SEARCH, szSearch, sizeof (szSearch));
  248.  
  249.                     /* Find the text */
  250.                     Local_FindText (i);
  251.                     /*** FALL THRU ***/
  252.  
  253.                 /* End the dialog */
  254.                 case IDCANCEL:
  255.                     EndDialog (hwnd, 0);
  256.                     break;
  257.  
  258.                 default:
  259.                     return FALSE;
  260.             }
  261.             break;
  262.         }
  263.         default:
  264.             return FALSE;
  265.     }
  266.     return TRUE;
  267.         UNREFERENCED_PARAMETER(lParam);
  268. }
  269.  
  270. /****************************************************************************
  271.  *                                                                          *
  272.  *  FUNCTION   : Find()                                                     *
  273.  *                                                                          *
  274.  *  PURPOSE    : Invokes the Search/Find dialog.                            *
  275.  *                                                                          *
  276.  ****************************************************************************/
  277.  
  278. VOID APIENTRY Find()
  279. {
  280.     DialogBox (hInst, IDD_FIND, hwndFrame, FindDlgProc);
  281. }
  282.