• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3372
  • Last Modified:

How to write text on a textbox of another program?

Some years ago, i've found a VB example showing how to "know" all controls on a window (i mean: any running program that have a form), find a Textbox in these controls and write text on it.

I've lost this source during these years... but now i need exactly to do that (in VB6)

Anyone know how to do that?
0
fab1970
Asked:
fab1970
1 Solution
 
jimbobmcgeeCommented:
Try

    For Each ctl in myForm.Controls

          If TypeOf ctl Is TextBox Then ctl.Text = "my text here"

    Next ctl

You may need to change ...Is TextBox... to ...Is VB.TextBox... or ...Is MSForms.TextBox... depending on what you are using...

HTH

J.
0
 
Ioannis ParaskevopoulosCommented:
Dim neededhWnd As Long
Dim Title As String

Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2
Const SWP_NOSIZE = &H1
Const SWP_NOMOVE = &H2
Const SWP_NOACTIVATE = &H10
Const SWP_SHOWWINDOW = &H40


Private Declare Function GetForegroundWindow Lib "user32" () As Long

'Get the name from a window hWnd
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 GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Long





Private Sub Timer1_Timer()
    neededhWnd = GetForegroundWindow()
    If neededhWnd <> Me.hWnd Then
        Length = GetWindowTextLength(neededhWnd)
        If (Length > 0) Then
          ListItem$ = Space$(Length + 1)
          Length = GetWindowText(neededhWnd, ListItem$, Length + 1)
          Title = ListItem$
        End If
    End If
End Sub


Private Sub cmdSendText_Click()
   
    AppActivate Title
    SendKeys txtMyTextToSend.Text
End Sub




'Put all this in the form's code window.Put also a textbox named txtMyTextToSend a command button named
'cmdSendText and a
'Timer named Timer1,with its interval property set to 100.The timer checks the handle of thecurrently active window every
'0.1 seconds.If the handle is different of that of your application,then it stores the handle in a varriable.With
'this varrible it finds the title of the window that had the focus before.
'To use this proggram you must select the control of the window where you want to write,then select your application
'and write what you want in the textbox.Then click on the control button andhe work is done.Try this code and tell me if
'there is any problem.


'This whole text has been written with the use of a virtual keyboard i have made.
0
 
fab1970Author Commented:
jyparask:
This code works as you've described.
BUT
i need to look in the window i need to write to find the controls it have inside (i "don't want" to click in the textbox before sending chars).
I know it's possible, with a lot of APIs works (i remember a barely readable code in the source sample i've lost, fullfilled of API calls....)
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
Erick37Commented:
The first thing to do is determine how to ID the main application window you need to interact with.

Do you want to use the application with focus, or can you search for the application using its window title, or exe name?
0
 
Erick37Commented:
Here is an example of using the API function EnumWindows and EnumChildWindows to find an Edit class window in a program with a specific window title.  We then call SendMessage with the WM_SETTEXT message to set the new text in the edit window.  The sample below uses Address Book as a test.

Note that the function uses the Like operator to search the Titles.  This gives more flexibility in finding your window.  e.g. to find an IE window use: "*Internet Explorer"

Here's the code


'~~~Form Code~~~~~
Option Explicit

Private Sub Command1_Click()

'Set the text in Windows Address Book
'Note the search string uses an asterisk because we search
'    using the Like operator and don't care about any text after "Address Book" in the title
Call WriteToAnotherEditWindow("Address Book*", "Hello API")

End Sub

'~~~~~~~~~~~~~~~Place the following in a standard code MODULE ~~~~~~~~~~~~~~~~~~~~~
Option Explicit

' The following adapted from the sample found at VBNet
' http://vbnet.mvps.org/index.html?code/enums/enumwindowsdemo.htm

'Search for a window with this string
Private sWindowTitleLike As String
'New text to place in edit window
Private sNewText As String
'Flag to see if we tried to set the text
Private bSuccess As Boolean


Private Const WM_SETTEXT = &HC

Public Declare Function EnumWindows Lib "user32" _
  (ByVal lpEnumFunc As Long, _
   ByVal lParam As Long) As Long
   
