Option Explicit
Private Const ConsoleClassName As String = "ConsoleWindowClass"
Private Const PuTTYClassName As String = "PuTTY"
Private Const WM_CHAR As Long = &H102
Private Const WM_KEYDOWN As Long = &H100
Private Const GW_HWNDNEXT = 2
'https://msdn.microsoft.com/en-us/library/office/gg264421.aspx
'64-Bit Visual Basic for Applications Overview
#If VBA7 Then
'New VBA version 7 compiler, therefore >= Office 2010
'PtrSafe means function works in 32-bit and 64-bit Office
'LongPtr type alias resolves to Long (32 bits) in 32-bit Office, or LongLong (64 bits) in 64-bit Office
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function GetParent Lib "user32" _
(ByVal hwnd As LongPtr) As LongPtr
Private Declare PtrSafe Function GetWindow Lib "user32" _
(ByVal hwnd As LongPtr, ByVal wCmd As Long) As LongPtr
Private Declare PtrSafe Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As LongPtr, ByVal lpdwProcessId As LongPtr) As Long
Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As LongPtr, ByVal lpString As String, ByVal cch As LongPtr) As Long
Private Declare PtrSafe Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long)
Private Declare PtrSafe Function PostMessage Lib "user32" Alias "PostMessageA" _
(ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As Long
#Else
'Old VBA version 6 or earlier compiler, therefore <= Office 2007
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetParent 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 Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, ByVal lpdwProcessId 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 Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds 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
#End If
#If VBA7 Then
Public Sub SendChars(hwnd As LongPtr, sChars As String)
#Else
Public Sub SendChars(hwnd As Long, sChars As String)
#End If
Dim i As Long
Dim ret As Long
For i = 1 To Len(sChars)
ret = PostMessage(hwnd, WM_CHAR, Asc(Mid(sChars, i, 1)), 0&)
'ret = PostMessage(hWnd, WM_KEYDOWN, Asc(Mid(sChars, i, 1)), 0&)
Next
End Sub
'Original code with argument name changed from hInstance to pid and without debugging to get window title
#If VBA7 Then
Public Function GetWindowHandle(pid As Long) As LongPtr
#Else
Public Function GetWindowHandle(pid As Long) As Long
#End If
#If VBA7 Then
Dim tempHwnd As LongPtr
#Else
Dim tempHwnd As Long
#End If
Dim strWindowTitle As String
' Grab the first window handle that Windows finds:
tempHwnd = FindWindow(vbNullString, vbNullString)
' Loop until you find a match or there are no more window handles:
Do Until tempHwnd = 0
' Check if no parent for this window
If GetParent(tempHwnd) = 0 Then
' Check for PID match
If pid = ProcIDFromWnd(tempHwnd) Then
' Return found handle
GetWindowHandle = tempHwnd
' Exit search loop
Exit Do
End If
End If
' Get the next window handle
tempHwnd = GetWindow(tempHwnd, GW_HWNDNEXT)
Loop
End Function
#If VBA7 Then
Private Function ProcIDFromWnd(ByVal hwnd As LongPtr) As Long
#Else
Private Function ProcIDFromWnd(ByVal hwnd As Long) As Long
#End If
Dim idProc As Long
' Get PID for this HWnd
GetWindowThreadProcessId hwnd, VarPtr(idProc)
' Return PID
ProcIDFromWnd = idProc
End Function