home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / strtds13.zip / HELLO.C < prev    next >
C/C++ Source or Header  |  1990-08-30  |  15KB  |  566 lines

  1. /****************************** Module Header ******************************\
  2. * Module Name: HELLO.C
  3. *
  4. * Example of how to start a DOS application in OS/2 version 1.2x.
  5. *
  6. * Created by Microsoft Corp., 1988
  7. *
  8. \***************************************************************************/
  9.  
  10. #define INCL_PM
  11. #define INCL_BASE
  12. #include <os2.h>
  13. #include <string.h>
  14. #include "hello.h"
  15.  
  16. HAB     hAB;
  17. HMQ     hmqHello;
  18. HWND    hwndHello;
  19. HWND    hwndHelloFrame;
  20.  
  21. CHAR    szClassName[] = "Start DOS";
  22. CHAR    szMessage[]   = "Start a DOS application.";
  23.  
  24.  
  25. #define DOS_SESSION    2
  26. #define BUFMAX        130
  27. #define PATHMAX     260
  28. #define CCHMAXSTRING    PATHMAX
  29.  
  30. CHAR        szTitle      [BUFMAX];
  31. CHAR        szExecutable [BUFMAX];
  32. CHAR        szParameters [BUFMAX];
  33. CHAR        szStartupDir [BUFMAX];
  34.  
  35. CHAR    szDosBusy[] =
  36. "There is already a program running in DOS mode. \
  37.  You may have only one DOS mode program running at a time.\
  38.  Either exit the program running in DOS mode,\
  39.  or wait until it completes before attempting to start another.";
  40.  
  41. CHAR    szPathTooLong[] =
  42. "The DOS program start command string is too long. \
  43.  The combined length of the path, filename,\
  44.  and parameters for DOS mode cannot exceed 127 characters.";
  45.  
  46. CHAR    szDirTooLong[] =
  47. "The DOS path for the Working Directory is too long. \
  48.  The Working Directory path for DOS mode cannot exceed 124 characters.";
  49.  
  50.  
  51. VOID SetSysMenu(hwndPar)
  52. HWND hwndPar;
  53. {
  54.     HWND     hSysMenu;
  55.     MENUITEM Mi;
  56.     SHORT    Pos;
  57.     SHORT    Id;
  58.     SHORT    cItems;
  59.  
  60.     /******************************************************************/
  61.     /*    We only want Move and Close in the system menu              */
  62.     /******************************************************************/
  63.  
  64.     hSysMenu = WinWindowFromID(hwndPar, FID_SYSMENU);
  65.     WinSendMsg( hSysMenu, MM_QUERYITEM
  66.               , MPFROM2SHORT(SC_SYSMENU, FALSE), MPFROMP((PCH) & Mi));
  67.     Pos = 0;
  68.     cItems = (SHORT)WinSendMsg( Mi.hwndSubMenu, MM_QUERYITEMCOUNT, 0L, 0L);
  69.     while (cItems--) {
  70.         Id = (SHORT)WinSendMsg( Mi.hwndSubMenu, MM_ITEMIDFROMPOSITION
  71.                           , MPFROM2SHORT(Pos, TRUE), (MPARAM)NULL);
  72.         switch (Id) {
  73.         case SC_MOVE:
  74.         case SC_CLOSE:
  75.             Pos++;  // Don't Delete that one
  76.             break;
  77.         default:
  78.             WinSendMsg( Mi.hwndSubMenu, MM_DELETEITEM
  79.                       , MPFROM2SHORT(Id, TRUE), (MPARAM)NULL);
  80.         }
  81.  
  82.     }
  83. }
  84.  
  85.  
  86. MRESULT EXPENTRY ChangeProgramDlgProc(hdlg, msg, mp1, mp2)
  87. HWND    hdlg;
  88. USHORT  msg;
  89. MPARAM    mp1;
  90. MPARAM    mp2;
  91. {
  92.  
  93.     switch (msg)
  94.     {
  95.  
  96.     case WM_INITDLG:
  97.  
  98.         /* Fix up our sys menu. */
  99.         SetSysMenu(hdlg);
  100.  
  101.         /* Expand the controls' buffers. */
  102.         WinSendDlgItemMsg(hdlg, IDC_PROGRAMNAME, EM_SETTEXTLIMIT,
  103.                   MPFROMSHORT(BUFMAX), 0L);
  104.         WinSendDlgItemMsg(hdlg, IDC_FILENAME,    EM_SETTEXTLIMIT,
  105.                   MPFROMSHORT(BUFMAX), 0L);
  106.         WinSendDlgItemMsg(hdlg, IDC_PARAMS,      EM_SETTEXTLIMIT,
  107.                   MPFROMSHORT(BUFMAX), 0L);
  108.         WinSendDlgItemMsg(hdlg, IDC_WORKDIR,     EM_SETTEXTLIMIT,
  109.                   MPFROMSHORT(BUFMAX), 0L);
  110.  
  111.         /* Initialize the controls. */
  112.         /* NOTE: These were initialized to NULL down in main(). */
  113.         WinSetWindowText(WinWindowFromID(hdlg, IDC_PROGRAMNAME), szTitle);
  114.         WinSetWindowText(WinWindowFromID(hdlg, IDC_FILENAME), szExecutable);
  115.         WinSetWindowText(WinWindowFromID(hdlg, IDC_PARAMS), szParameters);
  116.         WinSetWindowText(WinWindowFromID(hdlg, IDC_WORKDIR), szStartupDir);
  117.  
  118.         /* Select the entire contents. */
  119.         WinSendDlgItemMsg(hdlg, IDC_PROGRAMNAME, EM_SETSEL,
  120.                   MPFROM2SHORT(0, BUFMAX), 0L);
  121.         WinSendDlgItemMsg(hdlg, IDC_FILENAME,    EM_SETSEL,
  122.                   MPFROM2SHORT(0, BUFMAX), 0L);
  123.         WinSendDlgItemMsg(hdlg, IDC_PARAMS,      EM_SETSEL,
  124.                   MPFROM2SHORT(0, BUFMAX), 0L);
  125.         WinSendDlgItemMsg(hdlg, IDC_WORKDIR,     EM_SETSEL,
  126.                   MPFROM2SHORT(0, BUFMAX), 0L);
  127.  
  128.         break;
  129.  
  130.     case WM_COMMAND:
  131.  
  132.         switch (LOUSHORT(mp1))
  133.         {
  134.         case DID_OK:
  135.  
  136.             /* Go get what the user entered. */
  137.             WinQueryWindowText(WinWindowFromID(hdlg, IDC_PROGRAMNAME),
  138.                        sizeof(szTitle      ), szTitle     );
  139.             WinQueryWindowText(WinWindowFromID(hdlg, IDC_FILENAME),
  140.                        sizeof(szExecutable), szExecutable);
  141.             WinQueryWindowText(WinWindowFromID(hdlg, IDC_PARAMS),
  142.                        sizeof(szParameters), szParameters);
  143.             WinQueryWindowText(WinWindowFromID(hdlg, IDC_WORKDIR),
  144.                        sizeof(szStartupDir), szStartupDir);
  145.  
  146.             WinDismissDlg(hdlg, TRUE);
  147.             break;
  148.  
  149.         case DID_CANCEL:
  150.             WinDismissDlg(hdlg, FALSE);
  151.             break;
  152.             }
  153.         break;
  154.  
  155.     default:
  156.         return WinDefDlgProc(hdlg, msg, mp1, mp2);
  157.     }
  158.  
  159.     return 0L;
  160. }
  161.  
  162.  
  163. /*****************************************************************************\
  164. *
  165. * This routine shows how to start a real mode program from OS/2 version 1.2x
  166. * It does this by writing to an undocumented system driver. This code works
  167. * on versions 1.2 through 1.21, but will fail in versions 2.x and later.
  168. *
  169. \*****************************************************************************/
  170.  
  171. void NEAR PASCAL StartDOS(HWND hWnd)
  172. {
  173.     HWND        hwndTemp;
  174.     HENUM        hHenum;
  175.     USHORT        usResult;
  176.     USHORT        sbw;
  177.     CHAR        szDosCmdStr  [CCHMAXSTRING];
  178.     CHAR        szWorkStr     [CCHMAXSTRING];
  179.     PSZ         pszExt;
  180.     HSWITCH        vhDosSwitch;
  181.     SWCNTRL        vslctl;
  182.     HFILE        vhfFile;
  183.     USHORT        i;
  184.     USHORT        afAppType;
  185.  
  186.  
  187.     /* Check the version since this only works in 1.2x. */
  188.     usResult = (USHORT)WinQueryVersion(hAB);
  189.     if ((LOBYTE(usResult) != 10) ||
  190.     ((HIBYTE(usResult) != 21) && (HIBYTE(usResult) != 20)))
  191.     {
  192.     /* Wrong version. */
  193.     WinMessageBox(HWND_DESKTOP,
  194.               hWnd,
  195.               "OS/2 version 1.2x required.",
  196.               szClassName,
  197.               1717,
  198.               MB_CANCEL | MB_ERROR | MB_MOVEABLE );
  199.     goto StartDOSExit;
  200.     }
  201.  
  202.  
  203.     /* We need to open the DOS$ driver to have it start any DOS apps. We
  204.        can open it each time we need it, or we can just leave it open if
  205.        that's easier. This first section is the code that we can do just
  206.        once. */
  207.  
  208.     /* Open the real mode device driver. */
  209.     if (DosOpen("DOS$",
  210.         &vhfFile,
  211.         &usResult,
  212.         0L,
  213.         0,
  214.         FILE_OPEN,
  215.         OPEN_FLAGS_FAIL_ON_ERROR |
  216.              OPEN_SHARE_DENYNONE |
  217.              OPEN_FLAGS_NOINHERIT |
  218.              OPEN_ACCESS_WRITEONLY,
  219.         0L))
  220.     {
  221.     /* The DOS box isn't there. */
  222.     WinMessageBox(HWND_DESKTOP,
  223.               hWnd,
  224.               "The OS/2 version 1.2x DOS box isn't loaded.",
  225.               szClassName,
  226.               1717,
  227.               MB_CANCEL | MB_ERROR | MB_MOVEABLE );
  228.     goto StartDOSExit;
  229.     }
  230.     else
  231.     {
  232.     /* Get the handle to the real mode box. */
  233.  
  234.     hHenum = WinBeginEnumWindows(HWND_DESKTOP);
  235.  
  236.     while (hwndTemp = WinGetNextWindow(hHenum))
  237.         {
  238.         vhDosSwitch = WinQuerySwitchHandle(hwndTemp, 0);
  239.         WinQuerySwitchEntry(vhDosSwitch, &vslctl);
  240.         if (vslctl.idSession == DOS_SESSION && vhDosSwitch)
  241.         {
  242.         /* We found it. */
  243.         goto GotDosSwitch;
  244.         }
  245.         }
  246.     WinEndEnumWindows(hHenum);
  247.  
  248.     /* We couldn't find the DOS session. */
  249.     WinMessageBox(HWND_DESKTOP,
  250.               hWnd,
  251.               "The DOS box can't be accessed.",
  252.               szClassName,
  253.               1717,
  254.               MB_CANCEL | MB_ERROR | MB_MOVEABLE );
  255.     goto StartDOSClose;
  256.  
  257. GotDosSwitch:
  258.     WinEndEnumWindows(hHenum);
  259.     }
  260.  
  261.  
  262.     /* Now we enter the code that we need to do every time we want to
  263.        start a DOS app. */
  264.  
  265.     /* Put up a dialog box to get the things we need. */
  266.     if (!WinDlgBox(HWND_DESKTOP, hWnd, (PFNWP)ChangeProgramDlgProc, NULL,
  267.               IDDLG_CHANGEPROGRAM, NULL))
  268.     {
  269.     goto StartDOSClose;
  270.     }
  271.  
  272.     if (!*szExecutable)
  273.     {
  274.     /* We need an executable. */
  275.     WinMessageBox(HWND_DESKTOP,
  276.               hWnd,
  277.               "An executable is required.",
  278.               szClassName,
  279.               1717,
  280.               MB_CANCEL | MB_ERROR | MB_MOVEABLE );
  281.     goto StartDOSClose;
  282.     }
  283.  
  284.  
  285.     /* Confirm that this is a real mode app. We assume that the
  286.        executable string is fully qualified. If it isn't DosQAppType()
  287.        will search the protect mode path for it rather than the real
  288.        mode path. They probably aren't the same. We might want to reject
  289.        any name that doesn't start with <letter><colon><backslash>. */
  290.  
  291.     /* First get the extension. */
  292.     pszExt = szExecutable;
  293.     while (*++pszExt) ;
  294.     while (*--pszExt != '.')
  295.     {
  296.     if (pszExt == szExecutable)
  297.         {
  298.         pszExt = NULL;
  299.         break;
  300.         }
  301.     }
  302.  
  303.     /* Confirm that it's valid in DOS. */
  304.     if (usResult = DosQAppType(szExecutable, &afAppType))
  305.     {
  306.     /* Check if this is an old DOS COM or BAT program. */
  307.     if ((usResult != ERROR_INVALID_EXE_SIGNATURE) ||
  308.         (strcmpi(pszExt, ".COM") && strcmpi(pszExt, ".BAT")))
  309.         {
  310.         goto StartDOSBadApp;
  311.         }
  312.     }
  313.     else
  314.     {
  315.     if (!(afAppType & DOSFORMAT))
  316.         {
  317. StartDOSBadApp:
  318.         /* It isn't DOS. */
  319.         WinMessageBox(HWND_DESKTOP,
  320.               hWnd,
  321.               "Not a valid DOS application or script.",
  322.               szClassName,
  323.               1717,
  324.               MB_CANCEL | MB_ERROR | MB_MOVEABLE );
  325.         goto StartDOSClose;
  326.         }
  327.     }
  328.  
  329.  
  330.     /* Build up the string to pass to the DOS box. */
  331.     szDosCmdStr[0] = NULL;
  332.  
  333.     /* First put on a change directory if needed. */
  334.     if (*szStartupDir)
  335.     {
  336.     /* skip any leading blanks */
  337.     for (i = 0; szStartupDir[i] == ' '; i++)
  338.         ;
  339.  
  340.     /* set current drive */
  341.     if (szStartupDir[i+1] == ':')
  342.         {
  343.         strcpy(szDosCmdStr, "\x80 ");
  344.         strcat(szDosCmdStr, &szStartupDir[i]);
  345.         szDosCmdStr[4]=NULL;
  346.         strcat(szDosCmdStr, "\r");
  347.         }
  348.  
  349.     /* Add directory change command. */
  350.  
  351.     /* Check to make sure the change directory command string length  */
  352.     /* will not be greater then 124 characters. Dos can only handle  */
  353.     /* strings of 124 characters or less.                 */
  354.  
  355.     strcpy(szWorkStr, "\x80 ");
  356.     strcat(szWorkStr, "CD ");
  357.     strcat(szWorkStr, &szStartupDir[i]);
  358.     strcat(szWorkStr, "\r");
  359.  
  360.     if (strlen(szWorkStr) > 124)
  361.         {
  362.         WinMessageBox(HWND_DESKTOP,
  363.               hWnd,
  364.               szDirTooLong,
  365.               szClassName,
  366.               1717,
  367.               MB_CANCEL | MB_ERROR | MB_MOVEABLE );
  368.         goto StartDOSClose;
  369.         }
  370.     else
  371.         {
  372.         strcat(szDosCmdStr, szWorkStr);
  373.         }
  374.     }
  375.  
  376.  
  377.     /* Build the command to pass to the DOS box. */
  378.     strcpy(szWorkStr, "\x80 ");
  379.     /* Add program name */
  380.     strcat(szWorkStr, szExecutable);
  381.     if (*szParameters)
  382.     {
  383.     /* Pad string with a blank */
  384.     strcat(szWorkStr, " ");
  385.     /* Add any program parameters */
  386.     strcat(szWorkStr, szParameters);
  387.     }
  388.     /* Terminate with a carrage return */
  389.     strcat(szWorkStr, "\r");
  390.  
  391.     if (strlen(szWorkStr) < 127)
  392.     {
  393.  
  394.     strcat(szDosCmdStr, szWorkStr);
  395.  
  396.     /* Start the Real Mode Program */
  397.  
  398.     if ( DosWrite(vhfFile, szDosCmdStr, strlen(szDosCmdStr)+1, &sbw))
  399.         {
  400.         /* If Busy display message */
  401.         WinMessageBox(HWND_DESKTOP,
  402.               hWnd,
  403.               szDosBusy,
  404.               szClassName,
  405.               1717,
  406.               MB_CANCEL | MB_ERROR | MB_MOVEABLE );
  407.         goto StartDOSClose;
  408.         }
  409.     else
  410.         {
  411.  
  412.         /* Change Task List DOS entry to name of program just started. */
  413.         strcpy(vslctl.szSwtitle, "DOS ");
  414.         strcat(vslctl.szSwtitle, szTitle);
  415.         WinChangeSwitchEntry(vhDosSwitch, &vslctl);
  416.  
  417.         /* Started ok. Switch to DOS Box. */
  418.         WinSwitchToProgram(vhDosSwitch);
  419.         }
  420.     }
  421.     else
  422.     {
  423.     /* The string is too long. */
  424.     WinMessageBox(HWND_DESKTOP,
  425.               hWnd,
  426.               szPathTooLong,
  427.               szClassName,
  428.               1717,
  429.               MB_CANCEL | MB_ERROR | MB_MOVEABLE );
  430.     goto StartDOSClose;
  431.     }
  432.  
  433.  
  434. StartDOSClose:
  435.  
  436.     /* Close the driver. If we're going to be doing a lot of this,
  437.        we ought to just leave it open while we're using it. */
  438.     DosClose(vhfFile);
  439.  
  440. StartDOSExit:
  441.  
  442.     return;
  443. }
  444.  
  445.  
  446. /***************************** Private Function ****************************\
  447. *
  448. * Hello World Main procedure
  449. *
  450. * Effects: Set globals   - hAB        Handle to Application Anchor Block
  451. *             - hmqHello   Handle to application window msg queue
  452. *
  453. * Warnings: None
  454. *
  455. \***************************************************************************/
  456.  
  457. int cdecl main( )
  458. {
  459.     QMSG qmsg;
  460.     ULONG ctldata;
  461.  
  462.     /* Set up all the default stuff. */
  463.     *szTitle      = NULL;
  464.     *szExecutable = NULL;
  465.     *szParameters = NULL;
  466.     *szStartupDir = NULL;
  467.  
  468.     hAB = WinInitialize(NULL);
  469.  
  470.     hmqHello = WinCreateMsgQueue(hAB, 0);
  471.  
  472.     if (!WinRegisterClass( hAB,
  473.                            (PCH)szClassName,
  474.                            (PFNWP)HelloWndProc,
  475.                            CS_SYNCPAINT | CS_SIZEREDRAW,
  476.                            0))
  477.         return( 0 );
  478.  
  479.     ctldata = FCF_STANDARD & ~FCF_ACCELTABLE;
  480.  
  481.     hwndHelloFrame = WinCreateStdWindow( HWND_DESKTOP,
  482.                      WS_VISIBLE,
  483.                        &ctldata,
  484.                                          (PCH)szClassName,
  485.                      NULL,
  486.                                          0L,
  487.                                          (HMODULE)NULL,
  488.                                          HELLOICON,
  489.                                          (HWND FAR *)&hwndHello );
  490.  
  491.     WinShowWindow( hwndHelloFrame, TRUE );
  492.  
  493.  
  494.     /* Poll messages from event queue */
  495.  
  496.     while( WinGetMsg( hAB, (PQMSG)&qmsg, (HWND)NULL, 0, 0 ) )
  497.     {
  498.         WinDispatchMsg( hAB, (PQMSG)&qmsg );
  499.     }
  500.  
  501.     WinDestroyWindow( hwndHelloFrame );
  502.     WinDestroyMsgQueue( hmqHello );
  503.     WinTerminate( hAB );
  504. }
  505.  
  506.  
  507.  
  508. /***************************** Private Function ****************************\
  509. *
  510. * Procedure which processes window messages
  511. *
  512. * Effects: None
  513. *
  514. * Warnings: None
  515. *
  516. \***************************************************************************/
  517.  
  518. MRESULT EXPENTRY HelloWndProc( hWnd, msg, mp1, mp2 )
  519. HWND   hWnd;
  520. USHORT msg;
  521. MPARAM mp1;
  522. MPARAM mp2;
  523. {
  524.     HPS    hPS;
  525.     POINTL pt;
  526.     CHARBUNDLE cb;
  527.  
  528.     switch (msg)
  529.     {
  530.     case WM_COMMAND:
  531.         switch ((USHORT) SHORT1FROMMP(mp1))       /* command value */
  532.         {
  533.         case ID_STARTDOS:
  534.             StartDOS(hWnd);
  535.             break;
  536.  
  537.         default:
  538.             return( WinDefWindowProc( hWnd, msg, mp1, mp2 ) );
  539.         }
  540.         break;
  541.  
  542.     case WM_CLOSE:
  543.         WinPostMsg( hWnd, WM_QUIT, 0L, 0L );
  544.         break;
  545.  
  546.     case WM_PAINT:
  547.         hPS = WinBeginPaint( hWnd, (HPS)NULL, (PWRECT)NULL );
  548.         pt.x = pt.y = 10L;
  549.         cb.lColor = CLR_BLACK;
  550.         GpiSetAttrs(hPS, PRIM_CHAR, CBB_COLOR, 0L, (PBUNDLE)&cb);
  551.  
  552.         GpiCharStringAt( hPS, (PPOINTL)&pt, (LONG)sizeof(szMessage)-1,
  553.                 (PCH)szMessage );
  554.         WinEndPaint( hPS );
  555.         break;
  556.  
  557.     case WM_ERASEBACKGROUND:
  558.         return( TRUE );
  559.         break;
  560.  
  561.     default:
  562.         return( WinDefWindowProc( hWnd, msg, mp1, mp2 ) );
  563.     }
  564.     return(0L);
  565. }
  566.