home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / sysutils / mshell / source / object.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-16  |  9.7 KB  |  367 lines

  1. // object.c
  2.  
  3. // the object window procedure on thread 2;
  4. // tasks posted to the object window are not bound by 1/10 second rule;
  5. // post an acknowledgement message back when finished
  6.  
  7.  
  8.  
  9.  
  10. // os2 includes
  11. #define INCL_DOS
  12. #define INCL_DOSERRORS
  13. #define INCL_PM
  14. #include <os2.h>
  15.  
  16. // crt includes
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20.  
  21.  
  22.  
  23. // app includes
  24. #include "def.h"
  25. #include "mshell.h"
  26. #include "pmassert.h"
  27.  
  28.  
  29.  
  30. // my own header for this undocumented spooler-start API
  31. BOOL APIENTRY Spl32QmInitialize( PULONG pulError);
  32.  
  33.  
  34.  
  35. // ----------------------------------------------------------------
  36. // thread 2 code; gets and dispatches object window messages
  37.  
  38.  
  39. void _Optlink threadmain( void * pv  )
  40. {
  41.   BOOL       bSuccess;
  42.   HAB        hab;
  43.   HMQ        hmq;
  44.   QMSG       qmsg;
  45.   PGLOBALS   pg;
  46.  
  47.  
  48.   // cast and set the void pointer coming in
  49.   pg = (PGLOBALS) pv;
  50.  
  51.   // thread initialization
  52.   hab = WinInitialize( 0 );
  53.   hmq = WinCreateMsgQueue( hab, 0 );
  54.  
  55.   bSuccess = WinRegisterClass( hab, OBJECTCLASSNAME, ObjectWinProc, 0, sizeof( PGLOBALS ) );
  56.   pmassert( hab, bSuccess );
  57.  
  58.   // create a window where its parent is the PM object window
  59.   pg->hwndObject = WinCreateWindow( HWND_OBJECT,       // parent
  60.                                     OBJECTCLASSNAME,   // class name
  61.                                     "",                // name
  62.                                     0,                 // style
  63.                                     0,                 // x,y
  64.                                     0,
  65.                                     0,                 // cx,cy
  66.                                     0,
  67.                                     HWND_OBJECT,       // owner
  68.                                     HWND_BOTTOM,       // position behind this window (nop)
  69.                                     0,                 // id
  70.                                     (PVOID)pg,         // globals pointer as control data
  71.                                     NULL );            // presparams
  72.   pmassert( hab, pg->hwndObject );
  73.  
  74.  
  75.   // WM_CREATE processing completed; application has completely initialized
  76.   WinPostMsg( pg->hwndClient, WM_USER_ACK, (MPARAM)WM_CREATE, 0 );
  77.  
  78.  
  79.   // dispatch messages; these messages will be mostly user-defined messages
  80.   while( WinGetMsg ( hab, &qmsg, 0, 0, 0 ))  {
  81.     WinDispatchMsg ( hab, &qmsg );
  82.   }
  83.  
  84.   // wrap up
  85.   WinDestroyWindow ( pg->hwndObject );
  86.   WinDestroyMsgQueue ( hmq );
  87.   WinTerminate ( hab );
  88.  
  89.   return;
  90. }
  91.  
  92.  
  93.  
  94.  
  95.  
  96. // -----------------------------------------------------------------------
  97. // object window operated by thread 2
  98. // post wm_user messages to this window to do lengthy tasks
  99. // mp1 is the hwnd to ack when task completes
  100.  
  101.  
  102. MRESULT EXPENTRY ObjectWinProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  103. {
  104.   BOOL              bAutoStart;
  105.   BOOL              bOK;
  106.   CHAR              szTitle[ LEN_WORKSTRING ];
  107.   CHAR              szWork[ LEN_WORKSTRING ];
  108.   FILE              *f;
  109.   HAB               hab;
  110.   HWND              hwndToAck;
  111.   PCHAR             pch;
  112.   PGLOBALS          pg;
  113.   LONG              i;
  114.   LONG              cLines;
  115.   STARTDATA         sd;
  116.   ULONG             rc;
  117.   ULONG             ulProcID;
  118.   ULONG             ulSessionID;
  119.  
  120.  
  121.  
  122.   // store the handle of the window to ack upon task completion;
  123.   hwndToAck = (HWND)mp1;
  124.   hab = WinQueryAnchorBlock( hwnd );
  125.  
  126.  
  127.   switch( msg ) {
  128.  
  129.  
  130.   case WM_CREATE:
  131.     // mp1 is pointer to globals; save it in object window words
  132.     pg = (PGLOBALS)mp1;
  133.     WinSetWindowULong( hwnd, QWL_USER, (ULONG) mp1 );
  134.  
  135.  
  136.     // start the spooler ?
  137.     PrfQueryProfileString( HINI_PROFILE, "PM_SPOOLER", "SPOOL", "1;", szWork, LEN_WORKSTRING );
  138.     if( *szWork == '1' ) {
  139.  
  140.       // assume a bad spooler start
  141.       pg->fSpooler = FALSE;
  142.  
  143.       memset( &sd, 0, sizeof( STARTDATA ) );
  144.       sd.Length          = sizeof( STARTDATA );
  145.       sd.FgBg            = 1;                            // 1=background
  146.       sd.PgmTitle        = "Print Manager";
  147.       sd.PgmName         = "PMSPOOL.EXE";
  148.       sd.PgmInputs       = szWork;
  149.       sd.SessionType     = 3;                            // 3=pm
  150.       rc = DosStartSession( &sd, &ulSessionID, &ulProcID );
  151.       switch( rc ) {
  152.       case NO_ERROR:
  153.         // pmspool.exe from 1.3 started ok
  154.         pg->fSpooler = TRUE;
  155.         break;
  156.       default:
  157.         Spl32QmInitialize( &rc );
  158.         pmassert( pg->hab, 0 == rc );
  159.         pg->fSpooler = ( 0 == rc );
  160.         break;
  161.       }
  162.  
  163.       if( ! pg->fSpooler )  {
  164.         WinEnableMenuItem( pg->hwndMenubar,  IDM_SPOOLER,  FALSE );
  165.         WinPostMsg( pg->hwndClient, WM_NACK_NO_SPOOLER, 0, 0 );
  166.       }
  167.     }
  168.  
  169.  
  170.     // gather program data by parsing the INI file
  171.     if( WinSendMsg( hwnd, WM_USER_ADD_PROGRAMS, (MPARAM)hwnd, 0 )) {
  172.       // start the autostarts
  173.       for( i = 0; i < pg->cStartem; i++ ) {
  174.         if( pg->aStartem[ i ].bAutoStart ) {
  175.           WinSendMsg( hwnd, WM_USER_START, (MPARAM)hwnd, (MPARAM) i );
  176.         }
  177.       }
  178.     } else {
  179.       // no ini file
  180.       WinPostMsg( pg->hwndClient, WM_NACK_NO_INI, 0, 0 );
  181.     }
  182.  
  183.     return (MRESULT) 0;
  184.  
  185.  
  186.  
  187.  
  188.  
  189.   case WM_USER_ACK:
  190.     // nop for object window
  191.     return (MRESULT) 0;
  192.  
  193.  
  194.  
  195.   case WM_USER_ADD_PROGRAMS:
  196.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  197.  
  198.     // free allocations from the last time
  199.     for( i = 0; i < pg->cStartem; i++ ) {
  200.       if( pg->aStartem[ i ].pszTitle ) {
  201.         free( pg->aStartem[ i ].pszTitle );
  202.         pg->aStartem[ i ].pszTitle = NULL;
  203.       }
  204.       if( pg->aStartem[ i ].pszCMD ) {
  205.         free( pg->aStartem[ i ].pszCMD );
  206.         pg->aStartem[ i ].pszCMD = NULL;
  207.       }
  208.     }
  209.  
  210.     // reset how many items are startable
  211.     pg->cStartem = 0;
  212.  
  213.  
  214.     // open the text ini
  215.     f = fopen( "\\MSHELL.INI" , "r" );
  216.     if( !f ) {
  217.       // no file
  218.       WinPostMsg( hwndToAck, WM_NACK_NO_INI, (MPARAM)msg, (MPARAM) FALSE );
  219.       return (MPARAM) FALSE;
  220.     }
  221.  
  222.     // disable listbox painting
  223.     WinEnableWindowUpdate( pg->hwndListbox, FALSE );
  224.  
  225.     // delete all in listbox
  226.     WinSendMsg( pg->hwndListbox, LM_DELETEALL, 0, 0 );
  227.  
  228.  
  229.     cLines = 0;
  230.     i = 0;
  231.     while( i < LEN_STARTLIST && fgets( szWork, LEN_WORKSTRING, f )) {
  232.       cLines++;
  233.       ltrim( trim( szWork ));
  234.       memset( &(pg->aStartem[ i ]),  0, sizeof( STARTEM ));
  235.  
  236.       // comment lines begin with *
  237.       if( NULL == strchr( "*", *szWork )  && strlen( szWork ) ) {
  238.  
  239.         // not a comment and not an empty line. parse it
  240.         bOK = FALSE;
  241.  
  242.         // check for autostart symbol
  243.         bAutoStart = ('!' == *szWork);
  244.  
  245.         if( bAutoStart ) {
  246.           pch = strchr( szWork, '!' );
  247.           pmassert( pg->hab, pch );
  248.           *pch = ' ';
  249.           ltrim( szWork );
  250.         }
  251.  
  252.         // parse title up to ;
  253.         pch = strtok( szWork, ";" );
  254.         if( pch ) {
  255.           strcpy( szTitle, pch );
  256.  
  257.           // parse the rest as a CMD start command
  258.           pch = strtok( NULL, "\n" );
  259.           bOK = (BOOL) pch;
  260.         }
  261.  
  262.         // test result of parsing
  263.         if( bOK ) {
  264.           pg->aStartem[ i ].bAutoStart = bAutoStart;
  265.           pg->aStartem[ i ].pszTitle   = strdup( szTitle );
  266.           pg->aStartem[ i ].pszCMD     = strdup( pch );
  267.           WinSendMsg( pg->hwndListbox, LM_INSERTITEM, (MPARAM) LIT_END, (MPARAM) pg->aStartem[i].pszTitle );
  268.           // bump count of startable items
  269.           i++;
  270.         } else {
  271.           // fire off a nack to elicit a message box; provide line number
  272.           WinPostMsg( hwndToAck, WM_NACK_SYNTAX_ERROR, (MPARAM)msg, (MPARAM)cLines );
  273.         }
  274.       }
  275.     }
  276.     pg->cStartem = i;
  277.     fclose( f );
  278.  
  279.     if( pg->cStartem > 0 ) {
  280.       // select the first item
  281.       WinSendMsg( pg->hwndListbox, LM_SELECTITEM, (MPARAM) 0, (MPARAM) TRUE );
  282.     }
  283.  
  284.     // let listbox paint itself
  285.     WinEnableWindowUpdate( pg->hwndListbox, TRUE );
  286.  
  287.     // success
  288.     WinPostMsg( hwndToAck, WM_USER_ACK, (MPARAM)msg, (MPARAM) TRUE );
  289.     return (MRESULT) TRUE;
  290.  
  291.  
  292.  
  293.  
  294.   case WM_USER_START:
  295.     // index of program to start is in mp2
  296.  
  297.     // start an invisible, transient CMD session to handle the stored start command
  298.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  299.  
  300.     // make, modify a copy of the CMD start command
  301.     sprintf( szWork, "/c %s",  pg->aStartem[ (SHORT)mp2 ].pszCMD );
  302.  
  303.     // a startdata structure for DosStartSession that will start CMD.EXE;
  304.     // the parameter to CMD is the start command in szWork
  305.     memset( &sd, 0, sizeof( STARTDATA ));
  306.     sd.Length          = sizeof( STARTDATA );
  307.     sd.PgmInputs       = szWork;
  308.     sd.PgmControl      = SSF_CONTROL_INVISIBLE;
  309.  
  310.     rc = DosStartSession( &sd, &ulSessionID, &ulProcID );
  311.     pmassert( hab, rc == 0 ||  rc == ERROR_SMG_START_IN_BACKGROUND   );
  312.  
  313.     WinPostMsg( hwndToAck, WM_USER_ACK, (MPARAM)msg, 0 );
  314.     break;
  315.  
  316.  
  317.  
  318.  
  319.   case WM_USER_START_CMD:
  320.     // start CMD in a window; this is default for DosStartSession
  321.     memset( &sd, 0, sizeof( STARTDATA ));
  322.     sd.Length = sizeof( STARTDATA );
  323.     rc = DosStartSession( &sd, &ulSessionID, &ulProcID );
  324.     pmassert( hab, rc == 0 );
  325.     WinPostMsg( hwndToAck, WM_USER_ACK, 0, 0 );
  326.     break;
  327.  
  328.   }
  329.  
  330.   // default:
  331.   return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  332. }
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339. // ----------------------------------------------------------------------------------------------------------
  340.  
  341. char *trim( char *s )
  342. {
  343.   char *p;
  344.   p=s;
  345.   while( *s ) s++;
  346.   s--;
  347.   while( *s == '\r' || *s == ' ' || *s == '\n' || *s == '\t' ) *s-- = 0;
  348.   return p;
  349. }
  350.  
  351.  
  352.  
  353. // -----------------------------------------------------------------------
  354.  
  355. char *ltrim( char *s )
  356. {
  357.   char *p, *keep;
  358.   keep=p=s;
  359.   while( (*p) && (*p == ' ') ) p++;
  360.   if( p > s ) while( *s++ = *p++ );
  361.   return keep;
  362. }
  363.  
  364.  
  365.  
  366.  
  367.