home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / rwp15.zip / FILESRCH.C < prev    next >
C/C++ Source or Header  |  1993-03-24  |  9KB  |  297 lines

  1. /* --------------------------------------------------------------------
  2.                               File Search
  3.                               Chapter 15
  4.  
  5.                     Real World Programming for OS/2
  6.              Copyright (c) 1993 Blain, Delimon, and English
  7. -------------------------------------------------------------------- */
  8.  
  9. #define INCL_DOS
  10. #define INCL_DOSFILEMGR
  11. #define INCL_WIN
  12. #define INCL_ERRORS
  13.  
  14. #include <os2.h>
  15. #include <string.h>
  16. #include "misc.h"
  17. #include "drives.h"
  18. #include "filesrch.h"
  19.  
  20. /* Thread Function */
  21.  
  22. #ifdef __WATCOM__
  23. VOID __stdcall SearchThread (HWND);
  24. #else
  25. VOID SearchThread (HWND);
  26. #endif
  27.  
  28. /* Local Functions    */
  29. VOID SearchForFile (HWND);
  30. VOID SetControlStates (HWND);
  31. VOID StartSearch (HWND);
  32. VOID StopSearch (VOID);
  33.  
  34. /* External variables */
  35. extern HAB       hab;                  /* Handle to anchor block     */
  36. extern DRIVEINFO DriveInfo[];
  37. extern ULONG     ulNumDrives;
  38.  
  39. /* Global variables */
  40. TID  SearchThreadID;                   /* Thread ID of Search thread */
  41. CHAR szFileName[CCHMAXPATHCOMP];       /* Filename to search         */
  42. CHAR szFullPath[CCHMAXPATH] = " :\\";  /* File path buffer           */
  43. HWND hWndFileSearch         = 0;       /* File search dialog window  */
  44. BOOL bSearching             = FALSE;   /* Search in progress flag    */
  45.  
  46. /* ------------------ Search Thread Function ----------------------- */
  47.  
  48. /*
  49.     The Search thread is responsible for searching the selected disk
  50.     for the specified filename.  This function will search all
  51.     subdirectories starting with the directory in szFullPath.
  52.     The field IDC_CURRENTDIR is updated with the name of each directory 
  53.     that is being searched.  Each matching filename is added to
  54.     the IDC_DIRLIST listbox.
  55.  
  56.     Since this thread will be directly updating the dialog box control
  57.     windows it must create a message queue.  Thus it will be a
  58.     Message queue thread.
  59.  
  60.     The thread is automatically terminated when all subdirectories have
  61.     been search or when the bSearching flag is reset.
  62. */
  63.  
  64. #ifdef __IBMC__
  65. #pragma linkage(SearchThread, system)
  66. #endif
  67.  
  68. #ifdef __WATCOM
  69. VOID __stdcall SearchThread (HWND hWnd)
  70. #else
  71. VOID SearchThread (HWND hWnd)
  72. #endif
  73.  
  74. {
  75.     HMQ hmqThread;
  76.     HAB habThread;
  77.  
  78.     /* Create message queue for this thread */
  79.     habThread = WinInitialize (0);
  80.     hmqThread = WinCreateMsgQueue (hab, 0);
  81.  
  82.     bSearching = TRUE;
  83.  
  84.     SetControlStates (hWnd);
  85.  
  86.     /* Perform the search */
  87.     SearchForFile (hWnd);
  88.  
  89.     bSearching = FALSE;
  90.  
  91.     SetControlStates (hWnd);
  92.  
  93.     /* Destroy the message queue for this thread */
  94.     WinDestroyMsgQueue (hmqThread);
  95.     WinTerminate (habThread);
  96.  
  97.     DosExit (EXIT_THREAD, 0L);
  98. }
  99.  
  100. /* ----------------------- Local Functions ----------------------- */
  101.  
  102. VOID SearchForFile (HWND hWnd)
  103.     HDIR         hDir        = HDIR_CREATE;
  104.     ULONG        ulDirPos    = strlen (szFullPath);
  105.     ULONG        ulFileCount = 1L;
  106.     FILEFINDBUF3 FindBuf3;
  107.  
  108.     /* Check for filename length overflow */
  109.     if ((ulDirPos + strlen(szFileName)) > CCHMAXPATH)
  110.         return;
  111.  
  112.     WinSetDlgItemText (hWnd, IDC_CURRENTDIR, szFullPath);
  113.  
  114.     /* Search for all files in directory matching the filename */
  115.     strcat (szFullPath, szFileName);    
  116.     if (!DosFindFirst (szFullPath, &hDir, FILE_NORMAL, &FindBuf3,
  117.             sizeof(FILEFINDBUF3), &ulFileCount, FIL_STANDARD))
  118.     {
  119.         do
  120.         {
  121.             szFullPath[ulDirPos] = '\0';
  122.             strncat (szFullPath, FindBuf3.achName, CCHMAXPATH);
  123.             WinSendDlgItemMsg (hWnd, IDC_DIRLIST, LM_INSERTITEM, (MPARAM)LIT_END,
  124.                 szFullPath);
  125.             ulFileCount = 1L;
  126.         }
  127.         while (bSearching &&
  128.                !DosFindNext (hDir, &FindBuf3, sizeof(FILEFINDBUF3), &ulFileCount));
  129.         DosFindClose (hDir);
  130.     }
  131.  
  132.     /* Has the user cancelled the searching? */
  133.     if (!bSearching)
  134.         return;
  135.  
  136.     /* For each subdirectory in this directory call SearchForFile */
  137.     szFullPath[ulDirPos] = '\0';
  138.     strcat (szFullPath, "*.*");
  139.     ulFileCount = 1L;
  140.     hDir        = HDIR_CREATE;
  141.     if (!DosFindFirst (szFullPath, &hDir, MUST_HAVE_DIRECTORY, &FindBuf3,
  142.             sizeof(FILEFINDBUF3), &ulFileCount, FIL_STANDARD))
  143.     {
  144.         do
  145.         {
  146.             if (!strcmp(FindBuf3.achName, ".") ||
  147.                 !strcmp(FindBuf3.achName, ".."))
  148.                 continue;
  149.  
  150.             /* Check for path name length overflow */
  151.             if ((ulDirPos + FindBuf3.cchName + 1) >= CCHMAXPATH)
  152.                 continue;
  153.  
  154.             szFullPath[ulDirPos] = '\0';
  155.             strcat (szFullPath, FindBuf3.achName);
  156.             strcat (szFullPath, "\\");
  157.             SearchForFile (hWnd);
  158.             ulFileCount = 1L;
  159.         }
  160.         while (bSearching &&
  161.                !DosFindNext (hDir, &FindBuf3, sizeof(FILEFINDBUF3), &ulFileCount));
  162.         DosFindClose (hDir);
  163.     }
  164.  
  165.     return;
  166. }
  167.  
  168. VOID SetControlStates (HWND hWnd)
  169. {
  170.     /* Show the searching fields */
  171.     WinShowWindow (WinWindowFromID (hWnd, IDC_SEARCHING), bSearching);
  172.     WinShowWindow (WinWindowFromID (hWnd, IDC_CURRENTDIR), bSearching);
  173.  
  174.     /* Disable filename and drivelist input controls */
  175.     WinEnableControl (hWnd, IDC_FILENAME, !bSearching);
  176.     WinEnableControl (hWnd, IDC_DRIVELIST, !bSearching);
  177.  
  178.     /* Change button text */
  179.     WinSetDlgItemText (hWnd, IDC_SEARCH, bSearching ? "Stop" : "Search");
  180.  
  181.     return;
  182. }
  183.  
  184. VOID StartSearch (HWND hWnd)
  185. {
  186.     ULONG ulInx;
  187.  
  188.     /* Get file spec to search */
  189.     WinQueryDlgItemText (hWnd, IDC_FILENAME, sizeof(szFileName), szFileName);
  190.     if (!szFileName[0])
  191.     {
  192.         DosBeep (750, 200);
  193.         return;
  194.     }
  195.  
  196.     /* Get drive selection and start at the root directory */
  197.     ulInx = (ULONG)WinSendDlgItemMsg (hWnd, IDC_DRIVELIST, 
  198.                        LM_QUERYSELECTION, (MPARAM)LIT_FIRST, 0L);
  199.     szFullPath[0] = DriveInfo[ulInx].szDrive[0];
  200.     szFullPath[3] = '\0';
  201.  
  202.     /* Clear the directory listbox */
  203.     WinSendDlgItemMsg (hWnd, IDC_DIRLIST, LM_DELETEALL, 0L, 0L);
  204.  
  205.     /* Start the search thread */
  206.     DosCreateThread (&SearchThreadID, (PFNTHREAD)SearchThread, (ULONG)hWnd, 0, 0x10000);
  207.  
  208.     return;
  209. }
  210.  
  211. VOID StopSearch ()
  212. {
  213.     /* Signal search thread to stop */
  214.     bSearching = FALSE;
  215.  
  216.     /* Don't attempt to call DosWaitThread here.  Doing so will hang
  217.        the process since when the search thread returns from the initial
  218.        call to SearchForFile it will call SetControlStates.  The call
  219.        to WinShowWindow, for example, will attempt to send a message to 
  220.        the control window's owner and since the main thread would be
  221.        blocked waiting for the search thread the message could not be
  222.        sent and the search thread would block. 
  223.  
  224.        The thread will terminate as soon as it sees the bSearching
  225.        flag has been set to FALSE. */
  226.  
  227.     return;
  228. }
  229.  
  230. /* ----------------------  Dialog Function ----------------------- */
  231.  
  232. VOID DoFileSearch (HWND hWnd)
  233. {
  234.     if (!hWndFileSearch)
  235.         hWndFileSearch = WinLoadDlg (HWND_DESKTOP, hWnd, FileSearchDlgProc, 
  236.                              0L, IDD_FILESEARCH, NULL);
  237.     else
  238.         WinSetActiveWindow (HWND_DESKTOP, hWndFileSearch);
  239.         
  240.     return;
  241. }
  242.  
  243. MRESULT EXPENTRY FileSearchDlgProc (HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  244. {
  245.     BOOL    bHandled = TRUE;
  246.     MRESULT mReturn  = 0;
  247.  
  248.     switch (msg)
  249.     {           
  250.         case WM_INITDLG:
  251.             QueryDrives (hWnd);
  252.             WinShowWindow (WinWindowFromID (hWnd, IDC_SEARCHING), FALSE);
  253.             WinShowWindow (WinWindowFromID (hWnd, IDC_CURRENTDIR), FALSE);
  254.             WinSendDlgItemMsg (hWnd, IDC_FILENAME, EM_SETTEXTLIMIT, 
  255.                 MPFROMSHORT(CCHMAXPATHCOMP), 0L);
  256.             break;
  257.  
  258.         case WM_COMMAND:
  259.         case WM_SYSCOMMAND:
  260.               switch (SHORT1FROMMP(mp1))
  261.             {
  262.                 case IDC_SEARCH:
  263.                     if (bSearching)
  264.                         StopSearch ();
  265.                     else
  266.                         StartSearch (hWnd);
  267.                     break;
  268.  
  269.                     case SC_CLOSE:
  270.                     if (bSearching)
  271.                         StopSearch ();
  272.                     WinDestroyWindow (hWnd);
  273.                     bHandled = TRUE;
  274.                     break;
  275.  
  276.                 default:
  277.                     bHandled = (msg == WM_COMMAND);
  278.             }
  279.             break;
  280.  
  281.         case WM_DESTROY:
  282.             hWndFileSearch = 0;
  283.             break;
  284.  
  285.         default:
  286.             bHandled = FALSE;
  287.             break;
  288.     }
  289.  
  290.     if (!bHandled)
  291.         mReturn = WinDefDlgProc (hWnd, msg, mp1, mp2);
  292.  
  293.     return (mReturn);
  294. }
  295.  
  296.