home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1998 February / PCOnline_02_1998.iso / filesbbs / win3x / pgpjn.exe / JNSOURCE.ZIP / WINEXEJN.CPP < prev    next >
C/C++ Source or Header  |  1995-11-30  |  5KB  |  181 lines

  1. //    WINEXEJN.CPP
  2. //
  3. //    Execute another application and wait until it completes.
  4. //
  5. //    Adapted by John Navas from code made available by Microsoft.
  6.  
  7. #define STRICT
  8. #include <windows.h>
  9. #include <shellapi.h>
  10. #include <ctype.h>
  11. #include <direct.h>
  12. #include <stdlib.h>
  13.  
  14. #include "winexejn.h"
  15.  
  16. ////////////////////////////////////////////////////////////////////////////////
  17.  
  18. // used to search for window of executed program
  19. typedef struct _ENUMINFO {
  20.     HINSTANCE hInstance;        // Supplied on input.
  21.     HWND hWnd;                  // Filled in by enum function.
  22. } ENUMINFO, FAR *LPENUMINFO;
  23.  
  24. // Define a structure used to hold info about an app we
  25. // start with ExecApp so that this info can be used again
  26. // later to test if the app is still running
  27. typedef struct _EXECAPPINFO {
  28.     HINSTANCE hInstance;            // The instance value
  29.     HWND hWnd;                      // The main window handle
  30.     HTASK hTask;                    // The task handle
  31. } EXECAPPINFO, *PEXECAPPINFO;
  32.  
  33. ////////////////////////////////////////////////////////////////////////////////
  34.  
  35. // search for the window of an executed program
  36. BOOL
  37. CALLBACK
  38. EnumWndProc(
  39. HWND hWnd,
  40. LPARAM lParam
  41. )
  42. {
  43.     HINSTANCE hInstance;
  44.     LPENUMINFO lpInfo;
  45.  
  46.     lpInfo = (LPENUMINFO) lParam;
  47.  
  48.     hInstance = (HINSTANCE) GetWindowWord(hWnd, GWW_HINSTANCE);
  49.  
  50.     if (hInstance == lpInfo->hInstance) {
  51.         lpInfo->hWnd = hWnd;
  52.         return FALSE;
  53.     }
  54.  
  55.     return TRUE;
  56. }
  57.  
  58. // Try running an app by calling WinExec.  If it works, return some
  59. // info about the app in the struct pointed to by pInfo.
  60. // It returns RAN_OK, NOT_FOUND or SOME_ERROR.
  61. static
  62. int
  63. TryWinExec(
  64. const char* pszPath,                    // pathname of program to execute
  65. const char* pszParams,                    // command line parameters
  66. const char* pszCWD,                        // working directory
  67. UINT fiCmdShow,                            // window state
  68. PEXECAPPINFO pInfo                        // return app info here
  69. )
  70. {
  71.     HINSTANCE uiResult;
  72.     ENUMINFO EnumInfo;                    // used to enumerate windows
  73.  
  74.     // execute program
  75.        uiResult = ShellExecute(NULL, NULL, pszPath, pszParams, pszCWD, fiCmdShow);
  76.  
  77.     // check results of WinExec
  78.     switch ((UINT) uiResult) {
  79.     case 2:
  80.     case 3:
  81.         return NOT_FOUND;
  82.     default:
  83.         if (((UINT) uiResult) <= 32)
  84.             return SOME_ERROR;
  85.     }
  86.  
  87.     // The app is running (or at least it was) so return some info about it
  88.  
  89.     pInfo->hInstance = uiResult;
  90.  
  91.     // Find the window handle of the instance by enumerating all
  92.     // the main windows until we find one with the correct
  93.     // instance value
  94.  
  95.     EnumInfo.hInstance = pInfo->hInstance;
  96.     EnumInfo.hWnd = NULL;
  97.  
  98.     // I don't have to use MakeProcInstance because this goes in a DLL
  99.     EnumWindows((WNDENUMPROC) EnumWndProc, (LPARAM)(LPENUMINFO)&EnumInfo);
  100.  
  101.     if (! EnumInfo.hWnd) {
  102.         // Didn't find a matching window so the task probably
  103.         // isn't running any more.  Maybe it did what it had to
  104.         // and went away already.
  105.         pInfo->hWnd = NULL;
  106.         pInfo->hTask = NULL;
  107.     }
  108.     else {
  109.         // We have the window handle. Now get the task.
  110.         pInfo->hWnd = EnumInfo.hWnd;
  111.         pInfo->hTask = GetWindowTask(pInfo->hWnd);
  112.     }
  113.  
  114.     return RAN_OK;
  115. }
  116.  
  117. ////////////////////////////////////////////////////////////////////////////////
  118.  
  119. // check to see if an app is running
  120. static
  121. BOOL                                    // TRUE if app is running
  122. IsAppRunning(PEXECAPPINFO pInfo)
  123. {
  124.     // make sure window and task are still valid
  125.     if (! IsWindow(pInfo->hWnd) || ! IsTask(pInfo->hTask))
  126.         return FALSE;
  127.     // check instance against window
  128.     if ((HINSTANCE) GetWindowWord(pInfo->hWnd, GWW_HINSTANCE) != pInfo->hInstance)
  129.         return FALSE;
  130.     // check task against window
  131.     if (GetWindowTask(pInfo->hWnd) != pInfo->hTask)
  132.         return FALSE;
  133.     // app is running!
  134.     return TRUE;
  135. }
  136.  
  137. ////////////////////////////////////////////////////////////////////////////////
  138.  
  139. int
  140. WinExeJN(
  141. const char* pszPath,                    // pathname of program to execute
  142. const char* pszParams,                    // command line parameters
  143. const char* pszCWD,                        // working directory
  144. UINT fiCmdShow                            // window state
  145. )
  146. {
  147.     EXECAPPINFO Info;                    // return app info here
  148.     int i;
  149.     HCURSOR hcurSave = SetCursor(LoadCursor(NULL, IDC_WAIT));    // hourglass
  150.  
  151.     // do the execution
  152.     i = TryWinExec(pszPath,                // pathname of program to execute
  153.             pszParams,                    // command line parameters
  154.             pszCWD,                        // working directory
  155.             fiCmdShow,                    // window state
  156.             &Info);                        // return app info here
  157.  
  158.     // wait for app to finish
  159.     if (RAN_OK == i)
  160.         while (IsAppRunning(&Info)) {    // use PeekMessage to permit multitasking
  161.             MSG msg;
  162.  
  163.             if (GetMessage(&msg, NULL, 0, 0)) {
  164.  
  165.                 TranslateMessage(&msg);
  166.                 DispatchMessage(&msg);
  167.  
  168.                 if (WM_MOUSEMOVE == msg.message)
  169.                     SetCursor(LoadCursor(NULL, IDC_WAIT));    // redisplay hourglass
  170.             }
  171.         }
  172.  
  173.     SetCursor(hcurSave);                // remove hourglass
  174.  
  175.     return i;
  176. }
  177.  
  178. ////////////////////////////////////////////////////////////////////////////////
  179.  
  180. //    WINEXEJN.CPP
  181.