Link to home
Start Free TrialLog in
Avatar of Mercurtio
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
Avatar of AzraSound
AzraSound
Flag of United States of America image

I would use WM_SETTEXT instead:

Private Const WM_SETTEXT = &HC

Call SendMessage(lhwnd, WM_SETTEXT, 0, ByVal "Hello")
Avatar of rajaamirapu
rajaamirapu

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(lhWnd, 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
 


Avatar of Mercurtio

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_hWnd)
    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(ByVal 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

ASKER CERTIFIED SOLUTION
Avatar of DarkoLord
DarkoLord
Flag of Slovenia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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