PRODUCT : Borland C++ NUMBER : 1560 VERSION : 3.x OS : Win DATE : December 13, 1993 PAGE : 1/7 TITLE : Spawning programs from within windows Included are three files wspawn.c, wspawn.h and test.c. wspawn.c is an example of emulating the DOS spawn() function in Windows. test.c excercises this function. wspawn.h provides the prototypes and external definitions needed for wspawn(). // ========= // // WSPAWN.C // // ========= // // ============================================================= // // wspawn - creates and runs a child process in Windows // // Syntax: // wspawn ( HINSTANCE hInst, int Mode, LPCSTR lpszCommand ) // // Remarks: // // hInst - the hInstance of the parent task. If NULL, // wspawn() determines the instance of the current // task. // // Mode - either WP_WAIT or WP_NOWAIT // // WP_WAIT - Puts parent process "on hold" until child // process completes execution // WP_NOWAIT - Continues to run parent process while // child process runs. // // lpszCommand - long pointer to a zero terminated string // that specifies the command _AND_ its // arguments. // // // ** CAUTION ** // You may want to modify the "while ( IsWaiting )" loop // in the wspawn() function. This loop disables the parent // process until the child terminates. However, Windows // will still allow mouse clicks on the parent possibly // filling up the message queue. To circumvent this, PRODUCT : Borland C++ NUMBER : 1560 VERSION : 3.x OS : Win DATE : December 13, 1993 PAGE : 2/7 TITLE : Spawning programs from within windows // you may want to disable all the windows associated with // the parent task using EnumTaskWindows() and // EnableWindow(hwnd,FALSE) in wspawn() and then re-enable // the windows in WspawnNotifyFunc(). // // ============================================================= /////////////////////////////////////////////////////// #include #include // for NotifyRegister() #include // for strlen() #include "wspawn.h" ////////////////////////////////////////////////////// static BOOL IsWaiting = FALSE; static HTASK hSpawnedTask; static WORD WSRetVal; static LPFNNOTIFYCALLBACK lpNotifyFunc; ////////////////////////////////////////////////////// BOOL _export CALLBACK WspawnNotifyFunc ( WORD, DWORD ); static HTASK HINSTtoHTASK ( HINSTANCE ); static HINSTANCE HTASKtoHINST( HTASK ); /////////////////////////////////////////////////////////// int wspawn( HINSTANCE hInst, int Mode, LPCSTR lpszCommand ) { int nError; HINSTANCE hSpawnedInst; // Check if wspawn is busy. if ( IsWaiting ) return -1; // If hInst == NULL, determine hInst. if ( hInst == NULL ) { hInst = HTASKtoHINST( GetCurrentTask() ); if ( hInst == NULL ) PRODUCT : Borland C++ NUMBER : 1560 VERSION : 3.x OS : Win DATE : December 13, 1993 PAGE : 3/7 TITLE : Spawning programs from within windows return -1; } switch ( Mode ) { case WP_WAIT: // Setup Notification lpNotifyFunc = (LPFNNOTIFYCALLBACK) MakeProcInstance ( (FARPROC)WspawnNotifyFunc, hInst ); if ( !lpNotifyFunc ) return -1; nError = NotifyRegister ( GetCurrentTask(),lpNotifyFunc,NF_NORMAL ); if ( !nError ) return -1; // Execute command hSpawnedInst = WinExec ( lpszCommand, SW_SHOW ); if ( hSpawnedInst < HINSTANCE_ERROR ) return -1; IsWaiting = TRUE; hSpawnedTask = HINSTtoHTASK( hSpawnedInst ); // The following merely Yields while waiting for the // child process to terminate... This approach // prevents the user from closing the parent but may // result in a system queue overflow if the user // insists on reactivating the parent [with mouse // clicks for example. An alternate method is to // start a PeekMessage loop. The disadvantage of the // PeekMessage loop is that the user may terminate // the parent before the child process terminates // #if 1 // Change this to '#if 0' to use the PeekMessage method // while ( IsWaiting ) Yield(); #else while( IsWaiting ) PRODUCT : Borland C++ NUMBER : 1560 VERSION : 3.x OS : Win DATE : December 13, 1993 PAGE : 4/7 TITLE : Spawning programs from within windows { MSG msg; if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { if ( msg.message == WM_QUIT ) { PostQuitMessage( msg.wParam ); return -2; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } } #endif // Clean up if ( !NotifyUnRegister( GetCurrentTask() ) ) return -1; FreeProcInstance( lpNotifyFunc ); break; case WP_NOWAIT: hSpawnedInst = WinExec ( lpszCommand, SW_SHOWMINNOACTIVE ); if ( hSpawnedInst < HINSTANCE_ERROR ) return -1; WSRetVal = 0; break; } return WSRetVal; } ///////////////////////////////////////////////////////////////// BOOL _export CALLBACK WspawnNotifyFunc ( WORD wID, DWORD dwData ) { if ( wID == NFY_EXITTASK && GetCurrentTask() == hSpawnedTask ) { IsWaiting = FALSE; PRODUCT : Borland C++ NUMBER : 1560 VERSION : 3.x OS : Win DATE : December 13, 1993 PAGE : 5/7 TITLE : Spawning programs from within windows WSRetVal = LOWORD(dwData); } return FALSE; } /////////////////////////////////////// HTASK HINSTtoHTASK ( HINSTANCE hInst ) { TASKENTRY TaskEntry; TaskEntry.dwSize = sizeof(TaskEntry); if ( TaskFirst( &TaskEntry ) ) do { if ( TaskEntry.hInst == hInst ) return TaskEntry.hTask; } while( TaskNext( &TaskEntry ) ); return 0; } ///////////////////////////////////// HINSTANCE HTASKtoHINST( HTASK hTask ) { TASKENTRY TaskEntry; TaskEntry.dwSize = sizeof(TaskEntry); TaskFindHandle( &TaskEntry, hTask ); return TaskEntry.hInst; } // ========= // // WSPAWN.H // // ========= // #if !defined(__WSPAWN_H) #define __WSPAWN_H PRODUCT : Borland C++ NUMBER : 1560 VERSION : 3.x OS : Win DATE : December 13, 1993 PAGE : 6/7 TITLE : Spawning programs from within windows #include #define WP_WAIT 0 #define WP_NOWAIT 1 #if defined(__cplusplus) extern "C" { #endif int wspawn( HINSTANCE hInst, int Mode, LPCSTR lpszCommand ); #if defined(__cplusplus) } #endif #endif // __WSPAWN_H // ======= // // TEST.C // // ======= // //-------------------------------------------------------------- // // test.c - test program for wspawn() // // // Setup: // To create test.exe either // // 1. Compile via the command-line ( Borland C++ only ) // // bcc -ml -W -v test.c wspawn.c // // // 2. Build and compile a project in the IDE // ( BCW or TCW ) // // - Project|Open test.prj // - Project|Add Item... test.c & wspawn.c // - Compile|Build All PRODUCT : Borland C++ NUMBER : 1560 VERSION : 3.x OS : Win DATE : December 13, 1993 PAGE : 7/7 TITLE : Spawning programs from within windows // // Remarks: // This test program spawns a DOS Shell using the // DOSPRMPT.PIF file located in the \windows directory. // Adjust the parameter below to match your directory setup. // //-------------------------------------------------------------- #include #include #include "wspawn.h" void main(void) { printf( "Spawning DOS IDE...\n" ); wspawn( NULL, WP_WAIT, "\\windows\\dosprmpt.pif dir" ); printf( "\nFinished..." ); } DISCLAIMER: You have the right to use this technical information subject to the terms of the No-Nonsense License Statement that you received with the Borland product to which this information pertains.