Odd. Can't find any reference to it. Maybe deleted. So here it is again. Allows you to launch a program by name, and get an extended PROCESS_INFORMATION structure back which, along with the normal PI stuff, contains the hWnd of the launched application. It's cut out of a larger app, so it may contain some extra declarations that you don't require:
[tt]
Option Explicit
Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
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
Public Type PROCESS_INFORMATION_EXT
hProcess As Long
hThread As Long
hwnd As Long
dwProcessID As Long
dwThreadID As Long
End Type
Private Declare Function CreateProcessA Lib "kernel32" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, ByVal lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Private Const INFINITE = &HFFFF
Private Declare Function WaitForInputIdle Lib "user32" (ByVal hProcess As Long, ByVal dwMilliseconds As Long) As Long
Private Const NORMAL_PRIORITY_CLASS = &H20
Private Const STARTF_USESHOWWINDOW = &H1
Private Const SW_NORMAL = 1
Private hWndApp As Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetTopWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Const GW_HWNDFIRST = 0
Private Const GW_HWNDNEXT = 2
Private Const GW_HWNDPREV = 3
Public Function myEnumWindows(lParam As Long) As Long
Dim hWndNext As Long
Dim EnumerationInProgress As Boolean
EnumerationInProgress = True
hWndNext = GetTopWindow(GetDesktopWindow())
hWndNext = GetWindow(hWndNext, GW_HWNDFIRST)
Do While hWndNext <> 0 And EnumWindowsProc(hWndNext, lParam) <> 0
hWndNext = GetWindow(hWndNext, GW_HWNDNEXT)
Loop
End Function
Public Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
Dim hInstance As Long
EnumWindowsProc = True
GetWindowThreadProcessId hwnd, hInstance
If lParam = hInstance Then
hWndApp = hwnd
EnumWindowsProc = False ' End enumeration
End If
End Function
' Function returns slightly extended version of PROCESS_INFORMATION, containing one additional
' member, hWnd, which can be used by any API calls that require an hWnd as a parameter
' (eg SetWindowText)
Public Function RunNamedProgram(strProgram As String) As PROCESS_INFORMATION_EXT
Dim piProcess As PROCESS_INFORMATION
Dim siStartUp As STARTUPINFO
Dim lResult As Long
hWndApp = 0
lResult = CreateProcessA(vbNullString, strProgram, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, vbNullString, siStartUp, piProcess)
WaitForInputIdle piProcess.hProcess, INFINITE 'Let it initialise properly
' Use the first call here if running under NT4 or later. Use the second if
' under W9x/ME
Call EnumWindows(AddressOf EnumWindowsProc, piProcess.dwProcessID)
'Call myEnumWindows(piProcess.dwProcessID)
RunNamedProgram.hThread = piProcess.hThread
RunNamedProgram.hProcess = piProcess.hProcess
RunNamedProgram.hwnd = hWndApp
RunNamedProgram.dwProcessID = piProcess.dwProcessID
RunNamedProgram.dwThreadID = piProcess.dwThreadID
End Function