From: focke@gmdzi.gmd.de (Stefan Focke)
Subject: Solution: Exec Program and wait until it returns
Organization: gmd
Date: Fri, 16 Oct 1992 08:38:34 GMT

In article <focke.67.719064585gmdzi.gmd.de> I wrote:
>I want to start an external Program (EXCEL) from my own program. My program
>should not continue execution until EXECL has ended. How can I do this?



These are the answers I got:


------------------------------
From: raymondc@microsoft.com
Wed, 14 Oct 92 12:27:49 PDT
To: focke@gmdzi.gmd.de (Stefan Focke)
Subject: Re: Help: Detection end of execution

Use the TOOLHELP library.  Use the NotifyRegister function to register
an application-termination notification callback.  Convert the value that
WinExec returns into an HTASK, via the TaskFirst and TaskNext functions.
Then have your callback routine watch for NFY_EXITTASK with wParam = the
HTASK you computed above.  When this happens, LOWORD(lParam) contains
the exit code.

This works for both DOS apps and Windows apps.  (Notice that nowhere
in the above paragraph does the word "DOS" or "PIF" appear.)



------------------------------
From: labb-2ff@WEB.berkeley.edu (Antonio Kamiya (Satoshi))
Wed, 14 Oct 92 10:01:28 PDT
To: focke@gmdzi.gmd.de
Cc: d88-jwa@byse.nada.kth.se
Subject: Re: Exec Program and wait until it ends


	I read the response made by <d88-jwa>. Unfortunately, his/her
response was not entirely the best way to do things under Windows. OLE
should be used only under special circumstances where an external document
is to be placed into another document.

	Here is a better way. Presumably, after your WinExec(or LoadModule
or ShellExec) call, you probably don't have much to do. You might test for
the return value of the call to see if the EXEC was successful. Well, after
testing and you find out that the call was indeed successful (a return
value > 32), set a global variable that is initialized to FALSE. Call this
flag, bExec. In all the message handlers that you don't want to have
responding to events, check to see if bExec is TRUE or not, and if so,
either call DefWindowProc (in case of messages like WM_PAINT, WM_NCPAINT,
and others that HAVE to be responded to) or ignore the message. In some
cases, you may want to disable your window or hide it to prevent having to
deal with input events.
	Nevertheless, what I have described above is only the locking
mechanism. Once you set the flag, set up a timer for your app. Then return
to Windows. Within the timer handler, check to see if Excel is still
running. Do a FindWindow() call with the appropriate strings. Use Spy to
find out the name of Excel's main window's class. You probably won't know
the title (Excel can concatenate the document name after it's "Excel"
string.), so use NULL for the LPSTR to title name. If this returns a
non-NULL value, excel is still up. Otherwise, Excel has been killed. In this
case, kill the timer, set bExec to FALSE, enable your window, and reactivate
and/or bring your window to top via BringWindowToTop as necessary.

	The method described above is a simple form of semaphores and such.
Good luck. I've used this method in a commercial application, and it has
worked fairly well. You can change the TIMER interval to vary the response
latency of your application to the Excel shutdown event. Also be careful
about the messages you handle or ignore while Excel is up. Like I said,
some messages MUST be handled and responded. If you fail to handle WM_PAINT
or WM_NCPAINT, either via your own proc or DefWindowProc using
BeginPaint/EndPaint sequence, Windows will RIP, and you'll just slow down
the system by repeatedly recieving WM_PAINT.

	Antonio Kamiya (akamiyaocf.berkeley.edu)

----------------------------------------------------------------------

Stefan Focke                  Tel. 02241-14-3154
GMD-I8                        e-mail: stefan.focke@gmd.de
Postfach 1316
D-W 5205 Sankt Augustin 1            
Newsgroups: comp.os.ms-windows.programmer.misc