home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / execdemo.zip / execpres.c < prev    next >
Text File  |  1994-09-03  |  9KB  |  248 lines

  1. /*
  2.  * EXECPRES.C
  3.  * Copyright 1994 Bryan Walker DBA WalkerWerks.  All rights reserved.
  4.  *
  5.  * User interface for
  6.  * Examples of using DosStartSession and WinStartApp API calls.
  7.  *
  8.  * This sample is provided to help illustrate examples for the class
  9.  * "Executing Programs in OS/2" for ColoradOS/2 1994.  The code is for
  10.  * example purposes only and not as a teaching tool for general programming principals.
  11.  * The author has no liability for any use of the code either private or commercial,
  12.  * or for any damages arrising from such use.
  13.  *
  14.  */
  15. #define INCL_DOS
  16. #define INCL_PM
  17. #include <os2.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <process.h>
  21.  
  22. #include "execpres.h"
  23. #define  NOTIFYQUEUE "\\QUEUES\\EXECPRES.QUE"
  24.  
  25. extern ULONG StartAppDos(CHAR *app, CHAR *parm, CHAR *dir, CHAR *env, SHORT type, BOOL activate, CHAR *queue) ;
  26. extern ULONG StartAppWin(CHAR *app, CHAR *parm, CHAR *dir, CHAR *env, SHORT type, BOOL activate, HWND hwndNotify) ;
  27. MRESULT EXPENTRY ExecProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) ;
  28. VOID WatchQueue(PVOID info) ;
  29.  
  30. struct _thddata
  31.    {
  32.    HQUEUE hque ;
  33.    HWND   hwnd ;
  34.    } ;
  35.  
  36. /*
  37.  * main initializes PM creates a message queue and
  38.  * processes the only dialog for this application.
  39.  */
  40. main(int argc, char *argv[], char *envp[])
  41. {
  42. HAB hab ;
  43. HMQ hmq ;
  44. HWND hwndDlg ;
  45. QMSG qmsg ;
  46. ULONG pid, tid ;
  47. HSWITCH hsw ;
  48. SWCNTRL swctl = { NULLHANDLE , NULLHANDLE , NULLHANDLE , 0 , 0 ,
  49.                   SWL_VISIBLE , SWL_JUMPABLE , "ExecPres" , 0 } ;
  50.  
  51. hab = WinInitialize(0) ;
  52. hmq = WinCreateMsgQueue(hab, 20) ;
  53.  
  54.  
  55. hwndDlg = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, ExecProc, NULLHANDLE, IDD_TOP, NULL ) ;
  56. WinQueryWindowProcess (hwndDlg, &pid, &tid);
  57. swctl.hwnd = hwndDlg;
  58. swctl.idProcess = pid;
  59. hsw = WinAddSwitchEntry (&swctl);
  60.  
  61. WinProcessDlg(hwndDlg) ;
  62.  
  63. WinRemoveSwitchEntry ( hsw ) ;
  64. WinDestroyMsgQueue(hmq) ;
  65. WinTerminate(hab) ;
  66. return 0 ;
  67. }
  68.  
  69. /*
  70.  * The dialog procedure for the panel where users enter the program
  71.  * information to run.  This is the only dialog in the program.
  72.  */
  73. MRESULT EXPENTRY ExecProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  74. {
  75. SHORT x ;
  76. HAPP  happ ;
  77. LONG  error ;
  78.  
  79. /*
  80.  * Instance data that needs to be maintained across
  81.  * PM messages.  Since PM destroys the stack between
  82.  * calls these either must be allocated or declared
  83.  * as static.  By allocating them and setting the
  84.  * User window word to the value of the pointer the
  85.  * data for multiple instances of a window is stored with
  86.  * the window structure through the pointer.
  87.  */
  88. struct StructVars
  89.    {
  90.    CHAR  App[CCHMAXPATH] ;
  91.    CHAR  Parm[CCHMAXPATH] ;
  92.    CHAR  Path[CCHMAXPATH] ;
  93.    CHAR  Env[501] ;
  94.    SHORT ApType ;
  95.    SHORT ForeBack ;
  96.    SHORT LaunchType ;
  97.    struct _thddata thddata ;
  98.    } *sv ;
  99.  
  100. sv = (struct StructVars *) WinQueryWindowULong(hwnd, QWL_USER) ;
  101. switch(msg)
  102.    {
  103.    /*
  104.     * WinStartApp() causes PM to post this message to the notify window
  105.     * for child apps that terminate.  MP1 contains the HAPP and MP2 contains
  106.     * the result code.  In addition the thread that monitors the queue for DosStartSession
  107.     * termination messages posts this message with the session id in MP1.
  108.     */
  109.    case WM_APPTERMINATENOTIFY:
  110.       happ = LONGFROMMP(mp1) ;
  111.       error = LONGFROMMP(mp2) ;
  112.       sprintf(sv->App, "Application %lu terminated with code %ld", happ, error) ;
  113.       WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, sv->App, "ExecPres", 0L, MB_NOICON|MB_ENTER) ;
  114.       return 0;
  115.  
  116.    case WM_INITDLG:
  117.       /*
  118.        * Allocate the instance data.
  119.        */
  120.       if( (sv = malloc( sizeof( struct StructVars ) ) ) == NULL )
  121.          {
  122.          WinDismissDlg(hwnd, FALSE ) ;
  123.          return 0 ;
  124.          }
  125.       memset( sv, 0, sizeof(struct StructVars) ) ;
  126.       /*
  127.        * Create the message queue for DosStartSession and start a thread
  128.        * to monitor it.
  129.        */
  130.       DosCreateQueue( &sv->thddata.hque, QUE_FIFO|QUE_CONVERT_ADDRESS, NOTIFYQUEUE ) ;
  131.       sv->thddata.hwnd = hwnd ;
  132.       _beginthread( WatchQueue, NULL, 8000, &sv->thddata ) ;
  133.  
  134.       /*
  135.        * Setup some defaults for the dialog.
  136.        */
  137.       WinSetWindowULong(hwnd, QWL_USER, (ULONG) sv ) ;
  138.       WinSendDlgItemMsg(hwnd, IDE_PROGRAM,   EM_SETTEXTLIMIT, MPFROMSHORT(256), 0L) ;
  139.       WinSendDlgItemMsg(hwnd, IDE_PARMS,     EM_SETTEXTLIMIT, MPFROMSHORT(256), 0L) ;
  140.       WinSendDlgItemMsg(hwnd, IDE_DIRECTORY, EM_SETTEXTLIMIT, MPFROMSHORT(256), 0L) ;
  141.       WinSendDlgItemMsg(hwnd, IDE_ENV      , EM_SETTEXTLIMIT, MPFROMSHORT(500), 0L) ;
  142.       WinSendDlgItemMsg(hwnd, IDR_NO, BM_SETCHECK, MPFROMSHORT(TRUE), 0L) ;
  143.       return 0 ;
  144.  
  145.    case WM_COMMAND:
  146.       switch(COMMANDMSG(&msg)->cmd)
  147.          {
  148.          case DID_OK:
  149.             /*
  150.              * Extract the entered data from the dialog and
  151.              * call the appropriate launching function.
  152.              */
  153.             WinQueryDlgItemText(hwnd, IDE_PROGRAM,   sizeof(sv->App),  sv->App) ;
  154.             WinQueryDlgItemText(hwnd, IDE_PARMS,     sizeof(sv->Parm), sv->Parm) ;
  155.             WinQueryDlgItemText(hwnd, IDE_DIRECTORY, sizeof(sv->Path), sv->Path) ;
  156.             WinQueryDlgItemText(hwnd, IDE_ENV, sizeof(sv->Env), sv->Env) ;
  157.             sv->ApType = SHORT1FROMMR(WinSendDlgItemMsg(hwnd, IDR_PM,
  158.                                        BM_QUERYCHECKINDEX, 0L, 0L)) ;
  159.             if(sv->ApType == -1)
  160.                {
  161.                WinAlarm(HWND_DESKTOP, WA_ERROR) ;
  162.                return 0 ;
  163.                }
  164.             sv->ForeBack = SHORT1FROMMR(WinSendDlgItemMsg( hwnd, IDR_NO,
  165.                              BM_QUERYCHECKINDEX, 0L, 0L)) ;
  166.             sv->LaunchType = SHORT1FROMMR(WinSendDlgItemMsg( hwnd, IDR_DOS,
  167.                              BM_QUERYCHECKINDEX, 0L, 0L)) ;
  168.             if( sv->LaunchType )
  169.                StartAppWin(sv->App, sv->Parm, sv->Path, sv->Env, sv->ApType, sv->ForeBack, hwnd ) ;
  170.             else
  171.                StartAppDos(sv->App, sv->Parm, sv->Path, sv->Env, sv->ApType, sv->ForeBack, NOTIFYQUEUE ) ;
  172.             return 0 ;
  173.  
  174.          case DID_CANCEL:
  175.             /*
  176.              * Reset the dialog to its default blank state for
  177.              * new information.
  178.              */
  179.             WinSetDlgItemText(hwnd, IDE_PROGRAM, "") ;
  180.             WinSetDlgItemText(hwnd, IDE_PARMS, "") ;
  181.             WinSetDlgItemText(hwnd, IDE_DIRECTORY, "") ;
  182.             WinSetDlgItemText(hwnd, IDE_ENV, "") ;
  183.             for(x = 0 ; x < 6 ; x++)
  184.                WinSendDlgItemMsg(hwnd, IDR_PM+x, BM_SETCHECK, MPFROMSHORT(FALSE), 0L) ;
  185.             WinSendDlgItemMsg(hwnd, IDR_NO,      BM_SETCHECK, MPFROMSHORT(TRUE), 0L) ;
  186.             WinSendDlgItemMsg(hwnd, IDR_DOS,    BM_SETCHECK, MPFROMSHORT(TRUE), 0L) ;
  187.             WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, IDE_PROGRAM) ) ;
  188.             return 0 ;
  189.  
  190.          case IDB_EXIT:
  191.             /*
  192.              * Notify the queue monitoring thread to terminate.
  193.              * then exit the dialog effectively exiting the program.
  194.              */
  195.             DosWriteQueue( sv->thddata.hque, 400, 0L, NULL, 0 ) ;
  196.             WinDismissDlg(hwnd, TRUE) ;
  197.             return 0 ;
  198.          }
  199.       break ;
  200.  
  201.    case WM_DESTROY:
  202.       /*
  203.        * Clean up our resources.
  204.        */
  205.       DosCloseQueue( sv->thddata.hque ) ;
  206.       free(sv) ;
  207.       return 0 ;
  208.    }
  209. return WinDefDlgProc(hwnd, msg, mp1, mp2) ;
  210. }
  211.  
  212.  
  213. /*
  214.  * This thread watches the DosQueue that is created for OS/2
  215.  * to notify the program through.  It then posts a WM_APPTERMINATENOTIFY
  216.  * message to the dialog just like WinStartApp().  The difference is that
  217.  * instead of a HAPP the session id is placed in mp1.
  218.  *
  219.  * A queue application data value of 400 is used to signal the thread
  220.  * to exit.  When this value is written to the queue the thread will
  221.  * not loop to start watching the queue again.
  222.  */
  223. VOID WatchQueue(PVOID info)
  224. {
  225. HQUEUE que = ((struct _thddata * )info)->hque;
  226. HWND hwndNotify = ((struct _thddata * )info)->hwnd;
  227. REQUESTDATA rq ;
  228. ULONG len ;
  229. struct  ProgDat
  230.    {
  231.    USHORT sid ;
  232.    SHORT  rc ;
  233.    } *pDat ;
  234. BYTE  priority ;
  235.  
  236. while (DosReadQueue( que, &rq, &len, (PVOID) &pDat, 0, DCWW_WAIT, &priority, 0 ) == 0)
  237.    {
  238.    if( rq.ulData == 0 && pDat != NULL )
  239.       WinPostMsg( hwndNotify, WM_APPTERMINATENOTIFY,
  240.                   MPFROMLONG( (ULONG)pDat->sid ), MPFROMLONG( (LONG) pDat->rc ) ) ;
  241.    if( pDat != NULL )
  242.       DosFreeMem(pDat) ;
  243.    if( rq.ulData == 400 )
  244.       return ;
  245.    }
  246. return ;
  247. }
  248.