Public Declare Function EnumChildWindows Lib "user32" _
  (ByVal hWndParent As Long, _
   ByVal lpEnumFunc As Long, _
   ByVal lParam As Long) 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 GetClassName Lib "user32" _
    Alias "GetClassNameA" _
   (ByVal hwnd As Long, _
    ByVal lpClassName As String, _
    ByVal nMaxCount As Long) As Long

Private Declare Function IsWindowVisible Lib "user32" _
   (ByVal hwnd As Long) As Long
   
Private Declare Function GetParent Lib "user32" _
   (ByVal hwnd As Long) As Long

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


Public Function WriteToAnotherEditWindow(ByVal WindowTitleLike As String, ByVal EditText As String) As Boolean
    '
    'This function searches all top level windows to find one with a matching Window Title
    'Then all of the window's child windows are searched for an "Edit" class window
    'The text is then written to the Edit window
    '
    'save the search string to a module level variable
    sWindowTitleLike = WindowTitleLike
   
    'Save the new text to a module variable
    sNewText = EditText
   
    bSuccess = False
   
    'start searching...
    Call EnumWindows(AddressOf EnumWindowProc, &H0)
   
    WriteToAnotherEditWindow = bSuccess
   
End Function

Public Function EnumWindowProc(ByVal hwnd As Long, _
                               ByVal lParam As Long) As Long
   
    'working vars
    Dim nSize As Long
    Dim sTitle As String
    Dim sClass As String
   
    'eliminate windows that are not top-level.
    If GetParent(hwnd) = 0& And IsWindowVisible(hwnd) Then
       
        'get the window title / class name
        sTitle = GetWindowIdentification(hwnd, sClass)
   
        'Uses the Like operator to be more flexible in our search
        'See if we have found our window
        If sTitle Like sWindowTitleLike Then
            'we found the main window
            Debug.Print "Found: " & sTitle
         
            'Excellent, now search for an Edit window in this app
            Call EnumChildWindows(hwnd, AddressOf EnumChildProc, &H0)
         
            'stop looking
            EnumWindowProc = 0
            Exit Function
           
        End If
       
    End If
   
    'To continue enumeration, return True
    'To stop enumeration return False (0).
    'When 1 is returned, enumeration continues
    'until there are no more windows left.
    EnumWindowProc = 1
   
End Function


Private Function GetWindowIdentification(ByVal hwnd As Long, sClass As String) As String

    Dim nSize As Long
    Dim sTitle As String
   
    'get the size of the string required
    'to hold the window title
    nSize = GetWindowTextLength(hwnd)
   
    'if the return is 0, there is no title
    If nSize > 0 Then
   
        sTitle = Space$(nSize + 1)
        Call GetWindowText(hwnd, sTitle, nSize + 1)
       
    End If
       
    sClass = Space$(64)
    Call GetClassName(hwnd, sClass, 64)
    sClass = TrimNull(sClass)
   
   
    GetWindowIdentification = TrimNull(sTitle)

End Function


Public Function EnumChildProc(ByVal hwnd As Long, _
                              ByVal lParam As Long) As Long
   
    'working vars
    Dim sTitle As String
    Dim sClass As String
   
    'get the window title / class name
    sTitle = GetWindowIdentification(hwnd, sClass)
   
    'Look for an edit window
    If sClass = "Edit" Then
       
       Debug.Print Hex(hwnd)
       
       'set the new text
       
       '---===### The Main Point of this Sample ###===---
       Call SendMessage(hwnd, WM_SETTEXT, 0&, ByVal sNewText)
       
       bSuccess = True
       
       'Done looking
       EnumChildProc = 0
    Else
        'keep looking
        EnumChildProc = 1
    End If
   
End Function


Private Function TrimNull(startstr As String) As String

    Dim pos As Integer
   
    pos = InStr(startstr, Chr$(0))
   
    If pos Then
        TrimNull = Left$(startstr, pos - 1)
        Exit Function
    End If
   
    'if this far, there was
    'no Chr$(0), so return the string
    TrimNull = startstr
 
