home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / pcmag / vol12n13.zip / FIND.ZIP / FINSRC.ZIP / FIND.C next >
C/C++ Source or Header  |  1993-05-02  |  28KB  |  826 lines

  1. //===========================================================
  2. // FIND - A text search utility for Windows
  3. // Copyright (C) 1993 Douglas Boling
  4. //===========================================================
  5. // Returns no. of elements
  6. #define dim(x) (sizeof(x) / sizeof(x[0]))   
  7. #define DATABUFFSIZE            32768
  8. #define OUTSIZE                 128
  9. #define SZFULLSIZE            128
  10. #define SZNAMESIZE            13
  11.  
  12. #define ERR_START                1000
  13. #define ERR_OUTOFLBSPACE    1000
  14. #define ERR_OUTOFMEM        1001
  15. #define FILLCHAR              0x2d
  16.  
  17. //-----------------------------------------------------------
  18. // Include files
  19. //-----------------------------------------------------------
  20. #include "windows.h"
  21. #include "wfext.h"
  22.  
  23. #include "stdlib.h"
  24. #include "string.h"
  25. #include "direct.h"
  26. #include "dos.h"
  27.  
  28. #include "find.h"
  29.  
  30. // File Manager Extension functions
  31. LONG DoFMExtLoad (HWND, UINT, LONG);
  32. LONG DoFMExtInitMenu (HWND, UINT, LONG);
  33.  
  34. // Prototypes for the File Manager menu extensions
  35. LONG DoFMExtFindText (HWND, UINT, LONG);
  36. LONG DoFMExtFindFile (HWND, UINT, LONG);
  37. LONG DoFMExtAbout (HWND, UINT, LONG);
  38.  
  39. // Entry Dialog box functions
  40. LONG DoInitDialogEntry (HWND, UINT, UINT, LONG);
  41. LONG DoCommandEntry (HWND, UINT, UINT, LONG);
  42. LONG DoSizeEntry (HWND, UINT, UINT, LONG);
  43.  
  44. LONG DoEntryCtlFind (HWND, UINT, HWND, UINT);
  45. LONG DoEntryCtlConfig (HWND, UINT, HWND, UINT);
  46. LONG DoEntryCtlExit (HWND, UINT, HWND, UINT);
  47.  
  48. // Utility function prototpes
  49. BOOL MyYield (void);
  50.  
  51. INT InitDLL(HANDLE);
  52. UINT FindText (HWND, char *);
  53.  
  54. //------------------------------------------------------------
  55. // Message dispatch table for FMExtensionProc
  56. //------------------------------------------------------------
  57. struct decodeFMEXT FMExtMessages[] = {
  58.     FMEVENT_LOAD, DoFMExtLoad,
  59.     FMEVENT_INITMENU, DoFMExtInitMenu,
  60.     IDM_FIND, DoFMExtFindText,
  61.     IDM_FFIND, DoFMExtFindFile,
  62.     IDM_ABOUT, DoFMExtAbout,
  63. };
  64. //------------------------------------------------------------
  65. // Message dispatch tables for EntryDlgProc
  66. //------------------------------------------------------------
  67. struct decodeUINT EntryMessages[] = {
  68.     WM_INITDIALOG, DoInitDialogEntry,
  69.     WM_COMMAND, DoCommandEntry,
  70.     WM_SIZE, DoSizeEntry,
  71. };
  72. struct decodeCMD EntryCtlItems[] = {
  73.     IDD_FIND, DoEntryCtlFind,
  74.     IDD_CONFIG, DoEntryCtlConfig,
  75.     IDCANCEL, DoEntryCtlExit
  76. };
  77.  
  78. //-----------------------------------------------------------
  79. // Global data
  80. //-----------------------------------------------------------
  81. UINT    wFMMenuDelta;
  82. HWND    hwndFMgr;
  83.  
  84. HANDLE    hInst;
  85. char szAppName[] = "Find";
  86. char szIconName[] = "Find";
  87. char szTitleText[] = "Find Window";
  88. char szProfileName[] = "winfile.ini";
  89. char szProSec[] = "Text Search Information";  
  90. char szMenuName[40];
  91.  
  92. BOOL    bChkCase, bRecurse;
  93. INT    sIncFlags;
  94. BOOL    bSearching = FALSE;
  95. char    szFileSpec[128];
  96. char    szSrchText[128];
  97. char    szOutText[OUTSIZE];
  98. PBYTE    pbDataBuff;
  99. LONG    lTotalFiles, lTotalHits, lHitFiles;
  100. UINT    usMaxLen, wSrchMenuID;
  101.  
  102. HANDLE    hDataBuff;
  103. OFSTRUCT    of;
  104. FMS_GETDRIVEINFO    fmsgdi;
  105. FMS_GETFILESEL        fmsgfs;
  106. //============================================================
  107. // DLL External Entry points and support routines
  108. //============================================================
  109. //============================================================
  110. // LibMain -- Entry point called during DLL init
  111. //============================================================
  112. INT CALLBACK LibMain (HANDLE hInstance, WORD wDataSeg, 
  113.                       WORD wHeapSize, LPSTR lpszCmdLine) {
  114.     hInst = hInstance;
  115.  
  116.     if (InitDLL (hInst))
  117.         return 0;
  118.     else
  119.         return 1;
  120. }
  121. //============================================================
  122. // WEP - DLL termination routine
  123. //============================================================
  124. INT CALLBACK WEP (int nParameter) {
  125.    
  126.     TermInstance(hInst, 0);
  127.     return 1;
  128. }
  129. //============================================================
  130. // FMExtensionProc - Entry point called by File Manager
  131. //============================================================
  132. DWORD CALLBACK FMExtensionProc (HWND hWnd, WORD wMsg, 
  133.                                 LONG lParam) {
  134.     INT i;
  135.     //
  136.     // Search message list to see if we need to handle this
  137.     // message.  If in list, call procedure.
  138.     //
  139.     hwndFMgr = hWnd;
  140.     for(i = 0; i < dim(FMExtMessages); i++) {
  141.         if(wMsg == FMExtMessages[i].Code)
  142.             return (*FMExtMessages[i].Fxn)(hWnd, wMsg, lParam);
  143.     }
  144.     return 0;
  145. }
  146. //============================================================
  147. // AboutDlgProc - About dialog box dialog procedure
  148. //============================================================
  149. BOOL CALLBACK AboutDlgProc (HWND hWnd, UINT wMsg, UINT wParam, 
  150.                             LONG lParam) {
  151.                               
  152.     if((wMsg == WM_COMMAND) && ((wParam == IDOK) || 
  153.                                 (wParam == IDCANCEL))) {
  154.         EndDialog(hWnd, 0);
  155.         return TRUE;
  156.     } 
  157.     return FALSE;
  158. }
  159. //============================================================
  160. // EntryDlgProc - Entry dialog box dialog procedure
  161. //============================================================
  162. BOOL CALLBACK EntryDlgProc(HWND hWnd, UINT wMsg, UINT wParam, 
  163.                            LONG lParam) {
  164.     INT i;
  165.     //
  166.     // Search message list to see if we need to handle this
  167.     // message.  If in list, call procedure.
  168.     //
  169.     for(i = 0; i < dim(EntryMessages); i++) {
  170.         if(wMsg == EntryMessages[i].Code)
  171.             return (BOOL) (*EntryMessages[i].Fxn)(hWnd, wMsg, 
  172.                                             wParam, lParam);
  173.     }
  174.     return FALSE;
  175. }
  176. //============================================================
  177. // ConfigDlgProc - About dialog box dialog procedure
  178. //============================================================
  179. BOOL CALLBACK ConfigDlgProc (HWND hWnd, UINT wMsg, UINT wParam, 
  180.                             LONG lParam) {
  181.     switch (wMsg) {
  182.        case WM_INITDIALOG:
  183.             CheckDlgButton (hWnd, IDD_INCHIDDEN, 
  184.                             sIncFlags & _A_HIDDEN);
  185.             CheckDlgButton (hWnd, IDD_INCRDONLY, 
  186.                             sIncFlags & _A_RDONLY);
  187.             CheckDlgButton (hWnd, IDD_INCSYSTEM, 
  188.                             sIncFlags & _A_SYSTEM);
  189.             CheckDlgButton (hWnd, IDD_INCARC, 
  190.                             sIncFlags & _A_ARCH);
  191.             break;
  192.         case WM_COMMAND:
  193.             if (wParam == IDOK) {    
  194.                 sIncFlags = 0;
  195.                 if (IsDlgButtonChecked (hWnd, IDD_INCHIDDEN) == 1)
  196.                     sIncFlags |= _A_HIDDEN;
  197.                 if (IsDlgButtonChecked (hWnd, IDD_INCRDONLY) == 1)
  198.                     sIncFlags |= _A_RDONLY;
  199.                 if (IsDlgButtonChecked (hWnd, IDD_INCSYSTEM) == 1)
  200.                     sIncFlags |= _A_SYSTEM;
  201.                 if (IsDlgButtonChecked (hWnd, IDD_INCARC) == 1)
  202.                     sIncFlags |= _A_ARCH;
  203.                 EndDialog(hWnd, 0);
  204.                 return TRUE;
  205.             }
  206.             if (wParam == IDCANCEL) {    
  207.                 EndDialog(hWnd, 0);
  208.                 return TRUE;
  209.             }
  210.     }        
  211.     return FALSE;
  212. }
  213. //-----------------------------------------------------------
  214. // Local routines for app setup and termination
  215. //-----------------------------------------------------------
  216. //-----------------------------------------------------------
  217. // InitDLL - Global initialization code for this application.
  218. //-----------------------------------------------------------
  219. INT InitDLL(HANDLE hInstance) {
  220.  
  221.     //Get data from last invocation
  222.     bRecurse = GetPrivateProfileInt (szProSec, PRO_CHKDIRS, FALSE,
  223.                                      szProfileName);
  224.     bChkCase = GetPrivateProfileInt (szProSec, PRO_CASE, FALSE,
  225.                                      szProfileName);
  226.     sIncFlags = GetPrivateProfileInt (szProSec, PRO_INC, _A_SYSTEM |
  227.                                       _A_HIDDEN | _A_RDONLY | _A_ARCH,
  228.                                       szProfileName);
  229.     GetPrivateProfileString (szProSec, PRO_MENUNAME, "Fi&nd", szMenuName,
  230.                           sizeof (szMenuName), szProfileName);
  231.     szSrchText[0] = '\0';                                      
  232.     return 0;
  233. }
  234. //------------------------------------------------------------
  235. // TermInstance - Instance termination code for this app.
  236. //------------------------------------------------------------
  237. INT TermInstance(HANDLE hinstance, int sDefRC) {
  238.  
  239.     MyWritePrivateProfileInt (szProSec, PRO_CHKDIRS, 
  240.                               bRecurse, 10, szProfileName);
  241.     MyWritePrivateProfileInt (szProSec, PRO_INC, 
  242.                               sIncFlags, 10, szProfileName);
  243.     MyWritePrivateProfileInt (szProSec, PRO_CASE, 
  244.                               bChkCase, 10, szProfileName);
  245.     WritePrivateProfileString (szProSec, PRO_MENUNAME, szMenuName,
  246.                                szProfileName);
  247.  
  248.     return sDefRC;
  249. }
  250. //============================================================
  251. // Message handling procedures for FMExtensionProc
  252. //============================================================
  253. //------------------------------------------------------------
  254. // DoFMExtLoad - Notification that the extension is being
  255. // loaded by the File Manager. 
  256. //------------------------------------------------------------
  257. LONG DoFMExtLoad (HWND hWnd, UINT wMsg, LONG lParam) {
  258.    HMENU    hMenu;
  259.  
  260.     //Get Menu delta constant   
  261.    wFMMenuDelta = ((LPFMS_LOAD) lParam)->wMenuDelta;
  262.     //
  263.     // Init the remainder of the FMS_LOAD structure   
  264.     //
  265.    ((LPFMS_LOAD) lParam)->dwSize = sizeof (FMS_LOAD);
  266.    lstrcpy (((LPFMS_LOAD) lParam)->szMenuName, szMenuName);
  267.    hMenu = LoadMenu (hInst, "FindMenu");    
  268.    ((LPFMS_LOAD) lParam)->hMenu = hMenu;
  269.     //
  270.     // NOTE! Returning the menu handle is required even though
  271.     // this is NOT what the documentation on the FMEVENT_LOAD
  272.     // message says.
  273.     //
  274.    return hMenu;
  275. }
  276. //------------------------------------------------------------
  277. // DoFMExtInitMenu - Notification that the user has selected
  278. // the extension menu.
  279. //------------------------------------------------------------
  280. LONG DoFMExtInitMenu (HWND hWnd, UINT wMsg, LONG lParam) {
  281.    INT    i, sCnt;
  282.    BOOL    bFound = FALSE;
  283.    HMENU    hMenu;
  284.  
  285.     // Get 'File' Menu
  286.     hMenu = GetMenu (hWnd);
  287.     sCnt = GetMenuItemCount (hMenu);
  288.     for (i = 0; i < sCnt; i++) {
  289.        GetMenuString (hMenu, i, szFileSpec, sizeof (szFileSpec),
  290.                       MF_BYPOSITION);
  291.        if (strcmp (szFileSpec, "&File") == 0) {
  292.            hMenu = GetSubMenu (GetMenu (hWnd), i);
  293.           bFound = TRUE;
  294.           break;
  295.        }
  296.     }
  297.     // Get Search menu
  298.     if (bFound) {
  299.         sCnt = GetMenuItemCount (hMenu);
  300.         for (i = 0; i < sCnt; i++) {
  301.            GetMenuString (hMenu, i, szFileSpec, sizeof (szFileSpec),
  302.                           MF_BYPOSITION);
  303.            if (strcmp (szFileSpec, "Searc&h...") == 0) {
  304.                 wSrchMenuID = GetMenuItemID (hMenu, i);
  305.               bFound = TRUE;
  306.               break;
  307.            }
  308.         }
  309.     }    
  310.     hMenu = HIWORD (lParam);
  311.     if (bFound) {
  312.        EnableMenuItem (hMenu, IDM_FFIND + LOWORD (lParam), 
  313.                        MF_BYCOMMAND | MF_ENABLED);
  314.     } else   
  315.        EnableMenuItem (hMenu, IDM_FFIND + LOWORD (lParam), 
  316.                        MF_BYCOMMAND | MF_GRAYED);
  317.     return 0;
  318. }
  319. //------------------------------------------------------------
  320. // DoFMExtFindText - Routine for handling user selecting
  321. // FIND TEXT addition to the File Manager menu.
  322. //------------------------------------------------------------
  323. LONG DoFMExtFindText (HWND hWnd, UINT wMsg, LONG lParam) {
  324.  
  325.     MyDisplayDialog(hInst, "EntryBox", hWnd, 
  326.                     (WNDPROC) EntryDlgProc, 0L);
  327.     return 0;
  328. }
  329. //------------------------------------------------------------
  330. // DoFMExtFindFile - Routine for handling user selecting
  331. // FIND FILE addition to the File Manager menu.
  332. //------------------------------------------------------------
  333. LONG DoFMExtFindFile (HWND hWnd, UINT wMsg, LONG lParam) {
  334.    PostMessage (hWnd, WM_COMMAND, wSrchMenuID, 0);
  335.     return 0;
  336. }
  337. //------------------------------------------------------------
  338. // DoFMExtAbout - Routine for handling user selecting
  339. // ABOUT extension addition to the File Manager menu.
  340. //------------------------------------------------------------
  341. LONG DoFMExtAbout (HWND hWnd, UINT wMsg, LONG lParam) {
  342.  
  343.     MyDisplayDialog(hInst, "AboutBox", hWnd, 
  344.                     (WNDPROC) AboutDlgProc, 0L);
  345.     return 0;
  346. }
  347. //============================================================
  348. // Message handling procedures for EntryDialog
  349. //============================================================
  350. //------------------------------------------------------------
  351. // DoInitDlgEntry - process WM_INITDIALOG message for Entry
  352. // dialog box.
  353. //------------------------------------------------------------ 
  354. LONG DoInitDialogEntry (HWND hWnd, UINT wMsg, UINT wParam, 
  355.                      LONG lParam) {
  356.     UINT    i;
  357.     HICON    hIcon;
  358.  
  359.     hIcon = LoadIcon (hInst, "FindIcon");
  360.     if (hIcon)
  361.           SetClassWord (hWnd, GCW_HICON, hIcon);
  362.     
  363.     SendDlgItemMessage (hWnd, IDD_SRCHTEXT, EM_LIMITTEXT,
  364.                         sizeof (szSrchText), 0L);
  365.     SendDlgItemMessage (hWnd, IDD_FILESPEC, EM_LIMITTEXT,
  366.                         sizeof (szFileSpec), 0L);
  367.     i = 40;
  368.     SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_SETTABSTOPS, 1, 
  369.                         (LPARAM)(LPINT)&i);
  370.     SetDlgItemText (hWnd, IDD_SRCHTEXT, szSrchText);                        
  371.  
  372.     i = (UINT) SendMessage (hwndFMgr, FM_GETSELCOUNT, 0, 0);
  373.     if (i) {
  374.        while (i > 0) {
  375.           i--;
  376.             SendMessage (hwndFMgr, FM_GETFILESEL, i,
  377.                          (LONG)(LPFMS_GETFILESEL) &fmsgfs);
  378.             SendDlgItemMessage (hWnd, IDD_FILESPEC, CB_ADDSTRING, 
  379.                                 0, (LONG)(LPSTR) fmsgfs.szName);
  380.        }
  381.     } else {
  382.         SendMessage (hwndFMgr, FM_GETDRIVEINFO, 0, 
  383.                      (LONG)(LPFMS_GETDRIVEINFO) &fmsgdi);
  384.         SendDlgItemMessage (hWnd, IDD_FILESPEC, CB_ADDSTRING, 
  385.                             0, (LONG)(LPSTR) fmsgdi.szPath);
  386.     }   
  387.     SendDlgItemMessage (hWnd, IDD_FILESPEC, CB_SETCURSEL, 
  388.                         0, 0);
  389.     GetDlgItemText (hWnd, IDD_FILESPEC, szFileSpec,
  390.                     sizeof (szFileSpec));
  391.  
  392.     CheckDlgButton (hWnd, IDD_NOCHKCASE, !bChkCase);
  393.     CheckDlgButton (hWnd, IDD_RECURSE, bRecurse);
  394.     return TRUE;
  395. }   
  396. //------------------------------------------------------------
  397. // DoCtlFindEntry - process IDD_FIND control for Entry
  398. // dialog box.
  399. //------------------------------------------------------------ 
  400. LONG DoEntryCtlFind (HWND hWnd, UINT idItem, HWND hwndCtl, 
  401.                      UINT wNotifyCode) {
  402.    UINT    i, rc = 0;
  403.     //
  404.     // If we are running, stop the search and exit
  405.     //
  406.     if (bSearching) {
  407.        bSearching = FALSE;
  408.        return TRUE;
  409.     }
  410.     //
  411.     // Get the state of the Recursion and case checkboxes
  412.     //
  413.     if (IsDlgButtonChecked (hWnd, IDD_RECURSE) == 0) 
  414.         bChkCase = FALSE;
  415.     else
  416.         bRecurse = TRUE;
  417.     if (IsDlgButtonChecked (hWnd, IDD_NOCHKCASE) == 0)
  418.         bChkCase = TRUE;
  419.     else
  420.         bChkCase = FALSE;
  421.     //
  422.     // See if user changed the file spec recieved from 
  423.     // FM, if so, throw out the old stuff and only use
  424.     // the user's file spec.
  425.     //
  426.     GetDlgItemText (hWnd, IDD_FILESPEC, szSrchText,
  427.                     sizeof (szSrchText));
  428.     if (SendDlgItemMessage (hWnd, IDD_FILESPEC, CB_FINDSTRING, 
  429.                         -1, (LONG) (LPSTR) szSrchText) == CB_ERR) {              
  430.         SendDlgItemMessage (hWnd, IDD_FILESPEC, 
  431.                             CB_RESETCONTENT, 0, 0L);
  432.         SendDlgItemMessage (hWnd, IDD_FILESPEC, CB_ADDSTRING, 
  433.                             0, (LONG)(LPSTR) szSrchText);
  434.         SendDlgItemMessage (hWnd, IDD_FILESPEC, CB_SETCURSEL, 
  435.                             0, 0);
  436.     }
  437.     //
  438.     // Reset counters, clear the outbox and set the focus there.
  439.     //    
  440.     lTotalFiles = 0;
  441.     lTotalHits = 0;
  442.     lHitFiles = 0;
  443.     usMaxLen = 0;
  444.     SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_RESETCONTENT, 
  445.                         0, 0L);
  446.     SetFocus (GetDlgItem (hWnd, IDD_OUTLIST));
  447.     //
  448.     // Get the search string. Test for null string
  449.     //
  450.     GetDlgItemText (hWnd, IDD_SRCHTEXT, szSrchText, 
  451.                     sizeof (szSrchText));
  452.     if (strlen (szSrchText) == 0) {
  453.         SetWindowText (hWnd, "Please enter search text");
  454.         SetFocus (GetDlgItem (hWnd, IDD_SRCHTEXT));
  455.         return TRUE;
  456.     }
  457.     hDataBuff = LocalAlloc (LHND, (UINT) DATABUFFSIZE);
  458.     if (hDataBuff == 0) {
  459.         bSearching = FALSE;
  460.        return TRUE;
  461.     }
  462.    pbDataBuff = LocalLock (hDataBuff);
  463.     SetDlgItemText (hWnd, IDD_FIND, "&Stop");
  464.     SetWindowText (hWnd, "Searching...");
  465.     bSearching = TRUE;
  466.     //
  467.     // Get the file spec strings from the combo box
  468.     // and search on each one.
  469.     //                    
  470.     i = (UINT) SendDlgItemMessage (hWnd, IDD_FILESPEC, 
  471.                                    CB_GETCOUNT, 0, 0);
  472.     while (i > 0 && rc == 0) {
  473.         i--;
  474.         SendDlgItemMessage (hWnd, IDD_FILESPEC, CB_GETLBTEXT,
  475.                             i, (LONG)(LPSTR) szFileSpec);
  476.         rc = FindText (hWnd, szFileSpec); 
  477.     }
  478.     bSearching = FALSE;
  479.     SetDlgItemText (hWnd, IDD_FIND, "&Find");
  480.     LocalUnlock (hDataBuff);
  481.     LocalFree (hDataBuff);
  482.     //
  483.     // Display search results
  484.     //
  485.     if (IsIconic (hWnd)) {
  486.        ShowWindow (hWnd, SW_SHOWNOACTIVATE);
  487.        MessageBeep (0);
  488.     }   
  489.     ltoa (lTotalFiles, szFileSpec, 10);
  490.     strcat (szFileSpec, " files searched. ");
  491.     switch (rc) {
  492.         case ERR_OUTOFLBSPACE:
  493.             strcat (szFileSpec, 
  494.                      "Search terminated. Out of output space");
  495.             break;
  496.  
  497.         case ERR_OUTOFMEM:
  498.             strcat (szFileSpec, 
  499.                     "Search terminated. Directory structure too deep");
  500.             break;
  501.  
  502.         default:
  503.             if (lTotalHits) {
  504.                 ltoa (lTotalHits, &szFileSpec[strlen (szFileSpec)], 10);
  505.                 strcat (szFileSpec, " matches found in ");
  506.                 ltoa (lHitFiles, &szFileSpec[strlen (szFileSpec)], 10);
  507.                 strcat (szFileSpec, " files");
  508.             } else         
  509.                 strcat (szFileSpec, "No matches found.");
  510.             break;
  511.     }
  512.     SetWindowText (hWnd, szFileSpec);
  513.     return TRUE;
  514. }
  515. //------------------------------------------------------------
  516. // DoEntryCtlConfig - process IDD_CONFIG control for Entry
  517. // dialog box.
  518. //------------------------------------------------------------ 
  519. LONG DoEntryCtlConfig (HWND hWnd, UINT idItem, HWND hwndCtl, 
  520.                       UINT wNotifyCode) {
  521.     MyDisplayDialog(hInst, "ConfigBox", hWnd, 
  522.                     (WNDPROC) ConfigDlgProc, 0L);
  523.     return 0;
  524. }
  525.  
  526. //------------------------------------------------------------
  527. // DoEntryCtlExit - process IDCANCEL control for Entry
  528. // dialog box.
  529. //------------------------------------------------------------ 
  530. LONG DoEntryCtlExit (HWND hWnd, UINT idItem, HWND hwndCtl, 
  531.                      UINT wNotifyCode) {
  532.    bSearching = FALSE;
  533.     GetDlgItemText (hWnd, IDD_SRCHTEXT, szSrchText, 
  534.                     sizeof (szSrchText));
  535.     EndDialog(hWnd, 0);
  536.     return TRUE;
  537. }
  538. //------------------------------------------------------------
  539. // DoSizeEntry - process WM_SIZE message for Entry dialog
  540. //------------------------------------------------------------ 
  541. LONG DoSizeEntry (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
  542.    
  543.     if (wParam == SIZE_MINIMIZED)
  544.         ShowWindow (hwndFMgr, SW_HIDE);
  545.     else if (wParam == SIZE_RESTORED)
  546.         ShowWindow (hwndFMgr, SW_SHOWNA);
  547.     return FALSE;
  548. }
  549.  
  550. //------------------------------------------------------------
  551. // DoCommandEntry - process WM_COMMAND message for Entry dialog
  552. // by decoding the control IDs with the CtlItems[] array, 
  553. // then Searching the corresponding function to process the command.
  554. //------------------------------------------------------------ 
  555. LONG DoCommandEntry (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
  556.     INT    i;
  557.     UINT    idItem, wNotifyCode;
  558.     HWND    hwndCtl;
  559.  
  560.     idItem = (UINT) wParam;                      // Parse Parameters
  561.     hwndCtl = (HWND) LOWORD(lParam);
  562.     wNotifyCode = (UINT) HIWORD(lParam);
  563.     //
  564.     // Call routine to handle control message
  565.     //
  566.     for(i = 0; i < dim(EntryCtlItems); i++) {
  567.         if(idItem == EntryCtlItems[i].Code)
  568.             return (*EntryCtlItems[i].Fxn)(hWnd, idItem, 
  569.                                          hwndCtl, wNotifyCode);
  570.     }
  571.     return FALSE;
  572. }
  573.  
  574. //============================================================
  575. // General helper routines
  576. //============================================================
  577. //------------------------------------------------------------
  578. // MyDisplayDialog - Display a dialog box
  579. //------------------------------------------------------------ 
  580. INT MyDisplayDialog (HINSTANCE hInstance, LPCSTR szDlgName,
  581.                      HWND hWnd, WNDPROC lpDialogProc, 
  582.                      LPARAM lParam) {
  583.     WNDPROC lpDlgProcInst;
  584.     INT        rc;
  585.  
  586.     lpDlgProcInst = MakeProcInstance(lpDialogProc, hInst);
  587.     rc = DialogBoxParam (hInstance, szDlgName, hWnd, 
  588.                          lpDlgProcInst, lParam);
  589.     FreeProcInstance(lpDlgProcInst);
  590.     return rc;                              
  591. }
  592. //------------------------------------------------------------
  593. // MyYield - Yields control to other programs, but returns
  594. // if Windows is idle.
  595. //------------------------------------------------------------
  596. BOOL MyYield (void) {
  597.    MSG    msg;
  598.    BOOL    bCont;
  599.    
  600.    bCont = TRUE;
  601.     while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
  602.        if (msg.message == WM_QUIT)
  603.           bCont = FALSE;
  604.         TranslateMessage(&msg);
  605.         DispatchMessage(&msg);
  606.     }
  607.     return bCont;
  608. }
  609. //------------------------------------------------------------
  610. // MyWritePrivateProfileInt - Writes an integer to the profile
  611. //------------------------------------------------------------
  612. BOOL MyWritePrivateProfileInt (char *szSec, char *szEntry, 
  613.                                int Num, int Base, char *szProfile) {
  614.     static char    szStr[33];
  615.                                
  616.     itoa (Num, szStr, Base);
  617.     return WritePrivateProfileString (szSec, szEntry, szStr, 
  618.                                       szProfile);
  619. }
  620. //============================================================  
  621. // Program specific procedures
  622. //============================================================
  623. UINT DisplayLine (HWND hWnd, char *szFilename, LONG lLineCnt, 
  624.                   UINT usMatchLen, char *pszFoundPtr, 
  625.                   char *pszLineStart, BOOL bBinary, UINT usBytesRead) {
  626.    INT    i, j, sLen;
  627.    char    *pszEnd;
  628.    char    ch;
  629.  
  630.     lTotalHits++;   
  631.     strcpy (szOutText, szFilename);
  632.     if (bBinary) 
  633.         strcat (szOutText, " \tOffset: ?");
  634.     else
  635.         strcat (szOutText, " \tLine: ?");
  636.  
  637.     ltoa (lLineCnt, strrchr (szOutText, '?'), 10);
  638.     strcat (szOutText, "  \t");
  639.     j = min (sizeof (szOutText) - strlen (szOutText),
  640.              (UINT) pbDataBuff + usBytesRead - (UINT) pszLineStart);
  641.     if (pszLineStart + j < pszFoundPtr)
  642.        pszLineStart = pszFoundPtr - j + usMatchLen;
  643.  
  644.     if (j > 0) {
  645.         if (bBinary)
  646.             for (i = 0; i < j; i++)
  647.                if (*(pszLineStart+i) < ' ')
  648.                   *(pszLineStart+i) = (char) FILLCHAR;
  649.                
  650.        ch = *(pszLineStart + j);
  651.        *(pszLineStart + j) = 0;
  652.         pszEnd = strchr (pszLineStart, 0x0d);
  653.         if (pszEnd != 0)
  654.             *pszEnd = '\0';
  655.         sLen = strlen (szOutText);
  656.         strncpy (szOutText+sLen, pszLineStart, j);
  657.         szOutText[sLen+j] = '\0';
  658.         if (pszEnd != 0)                           
  659.             *pszEnd = 0x0d;
  660.        *(pszLineStart + j) = ch;
  661.     }
  662.     if (SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_ADDSTRING, 0, 
  663.          (LPARAM) (LPSTR)szOutText) == LB_ERRSPACE)
  664.         return ERR_OUTOFLBSPACE;
  665.     else
  666.         return 0;
  667. }
  668. //------------------------------------------------------------
  669. // Searchfile - Searches a file for text.
  670. //------------------------------------------------------------
  671. UINT SearchFile (HWND hWnd, char *szFilename) {
  672.    HANDLE    hSrc;
  673.    UINT        i, rc = 0, usBytesRead, usLen, usOutLen;
  674.    char         *pszLineStart;
  675.    char        *pszDataPtr;
  676.    LONG        lOffset = 0, lLineCnt = 1;
  677.    BOOL        bFound = FALSE, bBinary = FALSE;
  678.    
  679.     usLen = strlen (szSrchText);
  680.     hSrc = OpenFile (szFilename, &of, OF_READ);
  681.     if (hSrc != -1) {
  682.         strcpy (szOutText, "Searching ");
  683.         strcat (szOutText, szFilename);
  684.         SetWindowText (hWnd, szOutText);
  685.       lTotalFiles++;
  686.        do {
  687.             usBytesRead = _lread (hSrc, (LPBYTE) pbDataBuff, 
  688.                                   (UINT) DATABUFFSIZE);
  689.             if (usBytesRead < usLen) break;
  690.             pszDataPtr = (char *)pbDataBuff;
  691.            pszLineStart = pszDataPtr;
  692.             if (bChkCase) {
  693.                 for (i = 0; (i <= usBytesRead - usLen) && (rc == 0); i++) {
  694.                       if (strncmp (pszDataPtr, szSrchText, usLen) == 0) {
  695.                          if (bBinary) {
  696.                             lLineCnt = lOffset + pszDataPtr - pbDataBuff;
  697.                             pszLineStart = max (pszDataPtr-16, pbDataBuff);
  698.                          }   
  699.                          rc = DisplayLine (hWnd, szFilename, lLineCnt, 
  700.                                            usLen, pszDataPtr, 
  701.                                            pszLineStart, bBinary,
  702.                                            usBytesRead);
  703.                             bFound = TRUE;
  704.                         }    
  705.                    if ((*pszDataPtr == 0x0a) || (*pszDataPtr == 0x0d)) {
  706.                        lLineCnt++;
  707.                        pszLineStart = pszDataPtr+1;
  708.                    } else if ((*pszDataPtr != '\t') && ((BYTE)*pszDataPtr < ' ')) 
  709.                       bBinary = TRUE;                      
  710.                     pszDataPtr++;
  711.                 }    
  712.             } else {
  713.                 for (i = 0; (i <= usBytesRead - usLen) && (rc == 0); i++) {
  714.                        if (strnicmp (pszDataPtr, szSrchText, usLen) == 0) {
  715.                          if (bBinary) {
  716.                             lLineCnt = lOffset + pszDataPtr - pbDataBuff;
  717.                             pszLineStart = max (pszDataPtr-16, pbDataBuff);
  718.                          }   
  719.                            rc = DisplayLine (hWnd, szFilename, lLineCnt, 
  720.                                              usLen, pszDataPtr, 
  721.                                              pszLineStart, bBinary,
  722.                                            usBytesRead);
  723.  
  724.                             bFound = TRUE;
  725.                         }    
  726.                    if ((*pszDataPtr == 0x0a) || (*pszDataPtr == 0x0d)) {
  727.                        pszLineStart = pszDataPtr+1;
  728.                        if (*pszDataPtr == 0x0d) lLineCnt++;
  729.                    } else if ((*pszDataPtr != '\t') && ((BYTE)*pszDataPtr < ' ')) 
  730.                       bBinary = TRUE;                      
  731.                     pszDataPtr++;
  732.                 }    
  733.             }
  734.             _llseek (hSrc, -(LONG)(usLen-1), 1);
  735.             lOffset = lOffset + usBytesRead - usLen - 1;
  736.             usMaxLen = max (usMaxLen, usOutLen);        
  737.            MyYield ();                                        //Yield to other apps
  738.         } while (usBytesRead == DATABUFFSIZE && rc == 0 && bSearching);
  739.         _lclose (hSrc);        
  740.     }
  741.     if (bFound)
  742.       lHitFiles++;
  743.    return rc;
  744. }   
  745. //------------------------------------------------------------
  746. // FindText - Searches for text in a list of files.
  747. //------------------------------------------------------------
  748. UINT FindText (HWND hWnd, char *szPath) {
  749.    FIND_T    *pfs;
  750.     INT    rc;
  751.     char    *pszEoP;
  752.     char    *pszName;
  753.     char    *pszFull;
  754.     UINT    usLen;
  755.  
  756.     if (!bChkCase)
  757.        strupr (szSrchText);
  758.    strupr (szPath);
  759.     pszName = (char *) LocalAlloc (LPTR, SZNAMESIZE + SZFULLSIZE + 
  760.                                          sizeof (FIND_T));
  761.     if (pszName == 0) {
  762.         bSearching = FALSE;
  763.        return ERR_OUTOFMEM;
  764.     }
  765.     pszFull = pszName + SZNAMESIZE;
  766.    pfs = (FIND_T *) ((PBYTE)pszFull + SZFULLSIZE);
  767.     _fullpath (pszFull, szPath, SZFULLSIZE);
  768.  
  769.     usLen = strlen (pszFull);
  770.     rc = chdir (pszFull);
  771.     if (rc == 0) {
  772.        if (pszFull[usLen-1] != '\\')
  773.           strcat (pszFull, "\\");
  774.         strcat (pszFull, "*.*");
  775.     }
  776.    if (*strrchr (pszFull,'\\') != 0)
  777.           pszEoP = strrchr (pszFull,'\\')+1;
  778.       else if (*strrchr (pszFull,':') != 0)
  779.           pszEoP = strrchr (pszFull,':')+1;
  780.       else
  781.         pszEoP = pszFull;
  782.     *pszName = '\0';
  783.     if (rc ==  HFILE_ERROR)
  784.         strcpy (pszName, pszEoP);
  785.     //
  786.     // File search
  787.     //
  788.     rc = _dos_findfirst (pszFull, sIncFlags, pfs);
  789.     while (rc == 0 && bSearching) {
  790.        strcpy (pszEoP, pfs->name);
  791.        usLen = usMaxLen;
  792.        rc = SearchFile (hWnd, pszFull);
  793.        if (usLen < usMaxLen) {
  794.             SendDlgItemMessage (hWnd, IDD_OUTLIST, 
  795.                                 LB_SETHORIZONTALEXTENT, 
  796.                                 usMaxLen * 10, 0L);
  797.         }
  798.         if (rc == 0)
  799.             rc = _dos_findnext (pfs);
  800.     }
  801.     //
  802.     // Directory search
  803.     //
  804.     if (bRecurse && bSearching) {
  805.         strcpy (pszEoP, "*.*");
  806.         rc = _dos_findfirst (pszFull, sIncFlags | _A_SUBDIR, pfs);
  807.         while (rc == 0 && bSearching) {
  808.             if ((pfs->attrib & _A_SUBDIR) &&
  809.                 (strcmp (pfs->name, ".") != 0) &&
  810.                 (strcmp (pfs->name, "..") != 0)) {
  811.                 strcpy (pszEoP, pfs->name);
  812.                 if (*pszName != '\0') {
  813.                     strcat (pszEoP, "\\");
  814.                     strcat (pszEoP, pszName);
  815.                 }    
  816.                 rc = FindText (hWnd, pszFull);
  817.             }    
  818.             if (rc == 0)
  819.                 rc = _dos_findnext (pfs);
  820.         }    
  821.     }
  822.     if (rc < ERR_START) rc = 0;
  823.     LocalFree ((HLOCAL) pszName);
  824.     return rc;
  825. }
  826.