Prev: Shutdown dialog Box
Next: Network Drive Not Ready
From: Ringo on 15 Feb 2006 21:29 I'm using ShellExecute inVB6 to launch a powerpointveiwer presentation like this; ShellExecute Me.hwnd, "Open", "D:\play.bat", vbNullString, "D:\", SW_SHOWNORMAL and need to know when the presentation has finished. I want my VB program to still be running and send commands to the PPT stuff using sendkeys but the vb should start doing something else when the ppt closes. How can I tell that the PPT stuff has finished? I saw somewhere that ShellExecuteEx can return an handle and thread, but how do I use these? Thanks Ringo
From: J French on 16 Feb 2006 05:14 On 15 Feb 2006 18:29:11 -0800, "Ringo" <ringo.davis(a)gmail.com> wrote: >I'm using ShellExecute inVB6 to launch a powerpointveiwer presentation >like this; > >ShellExecute Me.hwnd, "Open", "D:\play.bat", vbNullString, "D:\", >SW_SHOWNORMAL > >and need to know when the presentation has finished. I want my VB >program to still be running and send commands to the PPT stuff using >sendkeys but the vb should start doing something else when the ppt >closes. How can I tell that the PPT stuff has finished? I saw somewhere > >that ShellExecuteEx can return an handle and thread, but how do I use >these? This is a simplistic version - you'll find better ones using CreateProcess if you search for "Shell And Wait" Incidentally use FindExecutable to get the name & location of the App instead of letting ShellExecute do it for you Option Explicit Private Declare Function OpenProcess Lib "kernel32" _ (ByVal dwDesiredAccess As Long, _ ByVal bInheritHandle As Long, _ ByVal dwProcessId As Long) As Long Private Declare Function CloseHandle Lib "kernel32" _ (ByVal hObject As Long) As Long Private Const SYNCHRONIZE = &H100000 Private Const PROCESS_QUERY_INFORMATION = &H400 Private Declare Function GetExitCodeProcess _ Lib "kernel32" _ (ByVal hProcess As Long, _ lpExitCode As Long) As Long Dim pID As Long Sub Form_Load() Command1.Caption = "Shell" Command2.Caption = "Get Status" End Sub Private Sub Command2_Click() Dim Ok&, ECode& Dim hProcess&, Q& Q = PROCESS_QUERY_INFORMATION Or SYNCHRONIZE hProcess = OpenProcess(Q, False, pID) ' --- Ok = GetExitCodeProcess(hProcess, ECode) MsgBox Str$(Ok) + Str$(ECode) ' --- If hProcess Then CloseHandle hProcess End If End Sub Sub Command1_Click() Dim Style%, Cmd$ ' Style = vbHide Style = vbNormalFocus Cmd$ = "DIR C:\ /P" pID = Shell(Environ("Comspec") + " /C " + Cmd, Style) End Sub
From: Ringo on 17 Feb 2006 21:58 Thanks for the code. If I make a new project and put this code into it then it works great, but when I put into my existing project (which is pretty big) it opens a command window and then goes away immediately. Any idea what I could have in the rest of my program that would effect it that way? I'm not sure what to even look for. I did a copy and paste so I know I didn't mis-type anything. my declarations look like this Dim Serial_Port_Initialized As Boolean Dim Formloaded As Boolean Dim maxVLoaded As Integer Dim check1Loaded As Integer Dim check2Loaded As Integer Dim check3Loaded As Integer Dim Play_stop_Video As Integer Dim Play_stop_audio As Integer Dim TabNum As Integer Dim hmixer As Long ' mixer handle Dim volCtrl As MIXERCONTROL ' waveout volume control Dim micCtrl As MIXERCONTROL ' microphone volume control Dim rc As Long ' return code Dim ok As Boolean ' boolean return code Dim pID As Long Option Explicit Private Declare Function OpenProcess Lib "kernel32" _ (ByVal dwDesiredAccess As Long, _ ByVal bInheritHandle As Long, _ ByVal dwProcessId As Long) As Long Private Declare Function CloseHandle Lib "kernel32" _ (ByVal hObject As Long) As Long Private Const SYNCHRONIZE = &H100000 Private Const PROCESS_QUERY_INFORMATION = &H400 Private Const STATUS_PENDING = &H103& Private Declare Function GetExitCodeProcess Lib "kernel32" _ (ByVal hProcess As Long, lpExitCode As Long) As Long 'Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _ (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _ ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd _ As Long) As Long 'Private Declare Function GetDesktopWindow Lib "user32" () As Long Private Declare Sub Sleep Lib "kernel32" _ (ByVal dwMilliseconds As Long) Private Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long Private Type POINTAPI x As Long y As Long End Type Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long Private Const SW_SHOWNORMAL = 1 Private Declare Function GetShortPathName Lib "kernel32" Alias "GetShortPathNameA" _ (ByVal lpszLongPath As String, ByVal lpszShortPath As String, _ ByVal lBuffer As Long) As Long Public Function GetShortPath(strFileName As String) As String Dim lngRes As Long, strPath As String 'Create a buffer strPath = String$(165, 0) 'retrieve the short pathname lngRes = GetShortPathName(strFileName, strPath, 164) 'remove all unnecessary chr$(0)'s GetShortPath = Left$(strPath, lngRes) End Function Other than that I read some INI files, set up the com port and volume controls. Then I press the button to launch my app which is this; Private Sub btn_play_ppt_Click() ' ShellExecute Me.hwnd, "Open", "D:\pptview", " /L playlist.txt", "D:\", SW_SHOWNORMAL Dim Style%, Cmd$ ' Style = vbHide Style = vbNormalFocus Cmd$ = "d:\play.bat" pID = SHELL(Environ("Comspec") + " /C " + Cmd, Style) End Sub and I get teh behavior I described above? Any thoughts where I should start trying to figure it out? Thanks Ringo
From: J French on 18 Feb 2006 05:06 On 17 Feb 2006 18:58:52 -0800, "Ringo" <ringo.davis(a)gmail.com> wrote: >Thanks for the code. If I make a new project and put this code into it >then it works great, but when I put into my existing project (which is >pretty big) it opens a command window and then goes away immediately. >Any idea what I could have in the rest of my program that would effect >it that way? I'm not sure what to even look for. I did a copy and paste >so I know I didn't mis-type anything. I can't see anything wrong there However the best trick for checking such things is to put 'pause' in the first line of your batch file.
From: Ringo on 18 Feb 2006 20:59
Thanks, for all the help, I finally got it working using ShellAndWait, but it has another side effect I was not expecting. I have a remote control and when I push 1 button it plays the next video from a list, when I push another button it plays the next audio clip from a list. When the PPT presentation is running I want those 2 buttons to do "Pause" and "next" for the PPT stuff. I'm using Sendkeys to send PGDN and "." for the pause and next stuff. If I set a timer to start sending the PGDN's after I start the PPT thing I can see that it works because the presentation jumps forward when it is supposed to. But when I try to use the remote to do the same thing nothing happens. I put in debug statements in the MSComm1_OnComm() event but after I use shell to start the ppt thing then it appears the program no longer sees the serial data at all. Even after teh PPT has terminated the port does not work until I quit the VB program and restart it. Here is the code that does the work; Cmd$ = "D:\pptview ""D:\21st Century Robotics CD.ppt""" Call subShellAndWait(Cmd) PPT_Playing = False 'Shell (Cmd) End Sub Public Sub subShellAndWait(cmdline As String, Optional Param As Variant = 1) Dim hProcess As Long Dim ProcessId As Long Dim exitCode As Long ProcessId = Shell(cmdline, Param) hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessId) Do Call GetExitCodeProcess(hProcess, exitCode) DoEvents Loop While exitCode = STATUS_PENDING Call CloseHandle(hProcess) ' MsgBox "The shelled process " & cmdline & " has ended." End Sub Any ideas on why this would stop the MS_comm stuff from working? Thanks Ringo |