End Function

0
 
zzzzzoocCommented:
Here are two different approaches using FindWindowEx() and GetWindow(). They're more direct if you know the location of the window-handle you're looking for (use Spy++ to discover that).

Form1:
----------------------------------
Option Explicit

Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
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
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Private Const GW_HWNDFIRST = 0
Private Const GW_HWNDNEXT = 2
Private Const GW_CHILD = 5
Private Const WM_GETTEXT = &HD
Private Const WM_GETTEXTLENGTH = &HE
Private Const WM_SETTEXT = &HC
Private Sub Form_Load()
    Dim lngHandle As Long
    '1.) Find the window using FindWindowEx().
   
    'find our top-level window.. (Yahoo! IM in this case)
    lngHandle = FindWindow(vbNullString, "coozzzzz - Instant Message")
    If lngHandle > 0 Then
        'find the child window of lngHandle with the class-name of "RichEdit20A"...
        lngHandle = FindWindowEx(lngHandle, 0, "RichEdit20A", vbNullString)
        If lngHandle > 0 Then
            'set it's text..
            If WindowTextSet(lngHandle, "test") = True Then
                Call MsgBox("Success")
            End If
        End If
    End If
   
    '2.) Find the window using GetWindow()
    lngHandle = FindWindow(vbNullString, "coozzzzz - Instant Message")
    If lngHandle > 0 Then
        'get the first child-window...
        lngHandle = GetWindow(lngHandle, GW_CHILD)
        'loop through all of the child windows after the first...
        'until none is found or until our "RichEdit20A" window is found.
        Do Until lngHandle = 0 Or WindowClass(lngHandle) = "RichEdit20A"
            lngHandle = GetWindow(lngHandle, GW_HWNDNEXT)
        Loop
        If lngHandle > 0 Then
            'set it's text..
            If WindowTextSet(lngHandle, "test") = True Then
                Call MsgBox("Success")
            End If
        End If
    End If
End Sub
Private Function WindowClass(ByVal hWnd As Long) As String
    Const MAX_LEN As Byte = 255
    Dim strBuff As String, intLen As Integer
    strBuff = String(MAX_LEN, vbNullChar)
    intLen = GetClassName(hWnd, strBuff, MAX_LEN)
    WindowClass = Left(strBuff, intLen)
End Function
Private Function WindowTextGet(ByVal hWnd As Long) As String
    Dim strBuff As String, lngLen As Long
    lngLen = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0)
    If lngLen > 0 Then
        lngLen = lngLen + 1
        strBuff = String(lngLen, vbNullChar)
        lngLen = SendMessage(hWnd, WM_GETTEXT, lngLen, ByVal strBuff)
        WindowTextGet = Left(strBuff, lngLen)
    End If
End Function
Private Function WindowTextSet(ByVal hWnd As Long, ByVal strText As String) As Boolean
    WindowTextSet = (SendMessage(hWnd, WM_SETTEXT, Len(strText), ByVal strText) <> 0)
End Function
0
 
fab1970Author Commented:
Erick, your code works well, Thanks
Zzzzooc, i can't get your code working....
i admit that i don't know if the "Edit" class is a good value in place of your RichEdit20A...

For all:
I don't know if this needs to be asked in a new question, (so tell me) but how to send also the "Enter" key?
i was thinking that sending the vbCR character at the end of my text can works as "Enter" key.... that's not true.
0
 
Erick37Commented:
You can send an Enter key message using PostMessage:

Public Const WM_CHAR = &H102
Public Const VK_RETURN = &HD  'Enter Key
Public Const WM_KEYDOWN = &H100

'~~~~~~~~~~~~~~~~~~~~~~
'Module code
'~~~~~~~~~~~~~~~~~~~~~~
Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" ( _
   ByVal hwnd As Long, _
   ByVal wMsg As Long, _
   ByVal wParam As Long, _
   lParam As Long _
) As Long

'~~~~~~~~~~~~~~~~~~~~~~~

'Send the key
Call PostMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0)


0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now