VB6: Sleep, DoEvent, Loop, looking for best way of...

Posted on 2011-03-03
Last Modified: 2012-05-11

I asked this question before, since nobody respond to it,
I decide to ask it again to see if i can get a better results.

What i want to do is something simple, i am working in a VB6 project,
My goal is to execute a command code to a program, but before that
i want my project to wait for that program to be load, then apply code.

Ive been using the Sleep method, and actually is been working very well,
but i was wondering if i could do it better with DoEvent or something better.

Private Sub Form_Load()
Shell "Program-to-be-execute.exe"

Sleep 3 'wait like three seconds or so

Then after the program load up, is time to apply my code here.
I even add a second code to detect if the windows program is ready or not
'f return not ready, then another three seconds are applyed to my project.

End Sub

Thanks in advance

prior related question:
aikimark -- zone advisor
Question by:C0ding
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 37

Expert Comment

ID: 35033552
It depends on what the other program is. If that program has a visible API that calls events (or if you wrote the other program) then it can be done.
In the general case though, if you can get a 'not ready' returned, then that's pretty good.

You could spin lock
While Not Ready

I'd at least shorten the wait time to a half second or so. Three seconds is so long (in the computer world)
LVL 76

Assisted Solution

GrahamSkan earned 166 total points
ID: 35034778
You could use a Timer control. It does not hog the CPU while waiting. However you would have to structure the code differently.

Private Sub Form_Load()
    Shell "Program-to-be-execute.exe"
    Timer1.Interval = 3000 '= 3 seconds
    Timer1.Enabled = True
End Sub

Sub Timer1_Timer()
    'do (or call) code that expects the shelled program to be running
    Timer1.Enabled = False
End Sub

Alternatively you can use ShellExecute. Here the code will wait until the program has opened  - or not if there are problems. You can test the result. Here is Microsoft's article:

Accepted Solution

BrianVSoft earned 167 total points
ID: 35035099
I think the "Sleep" function is fine, it doesn't slow down other applications..
I think you need "Sleep 3000" for 3 seconds however..
You can use the "FindWindow" function to test if the 2nd App is "up".. All you need to know is the Window/Form Title of the 2nd App  eg. "MY APP 2"
Shell "Program-to-be-execute.exe"
  Sleep 200 ' fifth of a second.
  Count = Count + 1
   If FindWindow("ThunderRT6FormDC", "MY APP 2") > 0 Then Exit Do
Loop While Count < 50 ' Give up after 10 seconds.

You need to declare..
  Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long
PS. The "ThunderRT6FormDC" is the CLASS of VB6 type EXEs
Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

LVL 14

Assisted Solution

VBClassicGuy earned 167 total points
ID: 35036358
Try This:

Private Const INFINITE = -1&
Private Const WAIT_FAILED = -1&
Private Const WAIT_TIMEOUT = &H102&

Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function WaitForInputIdle Lib "user32" (ByVal hProcess As Long, ByVal dwMilliseconds As Long) As Long

Public Function ShellReady(PrgName As String, TimeOut As Long) As Long
    Dim pid As Long
    Dim lngProcess As Long
    Dim lngResult As Long
    pid = Shell(Chr(34) & PrgName & Chr(34), vbNormalFocus)
    lngProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, CLng(pid))
    If lngProcess <> 0 Then
        lngResult = WaitForInputIdle(lngProcess, TimeOut)
        lngResult = WAIT_FAILED
    End If

    ShellReady = lngResult
End Function


See WaitForInputIdle():

You can pass in INFINITE, or you can give it a TimeOut value in milliseconds.

If TimeOut is INFINITE, the function does not return until the process is idle.

You can check the return value to see if it is ready (0), timed out (WAIT_TIMEOUT),
or an error occurred (WAIT_FAILED)

Expert Comment

