home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
strtds13.zip
/
HELLO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-30
|
15KB
|
566 lines
/****************************** Module Header ******************************\
* Module Name: HELLO.C
*
* Example of how to start a DOS application in OS/2 version 1.2x.
*
* Created by Microsoft Corp., 1988
*
\***************************************************************************/
#define INCL_PM
#define INCL_BASE
#include <os2.h>
#include <string.h>
#include "hello.h"
HAB hAB;
HMQ hmqHello;
HWND hwndHello;
HWND hwndHelloFrame;
CHAR szClassName[] = "Start DOS";
CHAR szMessage[] = "Start a DOS application.";
#define DOS_SESSION 2
#define BUFMAX 130
#define PATHMAX 260
#define CCHMAXSTRING PATHMAX
CHAR szTitle [BUFMAX];
CHAR szExecutable [BUFMAX];
CHAR szParameters [BUFMAX];
CHAR szStartupDir [BUFMAX];
CHAR szDosBusy[] =
"There is already a program running in DOS mode. \
You may have only one DOS mode program running at a time.\
Either exit the program running in DOS mode,\
or wait until it completes before attempting to start another.";
CHAR szPathTooLong[] =
"The DOS program start command string is too long. \
The combined length of the path, filename,\
and parameters for DOS mode cannot exceed 127 characters.";
CHAR szDirTooLong[] =
"The DOS path for the Working Directory is too long. \
The Working Directory path for DOS mode cannot exceed 124 characters.";
VOID SetSysMenu(hwndPar)
HWND hwndPar;
{
HWND hSysMenu;
MENUITEM Mi;
SHORT Pos;
SHORT Id;
SHORT cItems;
/******************************************************************/
/* We only want Move and Close in the system menu */
/******************************************************************/
hSysMenu = WinWindowFromID(hwndPar, FID_SYSMENU);
WinSendMsg( hSysMenu, MM_QUERYITEM
, MPFROM2SHORT(SC_SYSMENU, FALSE), MPFROMP((PCH) & Mi));
Pos = 0;
cItems = (SHORT)WinSendMsg( Mi.hwndSubMenu, MM_QUERYITEMCOUNT, 0L, 0L);
while (cItems--) {
Id = (SHORT)WinSendMsg( Mi.hwndSubMenu, MM_ITEMIDFROMPOSITION
, MPFROM2SHORT(Pos, TRUE), (MPARAM)NULL);
switch (Id) {
case SC_MOVE:
case SC_CLOSE:
Pos++; // Don't Delete that one
break;
default:
WinSendMsg( Mi.hwndSubMenu, MM_DELETEITEM
, MPFROM2SHORT(Id, TRUE), (MPARAM)NULL);
}
}
}
MRESULT EXPENTRY ChangeProgramDlgProc(hdlg, msg, mp1, mp2)
HWND hdlg;
USHORT msg;
MPARAM mp1;
MPARAM mp2;
{
switch (msg)
{
case WM_INITDLG:
/* Fix up our sys menu. */
SetSysMenu(hdlg);
/* Expand the controls' buffers. */
WinSendDlgItemMsg(hdlg, IDC_PROGRAMNAME, EM_SETTEXTLIMIT,
MPFROMSHORT(BUFMAX), 0L);
WinSendDlgItemMsg(hdlg, IDC_FILENAME, EM_SETTEXTLIMIT,
MPFROMSHORT(BUFMAX), 0L);
WinSendDlgItemMsg(hdlg, IDC_PARAMS, EM_SETTEXTLIMIT,
MPFROMSHORT(BUFMAX), 0L);
WinSendDlgItemMsg(hdlg, IDC_WORKDIR, EM_SETTEXTLIMIT,
MPFROMSHORT(BUFMAX), 0L);
/* Initialize the controls. */
/* NOTE: These were initialized to NULL down in main(). */
WinSetWindowText(WinWindowFromID(hdlg, IDC_PROGRAMNAME), szTitle);
WinSetWindowText(WinWindowFromID(hdlg, IDC_FILENAME), szExecutable);
WinSetWindowText(WinWindowFromID(hdlg, IDC_PARAMS), szParameters);
WinSetWindowText(WinWindowFromID(hdlg, IDC_WORKDIR), szStartupDir);
/* Select the entire contents. */
WinSendDlgItemMsg(hdlg, IDC_PROGRAMNAME, EM_SETSEL,
MPFROM2SHORT(0, BUFMAX), 0L);
WinSendDlgItemMsg(hdlg, IDC_FILENAME, EM_SETSEL,
MPFROM2SHORT(0, BUFMAX), 0L);
WinSendDlgItemMsg(hdlg, IDC_PARAMS, EM_SETSEL,
MPFROM2SHORT(0, BUFMAX), 0L);
WinSendDlgItemMsg(hdlg, IDC_WORKDIR, EM_SETSEL,
MPFROM2SHORT(0, BUFMAX), 0L);
break;
case WM_COMMAND:
switch (LOUSHORT(mp1))
{
case DID_OK:
/* Go get what the user entered. */
WinQueryWindowText(WinWindowFromID(hdlg, IDC_PROGRAMNAME),
sizeof(szTitle ), szTitle );
WinQueryWindowText(WinWindowFromID(hdlg, IDC_FILENAME),
sizeof(szExecutable), szExecutable);
WinQueryWindowText(WinWindowFromID(hdlg, IDC_PARAMS),
sizeof(szParameters), szParameters);
WinQueryWindowText(WinWindowFromID(hdlg, IDC_WORKDIR),
sizeof(szStartupDir), szStartupDir);
WinDismissDlg(hdlg, TRUE);
break;
case DID_CANCEL:
WinDismissDlg(hdlg, FALSE);
break;
}
break;
default:
return WinDefDlgProc(hdlg, msg, mp1, mp2);
}
return 0L;
}
/*****************************************************************************\
*
* This routine shows how to start a real mode program from OS/2 version 1.2x
* It does this by writing to an undocumented system driver. This code works
* on versions 1.2 through 1.21, but will fail in versions 2.x and later.
*
\*****************************************************************************/
void NEAR PASCAL StartDOS(HWND hWnd)
{
HWND hwndTemp;
HENUM hHenum;
USHORT usResult;
USHORT sbw;
CHAR szDosCmdStr [CCHMAXSTRING];
CHAR szWorkStr [CCHMAXSTRING];
PSZ pszExt;
HSWITCH vhDosSwitch;
SWCNTRL vslctl;
HFILE vhfFile;
USHORT i;
USHORT afAppType;
/* Check the version since this only works in 1.2x. */
usResult = (USHORT)WinQueryVersion(hAB);
if ((LOBYTE(usResult) != 10) ||
((HIBYTE(usResult) != 21) && (HIBYTE(usResult) != 20)))
{
/* Wrong version. */
WinMessageBox(HWND_DESKTOP,
hWnd,
"OS/2 version 1.2x required.",
szClassName,
1717,
MB_CANCEL | MB_ERROR | MB_MOVEABLE );
goto StartDOSExit;
}
/* We need to open the DOS$ driver to have it start any DOS apps. We
can open it each time we need it, or we can just leave it open if
that's easier. This first section is the code that we can do just
once. */
/* Open the real mode device driver. */
if (DosOpen("DOS$",
&vhfFile,
&usResult,
0L,
0,
FILE_OPEN,
OPEN_FLAGS_FAIL_ON_ERROR |
OPEN_SHARE_DENYNONE |
OPEN_FLAGS_NOINHERIT |
OPEN_ACCESS_WRITEONLY,
0L))
{
/* The DOS box isn't there. */
WinMessageBox(HWND_DESKTOP,
hWnd,
"The OS/2 version 1.2x DOS box isn't loaded.",
szClassName,
1717,
MB_CANCEL | MB_ERROR | MB_MOVEABLE );
goto StartDOSExit;
}
else
{
/* Get the handle to the real mode box. */
hHenum = WinBeginEnumWindows(HWND_DESKTOP);
while (hwndTemp = WinGetNextWindow(hHenum))
{
vhDosSwitch = WinQuerySwitchHandle(hwndTemp, 0);
WinQuerySwitchEntry(vhDosSwitch, &vslctl);
if (vslctl.idSession == DOS_SESSION && vhDosSwitch)
{
/* We found it. */
goto GotDosSwitch;
}
}
WinEndEnumWindows(hHenum);
/* We couldn't find the DOS session. */
WinMessageBox(HWND_DESKTOP,
hWnd,
"The DOS box can't be accessed.",
szClassName,
1717,
MB_CANCEL | MB_ERROR | MB_MOVEABLE );
goto StartDOSClose;
GotDosSwitch:
WinEndEnumWindows(hHenum);
}
/* Now we enter the code that we need to do every time we want to
start a DOS app. */
/* Put up a dialog box to get the things we need. */
if (!WinDlgBox(HWND_DESKTOP, hWnd, (PFNWP)ChangeProgramDlgProc, NULL,
IDDLG_CHANGEPROGRAM, NULL))
{
goto StartDOSClose;
}
if (!*szExecutable)
{
/* We need an executable. */
WinMessageBox(HWND_DESKTOP,
hWnd,
"An executable is required.",
szClassName,
1717,
MB_CANCEL | MB_ERROR | MB_MOVEABLE );
goto StartDOSClose;
}
/* Confirm that this is a real mode app. We assume that the
executable string is fully qualified. If it isn't DosQAppType()
will search the protect mode path for it rather than the real
mode path. They probably aren't the same. We might want to reject
any name that doesn't start with <letter><colon><backslash>. */
/* First get the extension. */
pszExt = szExecutable;
while (*++pszExt) ;
while (*--pszExt != '.')
{
if (pszExt == szExecutable)
{
pszExt = NULL;
break;
}
}
/* Confirm that it's valid in DOS. */
if (usResult = DosQAppType(szExecutable, &afAppType))
{
/* Check if this is an old DOS COM or BAT program. */
if ((usResult != ERROR_INVALID_EXE_SIGNATURE) ||
(strcmpi(pszExt, ".COM") && strcmpi(pszExt, ".BAT")))
{
goto StartDOSBadApp;
}
}
else
{
if (!(afAppType & DOSFORMAT))
{
StartDOSBadApp:
/* It isn't DOS. */
WinMessageBox(HWND_DESKTOP,
hWnd,
"Not a valid DOS application or script.",
szClassName,
1717,
MB_CANCEL | MB_ERROR | MB_MOVEABLE );
goto StartDOSClose;
}
}
/* Build up the string to pass to the DOS box. */
szDosCmdStr[0] = NULL;
/* First put on a change directory if needed. */
if (*szStartupDir)
{
/* skip any leading blanks */
for (i = 0; szStartupDir[i] == ' '; i++)
;
/* set current drive */
if (szStartupDir[i+1] == ':')
{
strcpy(szDosCmdStr, "\x80 ");
strcat(szDosCmdStr, &szStartupDir[i]);
szDosCmdStr[4]=NULL;
strcat(szDosCmdStr, "\r");
}
/* Add directory change command. */
/* Check to make sure the change directory command string length */
/* will not be greater then 124 characters. Dos can only handle */
/* strings of 124 characters or less. */
strcpy(szWorkStr, "\x80 ");
strcat(szWorkStr, "CD ");
strcat(szWorkStr, &szStartupDir[i]);
strcat(szWorkStr, "\r");
if (strlen(szWorkStr) > 124)
{
WinMessageBox(HWND_DESKTOP,
hWnd,
szDirTooLong,
szClassName,
1717,
MB_CANCEL | MB_ERROR | MB_MOVEABLE );
goto StartDOSClose;
}
else
{
strcat(szDosCmdStr, szWorkStr);
}
}
/* Build the command to pass to the DOS box. */
strcpy(szWorkStr, "\x80 ");
/* Add program name */
strcat(szWorkStr, szExecutable);
if (*szParameters)
{
/* Pad string with a blank */
strcat(szWorkStr, " ");
/* Add any program parameters */
strcat(szWorkStr, szParameters);
}
/* Terminate with a carrage return */
strcat(szWorkStr, "\r");
if (strlen(szWorkStr) < 127)
{
strcat(szDosCmdStr, szWorkStr);
/* Start the Real Mode Program */
if ( DosWrite(vhfFile, szDosCmdStr, strlen(szDosCmdStr)+1, &sbw))
{
/* If Busy display message */
WinMessageBox(HWND_DESKTOP,
hWnd,
szDosBusy,
szClassName,
1717,
MB_CANCEL | MB_ERROR | MB_MOVEABLE );
goto StartDOSClose;
}
else
{
/* Change Task List DOS entry to name of program just started. */
strcpy(vslctl.szSwtitle, "DOS ");
strcat(vslctl.szSwtitle, szTitle);
WinChangeSwitchEntry(vhDosSwitch, &vslctl);
/* Started ok. Switch to DOS Box. */
WinSwitchToProgram(vhDosSwitch);
}
}
else
{
/* The string is too long. */
WinMessageBox(HWND_DESKTOP,
hWnd,
szPathTooLong,
szClassName,
1717,
MB_CANCEL | MB_ERROR | MB_MOVEABLE );
goto StartDOSClose;
}
StartDOSClose:
/* Close the driver. If we're going to be doing a lot of this,
we ought to just leave it open while we're using it. */
DosClose(vhfFile);
StartDOSExit:
return;
}
/***************************** Private Function ****************************\
*
* Hello World Main procedure
*
* Effects: Set globals - hAB Handle to Application Anchor Block
* - hmqHello Handle to application window msg queue
*
* Warnings: None
*
\***************************************************************************/
int cdecl main( )
{
QMSG qmsg;
ULONG ctldata;
/* Set up all the default stuff. */
*szTitle = NULL;
*szExecutable = NULL;
*szParameters = NULL;
*szStartupDir = NULL;
hAB = WinInitialize(NULL);
hmqHello = WinCreateMsgQueue(hAB, 0);
if (!WinRegisterClass( hAB,
(PCH)szClassName,
(PFNWP)HelloWndProc,
CS_SYNCPAINT | CS_SIZEREDRAW,
0))
return( 0 );
ctldata = FCF_STANDARD & ~FCF_ACCELTABLE;
hwndHelloFrame = WinCreateStdWindow( HWND_DESKTOP,
WS_VISIBLE,
&ctldata,
(PCH)szClassName,
NULL,
0L,
(HMODULE)NULL,
HELLOICON,
(HWND FAR *)&hwndHello );
WinShowWindow( hwndHelloFrame, TRUE );
/* Poll messages from event queue */
while( WinGetMsg( hAB, (PQMSG)&qmsg, (HWND)NULL, 0, 0 ) )
{
WinDispatchMsg( hAB, (PQMSG)&qmsg );
}
WinDestroyWindow( hwndHelloFrame );
WinDestroyMsgQueue( hmqHello );
WinTerminate( hAB );
}
/***************************** Private Function ****************************\
*
* Procedure which processes window messages
*
* Effects: None
*
* Warnings: None
*
\***************************************************************************/
MRESULT EXPENTRY HelloWndProc( hWnd, msg, mp1, mp2 )
HWND hWnd;
USHORT msg;
MPARAM mp1;
MPARAM mp2;
{
HPS hPS;
POINTL pt;
CHARBUNDLE cb;
switch (msg)
{
case WM_COMMAND:
switch ((USHORT) SHORT1FROMMP(mp1)) /* command value */
{
case ID_STARTDOS:
StartDOS(hWnd);
break;
default:
return( WinDefWindowProc( hWnd, msg, mp1, mp2 ) );
}
break;
case WM_CLOSE:
WinPostMsg( hWnd, WM_QUIT, 0L, 0L );
break;
case WM_PAINT:
hPS = WinBeginPaint( hWnd, (HPS)NULL, (PWRECT)NULL );
pt.x = pt.y = 10L;
cb.lColor = CLR_BLACK;
GpiSetAttrs(hPS, PRIM_CHAR, CBB_COLOR, 0L, (PBUNDLE)&cb);
GpiCharStringAt( hPS, (PPOINTL)&pt, (LONG)sizeof(szMessage)-1,
(PCH)szMessage );
WinEndPaint( hPS );
break;
case WM_ERASEBACKGROUND:
return( TRUE );
break;
default:
return( WinDefWindowProc( hWnd, msg, mp1, mp2 ) );
}
return(0L);
}