MPFIND.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:9k
源码类别:

Windows编程

开发平台:

Visual C++

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