ID: 35036648
This code is a 'paste' from Exp.Exchange legend "IdleMind"
It may add to your solution..
(search Exp.Exchange for "WaitForInputIdle" )
PS.. How does one extract a LINK to an Exp.Exchange question that you have browsed to??
Private Const INFINITE = -1& 

Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function WaitForInputIdle Lib "user32" (ByVal hProcess As Long, ByVal dwMilliseconds As Long) As Long 
    Dim FileName As String
    Dim params As String
    FileName = "C:\program.exe"
    params = "some params here"

    Dim pid As Long
    Dim lngProcess As Long
    pid = Shell(Chr(34) & FileName & Chr(34) & " " & params, vbNormalFocus)
    lngProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, CLng(pid))
    If lngProcess <> 0 Then
        WaitForInputIdle lngProcess, INFINITE
        TerminateProcess lngProcess, 0&
    End If

Open in new window


Expert Comment

ID: 35037107
Try this code to see if the application is running.
'code for Form1
Private Sub cmdCheck_Click()
'check if application is running
If IsTaskRunning(sAppName) Then
MsgBox "Application '" & sAppName & "' is running!"
MsgBox "Application '" & sAppName & "' is not running!"
End If

End Sub

Private Sub cmdClose_Click()
'close application
Call EndTask(sAppName)

End Sub

Private Sub cmdStart_Click()
'start an application
Shell sAppPath, vbNormalFocus

End Sub

Private Sub Form_Load()

  sAppName = "Microsoft Access"
  sAppPath = "C:\Program Files\access97\Office\MSACCESS.EXE"

End Sub

'Code for Module1

Option Explicit
 'API's Function Declarations
 Private Declare Function IsWindow Lib "user32" (ByVal hwnd As Long) As Long
 Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
 Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As String) As Long
 'API Constants
 Public Const GWL_STYLE = -16
 Public Const WS_DISABLED = &H8000000
 Public Const WM_CANCELMODE = &H1F
 Public Const WM_CLOSE = &H10
 Public sAppName As String, sAppPath As String

 Public Function IsTaskRunning(sWindowName As String) As Boolean
Dim hwnd As Long, hWndOffline As Long
   On Error GoTo IsTaskRunning_Eh
'get handle of the application
'if handle is 0 the application is currently not running
hwnd = FindWindow(0&, sWindowName)
If hwnd = 0 Then

IsTaskRunning = False

Exit Function

IsTaskRunning = True
End If

Exit Function
Call ShowError(sWindowName, "IsTaskRunning")
 End Function
 Public Function EndTask(sWindowName As String) As Integer
Dim X As Long, ReturnVal As Long, TargetHwnd As Long
   'find handle of the application
TargetHwnd = FindWindow(0&, sWindowName)
If TargetHwnd = 0 Then Exit Function
   If IsWindow(TargetHwnd) = False Then

GoTo EndTaskFail
'close application

If Not (GetWindowLong(TargetHwnd, GWL_STYLE) And WS_DISABLED) Then

X = PostMessage(TargetHwnd, WM_CLOSE, 0, 0&)


End If
End If
   GoTo EndTaskSucceed
ReturnVal = False
MsgBox "EndTask: cannot terminate " & sWindowName & " task"
GoTo EndTaskEndSub
ReturnVal = True
EndTask% = ReturnVal
 End Function
 Public Function ShowError(sText As String, sProcName As String)   'this function displays an error that occurred
   Dim sMsg As String
sMsg = "Error # " & Str(Err.Number) & " was generated by " & Err.Source & vbCrLf & Err.Description
MsgBox sMsg, vbCritical, sText & Space(1) & sProcName
Exit Function
 End Function

Open in new window

LVL 14

Expert Comment

ID: 35037420
Yes, Idle_Mind is indeed a legend, and a briliant programmer. The code I presented here was taken from his post, and slightly modified. I wish there was a way in EE to, if your answer is accepted and is taken from another member's answer somewherer else, to share points with that member, even if he has not contributed to the thread. That's hard to explain, but I think you know what I mean.

Author Comment

ID: 35083777

Thanks aikimark, i am kinda new here, and did not know that,
Next time i'll make sure i use that feature.

I'm sorry but i have not been able to come arround here since the day
when the site was under maintenance or something like that, cuz i did
but i keep seeing the "please try again later" or contact customer support.
and thats why i was away. SORRY.


Featured Post

SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction In a recent article ( for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

732 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question