Mercurtio
asked on
SendMessage API
I've made a program with a textbox and now Im making another one and attempting to add letters etc into a textbox on the first program. I've got the handle of the control by searching for 'ThunderTextBox' as the control name and then use the following code but it doesnt seem to work.
Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal _
wParam As Long, lParam As Any) As Long
Const WM_KEYDOWN = &H100
Const WM_KEYUP = &H101
Private Sub Command2_Click()
Call SendMessage(lhwnd, WM_KEYDOWN, 115, 0)
Call SendMessage(lhwnd, WM_KEYUP, 115, 0)
End Sub
Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal _
wParam As Long, lParam As Any) As Long
Const WM_KEYDOWN = &H100
Const WM_KEYUP = &H101
Private Sub Command2_Click()
Call SendMessage(lhwnd, WM_KEYDOWN, 115, 0)
Call SendMessage(lhwnd, WM_KEYUP, 115, 0)
End Sub
See this code, this gives an idea
Option Explicit
Private Sub Command1_Click()
Dim lRet As Long, lParam As Long
Dim lhWnd As Long
iFreeFile = FreeFile
lhWnd = Me.hwnd ' Find the Form's Child Windows
' Comment the line above and uncomment the line below to
' enumerate Windows for the DeskTop rather than for the Form
'lhWnd = GetDesktopWindow() ' Find the Desktop's Child Windows
' enumerate the list
lRet = EnumChildWindows(lhWnd, AddressOf EnumChildProc, lParam)
End Sub
Private Sub Command2_Click()
Dim lRet As Long
Dim lParam As Long
iFreeFile = FreeFile
Open "D:\TEST.TXT" For Output As #iFreeFile
'enumerate the list
lRet = EnumWindows(AddressOf EnumWinProc, lParam)
' How many Windows did we find?
Print #1, TopCount; " Total Top level Windows"
Print #1, ChildCount; " Total Child Windows"
Print #1, ThreadCount; " Total Thread Windows"
Print #1, "For a grand total of "; TopCount + _
ChildCount + ThreadCount; " Windows!"
Close #1
End Sub
Option Explicit
Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Public iFreeFile As Integer
Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, _
lpRect As RECT) As Long
Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, _
ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, _
ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function EnumWindows Lib "user32" _
(ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent _
As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function EnumThreadWindows Lib "user32" (ByVal dwThreadId _
As Long, ByVal lpfn As Long, ByVal lParam As Long) As Long
Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, lpdwProcessId As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
(ByVal hwnd As Long, ByVal lpClassName As String, _
ByVal nMaxCount 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
Public TopCount As Integer ' Number of Top level Windows
Public ChildCount As Integer ' Number of Child Windows
Public ThreadCount As Integer ' Number of Thread Windows
Function EnumWinProc(ByVal lhWnd As Long, ByVal lParam As Long) _
As Long
Dim RetVal As Long, ProcessID As Long, ThreadID As Long
Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
Dim WinClass As String, WinTitle As String
RetVal = GetClassName(lhWnd, WinClassBuf, 255)
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
WinTitle = StripNulls(WinTitleBuf)
TopCount = TopCount + 1
' see the Windows Class and Title for each top level Window
Debug.Print "Top level Class = "; WinClass; ", Title = "; WinTitle
' Usually either enumerate Child or Thread Windows, not both.
' In this example, EnumThreadWindows may produce a very long list!
RetVal = EnumChildWindows(lhWnd, AddressOf EnumChildProc, lParam)
ThreadID = GetWindowThreadProcessId(l hWnd, ProcessID)
RetVal = EnumThreadWindows(ThreadID , AddressOf EnumThreadProc, _
lParam)
EnumWinProc = True
End Function
Function EnumChildProc(ByVal lhWnd As Long, ByVal lParam As Long) _
As Long
Dim RetVal As Long
Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
Dim WinClass As String, WinTitle As String
Dim WinRect As RECT
Dim WinWidth As Long, WinHeight As Long
RetVal = GetClassName(lhWnd, WinClassBuf, 255)
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
WinTitle = StripNulls(WinTitleBuf)
ChildCount = ChildCount + 1
' see the Windows Class and Title for each Child Window enumerated
Debug.Print " Child Class = "; WinClass; ", Title = "; WinTitle
' You can find any type of Window by searching for its WinClass
If WinClass = "ThunderTextBox" Then ' TextBox Window
RetVal = GetWindowRect(lhWnd, WinRect) ' get current size
WinWidth = WinRect.Right - WinRect.Left ' keep current width
WinHeight = (WinRect.Bottom - WinRect.Top) * 2 ' double height
RetVal = MoveWindow(lhWnd, 0, 0, WinWidth, WinHeight, True)
EnumChildProc = False
Else
EnumChildProc = True
End If
End Function
Function EnumThreadProc(ByVal lhWnd As Long, ByVal lParam As Long) _
As Long
Dim RetVal As Long
Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
Dim WinClass As String, WinTitle As String
RetVal = GetClassName(lhWnd, WinClassBuf, 255)
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
WinTitle = StripNulls(WinTitleBuf)
ThreadCount = ThreadCount + 1
' see the Windows Class and Title for top level Window
Debug.Print "Thread Window Class = "; WinClass; ", Title = "; _
WinTitle
EnumThreadProc = True
End Function
Public Function StripNulls(OriginalStr As String) As String
' This removes the extra Nulls so String comparisons will work
If (InStr(OriginalStr, Chr(0)) > 0) Then
OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
End If
StripNulls = OriginalStr
End Function
Option Explicit
Private Sub Command1_Click()
Dim lRet As Long, lParam As Long
Dim lhWnd As Long
iFreeFile = FreeFile
lhWnd = Me.hwnd ' Find the Form's Child Windows
' Comment the line above and uncomment the line below to
' enumerate Windows for the DeskTop rather than for the Form
'lhWnd = GetDesktopWindow() ' Find the Desktop's Child Windows
' enumerate the list
lRet = EnumChildWindows(lhWnd, AddressOf EnumChildProc, lParam)
End Sub
Private Sub Command2_Click()
Dim lRet As Long
Dim lParam As Long
iFreeFile = FreeFile
Open "D:\TEST.TXT" For Output As #iFreeFile
'enumerate the list
lRet = EnumWindows(AddressOf EnumWinProc, lParam)
' How many Windows did we find?
Print #1, TopCount; " Total Top level Windows"
Print #1, ChildCount; " Total Child Windows"
Print #1, ThreadCount; " Total Thread Windows"
Print #1, "For a grand total of "; TopCount + _
ChildCount + ThreadCount; " Windows!"
Close #1
End Sub
Option Explicit
Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Public iFreeFile As Integer
Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, _
lpRect As RECT) As Long
Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, _
ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, _
ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function EnumWindows Lib "user32" _
(ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent _
As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function EnumThreadWindows Lib "user32" (ByVal dwThreadId _
As Long, ByVal lpfn As Long, ByVal lParam As Long) As Long
Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, lpdwProcessId As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
(ByVal hwnd As Long, ByVal lpClassName As String, _
ByVal nMaxCount 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
Public TopCount As Integer ' Number of Top level Windows
Public ChildCount As Integer ' Number of Child Windows
Public ThreadCount As Integer ' Number of Thread Windows
Function EnumWinProc(ByVal lhWnd As Long, ByVal lParam As Long) _
As Long
Dim RetVal As Long, ProcessID As Long, ThreadID As Long
Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
Dim WinClass As String, WinTitle As String
RetVal = GetClassName(lhWnd, WinClassBuf, 255)
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
WinTitle = StripNulls(WinTitleBuf)
TopCount = TopCount + 1
' see the Windows Class and Title for each top level Window
Debug.Print "Top level Class = "; WinClass; ", Title = "; WinTitle
' Usually either enumerate Child or Thread Windows, not both.
' In this example, EnumThreadWindows may produce a very long list!
RetVal = EnumChildWindows(lhWnd, AddressOf EnumChildProc, lParam)
ThreadID = GetWindowThreadProcessId(l
RetVal = EnumThreadWindows(ThreadID
lParam)
EnumWinProc = True
End Function
Function EnumChildProc(ByVal lhWnd As Long, ByVal lParam As Long) _
As Long
Dim RetVal As Long
Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
Dim WinClass As String, WinTitle As String
Dim WinRect As RECT
Dim WinWidth As Long, WinHeight As Long
RetVal = GetClassName(lhWnd, WinClassBuf, 255)
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
WinTitle = StripNulls(WinTitleBuf)
ChildCount = ChildCount + 1
' see the Windows Class and Title for each Child Window enumerated
Debug.Print " Child Class = "; WinClass; ", Title = "; WinTitle
' You can find any type of Window by searching for its WinClass
If WinClass = "ThunderTextBox" Then ' TextBox Window
RetVal = GetWindowRect(lhWnd, WinRect) ' get current size
WinWidth = WinRect.Right - WinRect.Left ' keep current width
WinHeight = (WinRect.Bottom - WinRect.Top) * 2 ' double height
RetVal = MoveWindow(lhWnd, 0, 0, WinWidth, WinHeight, True)
EnumChildProc = False
Else
EnumChildProc = True
End If
End Function
Function EnumThreadProc(ByVal lhWnd As Long, ByVal lParam As Long) _
As Long
Dim RetVal As Long
Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
Dim WinClass As String, WinTitle As String
RetVal = GetClassName(lhWnd, WinClassBuf, 255)
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
WinTitle = StripNulls(WinTitleBuf)
ThreadCount = ThreadCount + 1
' see the Windows Class and Title for top level Window
Debug.Print "Thread Window Class = "; WinClass; ", Title = "; _
WinTitle
EnumThreadProc = True
End Function
Public Function StripNulls(OriginalStr As String) As String
' This removes the extra Nulls so String comparisons will work
If (InStr(OriginalStr, Chr(0)) > 0) Then
OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
End If
StripNulls = OriginalStr
End Function
ASKER
I need to use it for other controls so I cant use settext. I tried sending the keydown to a listbox control on my computer game and nothing happened so decided to test it on a single textbox on a form and it still doesnt work. My complete codes below
The module that contains code to get the handle for the textbox
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal Classname As String, ByVal WindowName As String) As Long
Public Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal _
wParam As Long, lParam As Any) As Long
Public Declare Function SetFocus Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function EnumChildWindows Lib "user32.dll" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Public Declare Function ShowWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Public lhwnd As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd 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 EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private m_TargetString As String
Private m_TargetHwnd As Long
Dim d As Integer
' Check a returned task to see if it's the one we want.
Public Function EnumCallback(ByVal app_hWnd As Long, ByVal param As Long) As Long
Dim buf As String
Dim Title As String
Dim length As Long
' Get the window's title.
length = GetWindowTextLength(app_hW nd)
buf = Space$(length)
length = GetWindowText(app_hWnd, buf, length)
Title = Left$(buf, length)
' See if the title contains the target string.
If InStr(Title, m_TargetString) <> 0 Then
' This is the one we want.
m_TargetHwnd = app_hWnd
' Stop searching.
EnumCallback = 0
Else
' Continue searching.
EnumCallback = 1
End If
End Function
' Find a window with a title containing target_string
' and return its hWnd.
Public Function FindWindowByPartialTitle(B yVal target_string As String) As Long
m_TargetString = target_string
m_TargetHwnd = 0
' Enumerate windows.
EnumWindows AddressOf EnumCallback, 0
' Return the hWnd found (if any).
FindWindowByPartialTitle = m_TargetHwnd
End Function
Public Function Fun_EnumChildWindows(ByVal lngHwnd As Long, ByVal lngLParam As Long) As Long
Dim strClassName As String
Dim lngClassNameLen As Long
' Set some room for storing class name
strClassName = Space$(255)
' Get class name of current enumerated child window
lngClassNameLen = GetClassName(lngHwnd, strClassName, 255)
' Get only valid characters (lngClassNameLen)
strClassName = Left$(strClassName, lngClassNameLen)
' Check the class name
If strClassName = "ThunderRT6TextBox" Then
' Text box is found, show message with info
lhwnd = lngHwnd
Fun_EnumChildWindows = 0
Exit Function
End If
' Return 1 to continue enumeration with next window
' If no class is found
Fun_EnumChildWindows = 1
End Function
The form that contains the code where I'm trying to send the keydown and up to the textbox on the other program.
Const WM_KEYDOWN = &H100
Const WM_KEYUP = &H101
Private Sub Command1_Click()
Dim target_hwnd As Long
' Find the window.
target_hwnd = FindWindowByPartialTitle(" Graal:")
' Start enumerating child windows of known window hwnd
EnumChildWindows target_hwnd, AddressOf Fun_EnumChildWindows, 0
End Sub
Private Sub Command3_Click()
Call SendMessage(lhwnd, WM_KEYDOWN, 115, 0)
Call SendMessage(lhwnd, WM_KEYUP, 115, 0)
End Sub
The module that contains code to get the handle for the textbox
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal Classname As String, ByVal WindowName As String) As Long
Public Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal _
wParam As Long, lParam As Any) As Long
Public Declare Function SetFocus Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function EnumChildWindows Lib "user32.dll" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Public Declare Function ShowWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Public lhwnd As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd 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 EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private m_TargetString As String
Private m_TargetHwnd As Long
Dim d As Integer
' Check a returned task to see if it's the one we want.
Public Function EnumCallback(ByVal app_hWnd As Long, ByVal param As Long) As Long
Dim buf As String
Dim Title As String
Dim length As Long
' Get the window's title.
length = GetWindowTextLength(app_hW
buf = Space$(length)
length = GetWindowText(app_hWnd, buf, length)
Title = Left$(buf, length)
' See if the title contains the target string.
If InStr(Title, m_TargetString) <> 0 Then
' This is the one we want.
m_TargetHwnd = app_hWnd
' Stop searching.
EnumCallback = 0
Else
' Continue searching.
EnumCallback = 1
End If
End Function
' Find a window with a title containing target_string
' and return its hWnd.
Public Function FindWindowByPartialTitle(B
m_TargetString = target_string
m_TargetHwnd = 0
' Enumerate windows.
EnumWindows AddressOf EnumCallback, 0
' Return the hWnd found (if any).
FindWindowByPartialTitle = m_TargetHwnd
End Function
Public Function Fun_EnumChildWindows(ByVal
Dim strClassName As String
Dim lngClassNameLen As Long
' Set some room for storing class name
strClassName = Space$(255)
' Get class name of current enumerated child window
lngClassNameLen = GetClassName(lngHwnd, strClassName, 255)
' Get only valid characters (lngClassNameLen)
strClassName = Left$(strClassName, lngClassNameLen)
' Check the class name
If strClassName = "ThunderRT6TextBox" Then
' Text box is found, show message with info
lhwnd = lngHwnd
Fun_EnumChildWindows = 0
Exit Function
End If
' Return 1 to continue enumeration with next window
' If no class is found
Fun_EnumChildWindows = 1
End Function
The form that contains the code where I'm trying to send the keydown and up to the textbox on the other program.
Const WM_KEYDOWN = &H100
Const WM_KEYUP = &H101
Private Sub Command1_Click()
Dim target_hwnd As Long
' Find the window.
target_hwnd = FindWindowByPartialTitle("
' Start enumerating child windows of known window hwnd
EnumChildWindows target_hwnd, AddressOf Fun_EnumChildWindows, 0
End Sub
Private Sub Command3_Click()
Call SendMessage(lhwnd, WM_KEYDOWN, 115, 0)
Call SendMessage(lhwnd, WM_KEYUP, 115, 0)
End Sub
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Excellent I couldnt get it to work using 115 I had to do it like this to get it to work
Const VK_T = &H54
keybd_event VK_T, 0, 0, 0
Const VK_T = &H54
keybd_event VK_T, 0, 0, 0
Private Const WM_SETTEXT = &HC
Call SendMessage(lhwnd, WM_SETTEXT, 0, ByVal "Hello")