Second problem: Windows is multi-tasking. That's nice for us as users, but
it tends to complicate things when we still have our DOS head on under our
baseball caps. In DOS, things happen one at a time, serially, and step B
can't start until step A's done with. Not so in Windows, where the usual
deal is:
Program A fires off Program B
Program A continues about its business while Program B executes
So if you were to program something like:
PPT: go to next slide
PPT: fire off NOTEPAD
PPT: msgbox ("Looky here, I'm not stopping for nuthin'!")
You'd see the slide change, Notepad would appear and almost immediately,
there'd be a message box from PowerPoint.
To make this work you need to get fairly gritty ... where's David Foster
when you need 'im??? ... and get the Windows handle to the program you've
launched. Offhand, I don't know how to do this, but in round numbers, it'd
look like:
MyHandle = ShellExecute("MyProgram") ' launches the app and returns the
handle to it
' and assuming you have a function that checks for the handle and returns
True if the program's still running ...
While Master_It_LIVES(MyHandle)
DoEvents() ' let somebody else get some processor time
Wend
' and once you get here, you know the other program's quit, so you can go
about your business in PPT
(Ah. My associate, the REAL programmer, just walked in so I jumped him.
<g>)
It's grittier than I thought. You can't do this stuff w/o API calls from
VBA. By itself, VBA doesn't give you the tools you need. Sigh.
My simpleminded alternative: if you know roughly how long your program will
take to execute, you could have the PPT macro check the time before it
launches the program, go into a loop that includes DoEvents() call and
checks the time, breaks out of the loop when StartTime + ProgExecutionTime >
CurrentTime.
Or if you have control over the external app, you might could have it write
a little file in a known place at startup. The PPT loop checks for this
file and as long as it's there, keeps looping. Your external app finishes
up, deletes the file, PPT sees it's gone and knows it's ok to continue.
--
Steve Rindsberg, MVP (again!)
PPT FAQ & Slide imaging - http://www.rdpslides.com
RnR PPTools - http://www.rdpslides.com/pptools
ZAP! for service bureaus - http://www.rdpslides.com/zap.htm
Steve H <sjh...@hotmail.com> wrote in message
news:emi2hJ9K$GA....@cppssbbsa02.microsoft.com...
Steve ... I had a tilt at this in VBA. Read the reply below, then the reply
to the reply below that ... VBA code that'll handle the launch and wait 'til
terminate end of things.
--
Steve Rindsberg, MVP (again!)
PPT FAQ & Slide imaging - http://www.rdpslides.com
RnR PPTools - http://www.rdpslides.com/pptools
ZAP! for service bureaus - http://www.rdpslides.com/zap.htm
Steve Rindsberg <drop...@someplace.else> wrote in message
news:#KtPvBFL$GA.251@cppssbbsa05...
> VBA. By itself, VBA doesn't give you the tools you need. Sigh. (see
below, though)
>
> --
> Steve Rindsberg, MVP (again!)
> PPT FAQ & Slide imaging - http://www.rdpslides.com
> RnR PPTools - http://www.rdpslides.com/pptools
> ZAP! for service bureaus - http://www.rdpslides.com/zap.htm
>
And the code. Paste this into a VBA module in your presentation.
Option Explicit
Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Declare Function FindWindow Lib "user32" Alias _
"FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As Long) As Long
Declare Function GetActiveWindow Lib "user32" () As Long
Declare Function WaitForSingleObject Lib "kernel32" _
(ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long
Sub Launch(AppString$)
' Call with e.g. Launch("NOTEPAD.EXE MyFile.TXT") or
' Launch("NOTEPAD.EXE") or
' Launch("C:\Program Files\MyProggie\MyProg.EXE")
' Launches specified program and waits until program quits
On Error Resume Next
Const SW_RESTORE = 9
Const SYNCHRONIZE = &H100000
Const INFINITE = -1&
Dim pHnd&
Dim lRtn As Long
Dim ProcessID As Long
Dim PPTHwnd As Long
PPTHwnd = FindWindow("PP97FrameClass", 0&)
' or if PPT 20000
' PPTHwnd = FindWindow("PP9FrameClass", 0&)
If PPTHwnd = 0 Then
'MsgBox (PPTHwnd)
'MsgBox GetActiveWindow()
MsgBox ("FindWindow returned a 0")
Exit Sub
End If
' Wait routine needs a long, Shell returns a double, so convert on the fly
ProcessID = CLng(Shell(AppString, vbNormalFocus))
' Wait until launched app terminates
' NB, if it doesn't terminate, we're hung
' Would be better to rewrite this to wait until launched app terminates
' OR some amount of time has passed.
pHnd = OpenProcess(SYNCHRONIZE, 0, ProcessID)
If (pHnd <> 0) Then
lRtn = WaitForSingleObject(pHnd, INFINITE)
lRtn = CloseHandle(pHnd)
Else
' Houston, we have a problem
MsgBox ("Couldn't return a handle for Process ID: " & ProcessID)
End If
End Sub
Sub test()
' Modify this as needed to test the Launch routine:
Dim AppString As String
AppString = "NOTEPAD.EXE MYFILE.TXT"
' Delete the MsgBox lines once you have it firing on all eight cylinders
MsgBox ("About to launch: " & AppString)
Launch (AppString)
MsgBox ("You won't see me until after " & AppString & " terminates.")
End Sub