Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

CreateProcess 1

Status
Not open for further replies.

SDuke

Programmer
Mar 11, 2005
16
0
0
DE
Hi!
Who can help me?

I am using CreateProcess - (Creation flag=NORMAL_PRIORITY_CLASS, Start flag = STARTF_USESHOWWINDOW, and NormalFocus) - and WaitForSingleObject - (INFINITE) - to start another application (for this example: Notepad)

Everything works fine and the program starts and exits with no problems, and while running, the calling application is suspended as it should be.

However, after Notepad is up and running, if the user moves the Notepad window around, then it does one or two funny things:
After moving it, it may leave a copy of the window, where it was previously located, on the screen, (and each movement causes an additional copy to be left), or it will leave on white space on the calling application, or it will do both.

The white space caused from the window not repainted is only on the calling application's window (not the desktop or another application), and the copies of the Notepad window left on the screen could be anywhere and everywhere.

It doesn't matter if the calling app. is maximized or reduced, and same for Notepad.

So I figured it had to do with it running from the IDE and created and ran the exe. The problem of having muliple copies all over the screen stopped happening for the most part, but the white space problem on the calling application is still happening - well, it is a white space on XP and a copy of the Notepad window on W2000.

Anyone seen this before and/or knows how to correct it?

Many thanks!
 
Let me preface this by saying that I'm no expert, but I'm trying to provide a bit of help from my limited knowledge so I'm not such a leech on the forums. :)

I've seen this problem before in many applications, and I've fixed it with a number of ways. First, you can change the AUTOREDRAW information on your calling application. You can also include in your code to hide the form(s) on the calling application when you start Notepad, and unhide them once the shelled application is closed.

Whenever I've needed to open another application and hold my code, I've used a function called ShellAndWait that I found here on the forums. Without seeing all your code, I'm not sure if your function performs the same. If you search here in the Visual Basic 5.0 and 6.0 forum, you will find a few threads on ShellAndWait:
thread222-93111
thread222-859655

Hope this helps a bit,

rj

************
RudeJohn
************
 
Well, the behavior you describe is not a problem. This behavior is known and occurs when you call synchronization functions, in this case WaitForSingleObject.

To resolve this problem, avoid calling WaitForSingleObject with INFINITE timeout interval. When you call this function, the entire thread activity is suspended including painting of UI components. That is why you see white spots or similar unresponsive behavior of your application.

Consider calling WaitForSingleObject function with smaller intervals, and examine its return value to check if the specified object has entered its signaled state or the function timed out. In latter case you can call the function again and so on. Between two consecutive calls, you can update your display and carry out other UI task to make sure that your application always remains responsive.

See the following code. In this code, the wait function is called with 0 timeout interval, which ensures that your application always remain responsive.
___
[tt]
Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type

Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessID As Long
dwThreadID As Long
End Type

Const STARTF_USESHOWWINDOW = &H1&
Const NORMAL_PRIORITY_CLASS = &H20&
Const INFINITE = -1&
Const WAIT_TIMEOUT = 258&
Const WAIT_OBJECT_0 = 0

Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

'--- Shells the passed command line and waits for the process to finish
'--- Returns the exit code of the shelled process
Function ShellWait(strCmdLine As String, Optional ShowCommand As VbAppWinStyle = vbNormalFocus) As Long
Dim udtProc As PROCESS_INFORMATION, udtStart As STARTUPINFO

'initialize the STARTUPINFO structure
udtStart.cb = Len(udtStart) 'size
udtStart.dwFlags = STARTF_USESHOWWINDOW 'uses show window command
udtStart.wShowWindow = ShowCommand 'the show window command

'Launch the application
CreateProcess vbNullString, strCmdLine, ByVal 0&, ByVal 0&, 0, NORMAL_PRIORITY_CLASS, ByVal 0&, vbNullString, udtStart, udtProc

'Wait for the shelled application to finish
While WaitForSingleObject(udtProc.hProcess, 0) = WAIT_TIMEOUT
DoEvents
Wend

'get the exit code
GetExitCodeProcess udtProc.hProcess, ShellWait

'close handles
CloseHandle udtProc.hThread
CloseHandle udtProc.hProcess
End Function

Private Sub Form_Activate()
AutoRedraw = True
Print "Notepad is running."
ShellWait "notepad.exe"
MsgBox "Notepad finished."
Unload Me
End Sub[/tt]
 

Thank you rudejohn for your input! (yes - my function performs similar)

Thank you Hypetia!

I feel stupid now - but still smarter than before! :)

The loop with a 250 ms wait interval and disabling the calling application did the trick.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top