I was very lucky being able to find this free source code at The program allows me to start any executable program (I use COBOL) from within. What makes it different from Winexec and other methods is that the third party app does not appear in the task bar while running and when minimized it goes to the lower left hand corner, not to the taskbar. This works well for those who wish to create a Visual Basic frontend for console programs or to include notepad or others.
The one problem that I find with it is, that it does not work on an MDI child form. I'm sure I'm missing something, I just don't know what. VB6, and Win98.
Option Explicit
Private Const GW_HWNDNEXT = 2
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Long, ByVal lpWindowName As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private old_parent As Long
Private child_hwnd As Long
' Return the window handle for an instance handle.
Private Function InstanceToWnd(ByVal target_pid As Long) As Long
Dim test_hwnd As Long
Dim test_pid As Long
Dim test_thread_id As Long
' Get the first window handle.
test_hwnd = FindWindow(ByVal 0&, ByVal 0&)
' Loop until we find the target or we run out
' of windows.
Do While test_hwnd <> 0
' See if this window has a parent. If not,
' it is a top-level window.
If GetParent(test_hwnd) = 0 Then
' This is a top-level window. See if
' it has the target instance handle.
test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)
If test_pid = target_pid Then
' This is the target.
InstanceToWnd = test_hwnd
Exit Do
End If
End If
' Examine the next window.
test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
Loop
End Function
Private Sub cmdFree_Click()
SetParent child_hwnd, old_parent
cmdRun.Enabled = True
cmdFree.Enabled = False
End Sub
Private Sub cmdRun_Click()
Dim pid As Long
Dim buf As String
Dim buf_len As Long
' Start the program.
pid = Shell(txtProgram.Text, vbNormalFocus)
If pid = 0 Then
MsgBox "Error starting program"
Exit Sub
End If
' Get the window handle.
child_hwnd = InstanceToWnd(pid)
' Reparent the program so it lies inside
' the PictureBox.
old_parent = SetParent(child_hwnd, picChild.hwnd)
cmdRun.Enabled = False
cmdFree.Enabled = True
End Sub
Private Sub Form_Resize()
Dim hgt As Single
hgt = ScaleHeight - picChild.Top
If hgt < 120 Then hgt = 120
picChild.Move 0, picChild.Top, ScaleWidth, hgt
End Sub
The one problem that I find with it is, that it does not work on an MDI child form. I'm sure I'm missing something, I just don't know what. VB6, and Win98.
Option Explicit
Private Const GW_HWNDNEXT = 2
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Long, ByVal lpWindowName As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private old_parent As Long
Private child_hwnd As Long
' Return the window handle for an instance handle.
Private Function InstanceToWnd(ByVal target_pid As Long) As Long
Dim test_hwnd As Long
Dim test_pid As Long
Dim test_thread_id As Long
' Get the first window handle.
test_hwnd = FindWindow(ByVal 0&, ByVal 0&)
' Loop until we find the target or we run out
' of windows.
Do While test_hwnd <> 0
' See if this window has a parent. If not,
' it is a top-level window.
If GetParent(test_hwnd) = 0 Then
' This is a top-level window. See if
' it has the target instance handle.
test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)
If test_pid = target_pid Then
' This is the target.
InstanceToWnd = test_hwnd
Exit Do
End If
End If
' Examine the next window.
test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
Loop
End Function
Private Sub cmdFree_Click()
SetParent child_hwnd, old_parent
cmdRun.Enabled = True
cmdFree.Enabled = False
End Sub
Private Sub cmdRun_Click()
Dim pid As Long
Dim buf As String
Dim buf_len As Long
' Start the program.
pid = Shell(txtProgram.Text, vbNormalFocus)
If pid = 0 Then
MsgBox "Error starting program"
Exit Sub
End If
' Get the window handle.
child_hwnd = InstanceToWnd(pid)
' Reparent the program so it lies inside
' the PictureBox.
old_parent = SetParent(child_hwnd, picChild.hwnd)
cmdRun.Enabled = False
cmdFree.Enabled = True
End Sub
Private Sub Form_Resize()
Dim hgt As Single
hgt = ScaleHeight - picChild.Top
If hgt < 120 Then hgt = 120
picChild.Move 0, picChild.Top, ScaleWidth, hgt
End Sub