home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / sysutils / mshell / source / mshell.c < prev    next >
Text File  |  1993-10-16  |  11KB  |  364 lines

  1. // mshell.c  a set runworkplace=mshell.exe in config.sys shell (os2 2.0)
  2.  
  3.  
  4. #define INCL_BASE
  5. #define INCL_PM
  6. #include <os2.h>
  7.  
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #include "def.h"
  14. #include "mshell.h"
  15. #include "pmassert.h"
  16.  
  17.  
  18.  
  19. // -------------------------------------------------------------------
  20.  
  21.  
  22. int main( int argc, char **argv )
  23. {
  24.   BOOL          bOK;
  25.   HAB           hab;
  26.   HMQ           hmq;
  27.   HSWITCH       hsw;
  28.   HWND          hwndClient;
  29.   HWND          hwndFrame;
  30.   PGLOBALS      pg;
  31.   QMSG          qmsg;
  32.   SWCNTRL       swctl;
  33.   ULONG         CtlData;
  34.   ULONG         rc;
  35.  
  36.  
  37.   hab = WinInitialize( 0 );
  38.   hmq = WinCreateMsgQueue( hab, 0 );
  39.  
  40.   WinRegisterClass( hab, CLASSNAME, ClientWinProc, CS_SIZEREDRAW, sizeof( PGLOBALS ) );
  41.  
  42.   // create invisible
  43.   CtlData = FCF_SYSMENU | FCF_TITLEBAR | FCF_SIZEBORDER | FCF_MINMAX |  FCF_MENU | FCF_ICON;
  44.   hwndFrame = WinCreateStdWindow( HWND_DESKTOP, 0, &CtlData, CLASSNAME, CAPTION, 0, (HMODULE)0, ID_PMPGM, &hwndClient );
  45.   pmassert( hab, hwndFrame );
  46.  
  47.   // get global pointer stored by wm_create processing
  48.   pg = (PGLOBALS) WinQueryWindowULong( hwndClient, QWL_USER );
  49.   pmassert( hab, pg );
  50.  
  51.   // store my msg queue handle in there
  52.   pg->hmq = hmq;
  53.  
  54.   // set position of minimized mshell window
  55.   bOK = WinSetWindowUShort( pg->hwndFrame, QWS_XMINIMIZE, (USHORT)pg->profile.swpMinimized.x );
  56.   pmassert( hab, bOK );
  57.   bOK = WinSetWindowUShort( pg->hwndFrame, QWS_YMINIMIZE, (USHORT)pg->profile.swpMinimized.y );
  58.   pmassert( hab, bOK );
  59.  
  60.   // use profiled placement for restored size
  61.   rc = WinSetWindowPos( pg->hwndFrame,
  62.                         (HWND)0,
  63.                         pg->profile.swp.x,
  64.                         pg->profile.swp.y,
  65.                         pg->profile.swp.cx,
  66.                         pg->profile.swp.cy,
  67.                         SWP_SIZE | SWP_MOVE | SWP_ACTIVATE );
  68.   pmassert( hab, rc );
  69.  
  70.   // add program to task list
  71.   memset( &swctl, 0, sizeof( SWCNTRL ));
  72.   strcpy( swctl.szSwtitle, CAPTION    );
  73.   swctl.hwnd          = hwndFrame;
  74.   swctl.uchVisibility = SWL_VISIBLE;
  75.   swctl.fbJump        = SWL_JUMPABLE;
  76.   hsw = WinAddSwitchEntry( &swctl );
  77.  
  78.   // make it visible
  79.   WinShowWindow( pg->hwndFrame, TRUE );
  80.  
  81.   // use break statement to get out of this message loop
  82.   for(;;) {
  83.  
  84. #if 1
  85.     // until I call winshutdownsystem, toss out quit messages
  86.     if( ! pg->fShutdownCalled ) {
  87.       WinPeekMsg( hab, &qmsg, 0, WM_QUIT, WM_QUIT, PM_REMOVE );
  88.     }
  89.  
  90.     if( WinGetMsg( hab, &qmsg, 0, 0, 0 )) {
  91.       WinDispatchMsg( hab, &qmsg );
  92.     } else break;
  93.  
  94. #endif
  95.  
  96. #if 0
  97.     WinGetMsg( hab, &qmsg, 0, 0, 0 );
  98.     WinDispatchMsg( hab, &qmsg );
  99. #endif
  100.  
  101.   }
  102.  
  103.  
  104.   // wrap up
  105.   WinRemoveSwitchEntry( hsw );
  106.   WinDestroyWindow ( hwndFrame );
  107.   WinDestroyMsgQueue ( hmq );
  108.   WinTerminate ( hab );
  109.  
  110.   return 0;
  111. }
  112.  
  113.  
  114.  
  115.  
  116. //--------------------------------------------------------------------------------------------------
  117.  
  118.  
  119.  
  120. MRESULT EXPENTRY ClientWinProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  121. {
  122.   PGLOBALS            pg;
  123.   RECTL               rectl;
  124.   ULONG               rc;
  125.   LONG                lrc;
  126.   char                szWork[ LEN_WORKSTRING ];
  127.   FILE                *f;
  128.   SWP                 swp;
  129.  
  130.  
  131.  
  132.  
  133.   switch( msg ) {
  134.  
  135.  
  136.  
  137.   case WM_CLOSE:
  138.     // mshell does not close, but at least it can minimize and get out of the way
  139.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  140.     WinSetWindowPos( pg->hwndFrame, HWND_BOTTOM, 0, 0, 0, 0, SWP_MINIMIZE );
  141.     return (MRESULT) 0;
  142.  
  143.  
  144.   case WM_CREATE:
  145.     // see create.c
  146.     pg = Create( hwnd );
  147.     break;
  148.  
  149.   case WM_COMMAND:
  150.     // see menu.c
  151.     return Command( hwnd, msg, mp1, mp2 );
  152.  
  153.  
  154.   case WM_CONTROL:
  155.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  156.     switch( SHORT1FROMMP( mp1 )) {
  157.     case ID_LISTBOX:
  158.       switch( SHORT2FROMMP( mp1 )) {
  159.       case LN_ENTER:
  160.         // user wants to start a program
  161.         WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, 0, 0 );
  162.         // see object.c
  163.         // get index from listbox; works as index to aStartem array
  164.         lrc = (LONG) WinSendMsg( pg->hwndListbox, LM_QUERYSELECTION, (MPARAM)LIT_FIRST, 0 );
  165.         pmassert( pg->hab, LIT_NONE != lrc );
  166.         // pass index of program to start in mp2
  167.         WinPostMsg( pg->hwndObject, WM_USER_START,  (MPARAM) hwnd, (MPARAM) lrc );
  168.         break;
  169.       }
  170.       break;
  171.     }
  172.     return (MRESULT) 0;
  173.  
  174.  
  175.   case WM_ERASEBACKGROUND:
  176.     // see Petzold, WM_PAINT below
  177.     return (MRESULT) 1;
  178.  
  179.  
  180.  
  181.   case WM_MOUSEMOVE:
  182.     // display which pointer?
  183.     if( WinIsWindowEnabled( hwnd )) {
  184.       // not disabled; display regular pointer
  185.       WinSetPointer( HWND_DESKTOP, WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, FALSE ));
  186.     } else {
  187.       // disabled; display hourglass
  188.       WinSetPointer( HWND_DESKTOP, WinQuerySysPointer( HWND_DESKTOP, SPTR_WAIT, FALSE ));
  189.     }
  190.     return (MRESULT) 0;
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.   case WM_NACK_NO_INI:
  200.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  201.     WinSendMsg( hwnd, WM_USER_ENABLE_CLIENT, 0, 0 );
  202. #define PSZNOINIPROMPT "\
  203. Can't find \\MSHELL.INI, a plain text file used to configure MShell.\n\
  204. \n\
  205. Create a default one?"
  206.     rc = (ULONG)WinMessageBox( HWND_DESKTOP, pg->hwndFrame, PSZNOINIPROMPT, CAPTION, 0, MB_ICONEXCLAMATION | MB_YESNOCANCEL );
  207.     if( MBID_YES == rc ) {
  208. #define PSZDEFINI "\
  209. * MSHELL.INI defines programs that MShell can start\n\
  210. * Configure MSHELL.EXE using the RUNWORKPLACE setting in CONFIG.SYS\n\
  211. * MSHELL.EXE finds its INI in the root of the boot drive\n\
  212. * Each line in the INI file has two parts:\n\
  213. *  1: program title text to appear in MShell window\n\
  214. *  2: the CMD.EXE start command to start the program\n\
  215. * Separate the parts with a semicolon\n\
  216. * Lines starting with ! start automatically at bootup\n\
  217. * Comment lines begin with  *\n\
  218. \n\
  219. * command processors\n\
  220. OS/2 Command Prompt; start /f\n\
  221. DOS Command Prompt; start /f /fs /dos\n\
  222. Win-OS/2; start /fs /dos /c winos2\n\
  223. \n\
  224. * other stuff\n\
  225. Help for Start; start help start\n\
  226. Solitaire; start /f klondike\n\
  227. \n\
  228. * example to start from other than C:\\\n\
  229. * PM Program; d: & cd \\pmpgm & start pmpgm\n"
  230.  
  231.       if( f = fopen( "\\MSHELL.INI", "w" )) {
  232.         fprintf( f, PSZDEFINI );
  233.         fclose( f );
  234.       }
  235.       // make like user pressed refresh
  236.       WinPostMsg( hwnd, WM_COMMAND, (MPARAM)IDM_REFRESH, 0 );
  237.     }
  238.     return (MRESULT) 0;
  239.  
  240.  
  241.  
  242.  
  243.  
  244.   case WM_NACK_NO_SPOOLER:
  245.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  246.     WinMessageBox( HWND_DESKTOP, pg->hwndFrame, "Sorry, could not start the spooler.", CAPTION, 0, MB_CANCEL );
  247.     return (MRESULT) 0;
  248.  
  249.  
  250.   case WM_NACK_SYNTAX_ERROR:
  251.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  252.     // line number of INI file in mp2
  253.     sprintf( szWork, "Line %d of \\mshell.ini is unrecognized.", (SHORT) mp2 );
  254.     WinMessageBox( HWND_DESKTOP, pg->hwndFrame, szWork, CAPTION, 0, MB_CANCEL );
  255.     return (MRESULT) 0;
  256.  
  257.  
  258.   case WM_PAINT:
  259.     // see WM_ERASEBACKGROUND above;
  260.     // see Petzold sections on control windows which are children of the client window
  261.     break;
  262.  
  263.  
  264.  
  265.   case WM_SAVEAPPLICATION:
  266.     // save restored position
  267.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  268.     WinQueryWindowPos( pg->hwndFrame, &swp );
  269.  
  270.     if( swp.fl &  SWP_MINIMIZE ) {
  271.       // mshell is currently minimized
  272.       pg->profile.swpMinimized.x  = swp.x;
  273.       pg->profile.swpMinimized.y  = swp.y;
  274.       // get restored size from window words
  275.       pg->profile.swp.x  = WinQueryWindowUShort( pg->hwndFrame, QWS_XRESTORE  );
  276.       pg->profile.swp.y  = WinQueryWindowUShort( pg->hwndFrame, QWS_YRESTORE  );
  277.       pg->profile.swp.cx = WinQueryWindowUShort( pg->hwndFrame, QWS_CXRESTORE );
  278.       pg->profile.swp.cy = WinQueryWindowUShort( pg->hwndFrame, QWS_CYRESTORE );
  279.     } else if( swp.fl &  SWP_MAXIMIZE ) {
  280.       // mshell is currently maximized
  281.       // get restored size from window words
  282.       pg->profile.swp.x  = WinQueryWindowUShort( pg->hwndFrame, QWS_XRESTORE  );
  283.       pg->profile.swp.y  = WinQueryWindowUShort( pg->hwndFrame, QWS_YRESTORE  );
  284.       pg->profile.swp.cx = WinQueryWindowUShort( pg->hwndFrame, QWS_CXRESTORE );
  285.       pg->profile.swp.cy = WinQueryWindowUShort( pg->hwndFrame, QWS_CYRESTORE );
  286.       // get minimized icon position from window words
  287.       pg->profile.swpMinimized.x  = WinQueryWindowUShort( pg->hwndFrame, QWS_XMINIMIZE );
  288.       pg->profile.swpMinimized.y  = WinQueryWindowUShort( pg->hwndFrame, QWS_YMINIMIZE );
  289.     } else {
  290.       // mshell is in the restored state
  291.       pg->profile.swp = swp;
  292.       // get minimized icon position from window words
  293.       pg->profile.swpMinimized.x  = WinQueryWindowUShort( pg->hwndFrame, QWS_XMINIMIZE );
  294.       pg->profile.swpMinimized.y  = WinQueryWindowUShort( pg->hwndFrame, QWS_YMINIMIZE );
  295.     }
  296.     // write to ini
  297.     PrfWriteProfileData( HINI_PROFILE, INI_APP, INIKEY_PROFILE, (PVOID)&pg->profile, sizeof( PROFILE ));
  298.  
  299. #if 0
  300.     // save restored position
  301.     // TO DO: save icon position
  302.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  303.     WinQueryWindowPos( pg->hwndFrame, &(pg->profile.swp) );
  304.     if( 0 == ( pg->profile.swp.fl & ( SWP_MINIMIZE | SWP_MAXIMIZE ))) {
  305.       // app in restored state, swp struct fine the way it is.
  306.     }else{
  307.       // app currently min'd or max'd. pull restore info from win words
  308.       pg->profile.swp.x  = WinQueryWindowUShort( pg->hwndFrame, QWS_XRESTORE);
  309.       pg->profile.swp.y  = WinQueryWindowUShort( pg->hwndFrame, QWS_YRESTORE);
  310.       pg->profile.swp.cx = WinQueryWindowUShort( pg->hwndFrame, QWS_CXRESTORE);
  311.       pg->profile.swp.cy = WinQueryWindowUShort( pg->hwndFrame, QWS_CYRESTORE);
  312.     }
  313.     // write to ini
  314.     PrfWriteProfileData( HINI_PROFILE, INI_APP, INIKEY_PROFILE, (PVOID)&(pg->profile), sizeof( PROFILE ));
  315. #endif
  316.  
  317.     break;
  318.  
  319.  
  320.  
  321.   case WM_SIZE:
  322.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  323.     WinQueryWindowRect( hwnd, &rectl );
  324.     WinSetWindowPos( pg->hwndListbox, HWND_TOP, 0, 0,  rectl.xRight, rectl.yTop, SWP_SIZE | SWP_MOVE | SWP_SHOW );
  325.     return (MRESULT) 0;
  326.  
  327.  
  328.  
  329.   case WM_USER_ACK:
  330.     // re-enable the window
  331.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  332.     switch( (ULONG)mp1 ) {
  333.     case WM_CREATE:
  334.       WinSetFocus( HWND_DESKTOP, pg->hwndListbox );
  335.       break;
  336.     }
  337.     WinSendMsg( hwnd, WM_USER_ENABLE_CLIENT, 0, 0 );
  338.     return (MRESULT) 0;
  339.  
  340.  
  341.  
  342.   case WM_USER_DISABLE_CLIENT:
  343.     // this message sent; disable menu action bar as well
  344.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  345.     WinEnableWindow( pg->hwndClient,  FALSE );
  346.     WinEnableWindow( pg->hwndMenubar, FALSE );
  347.     WinEnableWindow( pg->hwndListbox, FALSE );
  348.     return (MRESULT) 0;
  349.  
  350.  
  351.   case WM_USER_ENABLE_CLIENT:
  352.     // this message sent; enable client and action bar
  353.     pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
  354.     WinEnableWindow( pg->hwndClient,  TRUE );
  355.     WinEnableWindow( pg->hwndMenubar, TRUE );
  356.     WinEnableWindow( pg->hwndListbox, TRUE );
  357.     return (MRESULT) 0;
  358.   }
  359.  
  360.   return( WinDefWindowProc( hwnd, msg, mp1, mp2 ));
  361. }
  362.  
  363.  
  364.