Solved

SendMessage API

Posted on 2004-08-20
5
968 Views
Last Modified: 2007-12-19
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
0
Comment
Question by:Mercurtio
5 Comments
 
LVL 28

Expert Comment

by:AzraSound
Comment Utility
I would use WM_SETTEXT instead:

Private Const WM_SETTEXT = &HC

Call SendMessage(lhwnd, WM_SETTEXT, 0, ByVal "Hello")
0
 
LVL 5

Expert Comment

by:rajaamirapu
Comment Utility
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
 


0
 

Author Comment

by:Mercurtio
Comment Utility
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

0
 
LVL 22

Accepted Solution

by:
DarkoLord earned 195 total points
Comment Utility
Hi, use this:

Private Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Private Sub Command3_Click()
    SetForeGroundWindow lhwnd
    keybd_event 115, 0, 0, 0
    keybd_event 115, 0, &H2, 0
End Sub

Darko
0
 

Author Comment

by:Mercurtio
Comment Utility
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
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now