Read/Write textbox of another application

Hi, I would like to know how can I read/write a textbox of anothers application (process) textbox1.

Example:
My program is - something.exe and there is a textbox in it .
Button1 gets a text from something2.exe (textbox1)
Button2 write's a text to something2.exe (textbox1)

Note: I don't have a source code of something2.exe .
_ColdFire_Asked:
Who is Participating?
 
Mike TomlinsonConnect With a Mentor Middle School Assistant TeacherCommented:
See if this works...
(I just copied Bob's code, pasted it below the form code, and added the necessary Imports at the top)
Imports System.Collections.Generic
Imports System.Runtime.InteropServices
Imports System.Text
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim ps() As Process = Process.GetProcessesByName("garena")
        If ps.Length > 0 Then
            Dim enumerator As New WindowsEnumerator
            For Each child As ApiWindow In enumerator.GetChildWindows(ps(0).MainWindowHandle)
                If child.ClassName.ToLower = "richedit20w" Then
                    Dim txt As String = child.MainWindowTitle
                    MessageBox.Show(txt, "Is this the text?")
                    Exit For
                End If
            Next
        End If
    End Sub

End Class

Public Class ApiWindow
    Public MainWindowTitle As String = ""
    Public ClassName As String = ""
    Public hWnd As Int32
End Class

''' <summary> 
''' Enumerate top-level and child windows 
''' </summary> 
''' <example> 
''' Dim enumerator As New WindowsEnumerator()
''' For Each top As ApiWindow in enumerator.GetTopLevelWindows()
'''    Console.WriteLine(top.MainWindowTitle)
'''    For Each child As ApiWindow child in enumerator.GetChildWindows(top.hWnd) 
'''        Console.WriteLine(" " + child.MainWindowTitle)
'''    Next child
''' Next top
''' </example> 
Public Class WindowsEnumerator

    Private Delegate Function EnumCallBackDelegate(ByVal hwnd As Integer, ByVal lParam As Integer) As Integer

    ' Top-level windows.
    Private Declare Function EnumWindows Lib "user32" _
     (ByVal lpEnumFunc As EnumCallBackDelegate, ByVal lParam As Integer) As Integer

    ' Child windows.
    Private Declare Function EnumChildWindows Lib "user32" _
     (ByVal hWndParent As Integer, ByVal lpEnumFunc As EnumCallBackDelegate, ByVal lParam As Integer) As Integer

    ' Get the window class.
    Private Declare Function GetClassName _
     Lib "user32" Alias "GetClassNameA" _
     (ByVal hwnd As Integer, ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer

    ' Test if the window is visible--only get visible ones.
    Private Declare Function IsWindowVisible Lib "user32" _
     (ByVal hwnd As Integer) As Integer

    ' Test if the window's parent--only get the one's without parents.
    Private Declare Function GetParent Lib "user32" _
     (ByVal hwnd As Integer) As Integer

    ' Get window text length signature.
    Private Declare Function SendMessage _
     Lib "user32" Alias "SendMessageA" _
     (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Int32) As Int32

    ' Get window text signature.
    Private Declare Function SendMessage _
     Lib "user32" Alias "SendMessageA" _
     (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As StringBuilder) As Int32

    Private _listChildren As New List(Of ApiWindow)
    Private _listTopLevel As New List(Of ApiWindow)

    Private _topLevelClass As String = ""
    Private _childClass As String = ""

    ''' <summary>
    ''' Get all top-level window information
    ''' </summary>
    ''' <returns>List of window information objects</returns>
    Public Overloads Function GetTopLevelWindows() As List(Of ApiWindow)

        EnumWindows(AddressOf EnumWindowProc, &H0)

        Return _listTopLevel

    End Function

    Public Overloads Function GetTopLevelWindows(ByVal className As String) As List(Of ApiWindow)

        _topLevelClass = className

        Return Me.GetTopLevelWindows()

    End Function

    ''' <summary>
    ''' Get all child windows for the specific windows handle (hwnd).
    ''' </summary>
    ''' <returns>List of child windows for parent window</returns>
    Public Overloads Function GetChildWindows(ByVal hwnd As Int32) As List(Of ApiWindow)

        ' Clear the window list.
        _listChildren = New List(Of ApiWindow)

        ' Start the enumeration process.
        EnumChildWindows(hwnd, AddressOf EnumChildWindowProc, &H0)

        ' Return the children list when the process is completed.
        Return _listChildren

    End Function

    Public Overloads Function GetChildWindows(ByVal hwnd As Int32, ByVal childClass As String) As List(Of ApiWindow)

        ' Set the search
        _childClass = childClass

        Return Me.GetChildWindows(hwnd)

    End Function

    ''' <summary>
    ''' Callback function that does the work of enumerating top-level windows.
    ''' </summary>
    ''' <param name="hwnd">Discovered Window handle</param>
    ''' <returns>1=keep going, 0=stop</returns>
    Private Function EnumWindowProc(ByVal hwnd As Int32, ByVal lParam As Int32) As Int32

        ' Eliminate windows that are not top-level.
        If GetParent(hwnd) = 0 AndAlso CBool(IsWindowVisible(hwnd)) Then

            ' Get the window title / class name.
            Dim window As ApiWindow = GetWindowIdentification(hwnd)

            ' Match the class name if searching for a specific window class.
            If _topLevelClass.Length = 0 OrElse window.ClassName.ToLower() = _topLevelClass.ToLower() Then
                _listTopLevel.Add(window)
            End If

        End If

        ' To continue enumeration, return True (1), and to stop enumeration 
        ' return False (0).
        ' When 1 is returned, enumeration continues until there are no 
        ' more windows left.

        Return 1

    End Function

    ''' <summary>
    ''' Callback function that does the work of enumerating child windows.
    ''' </summary>
    ''' <param name="hwnd">Discovered Window handle</param>
    ''' <returns>1=keep going, 0=stop</returns>
    Private Function EnumChildWindowProc(ByVal hwnd As Int32, ByVal lParam As Int32) As Int32

        Dim window As ApiWindow = GetWindowIdentification(hwnd)

        ' Attempt to match the child class, if one was specified, otherwise
        ' enumerate all the child windows.
        If _childClass.Length = 0 OrElse window.ClassName.ToLower() = _childClass.ToLower() Then
            _listChildren.Add(window)
        End If

        Return 1

    End Function

    ''' <summary>
    ''' Build the ApiWindow object to hold information about the Window object.
    ''' </summary>
    Private Function GetWindowIdentification(ByVal hwnd As Integer) As ApiWindow

        Const WM_GETTEXT As Int32 = &HD
        Const WM_GETTEXTLENGTH As Int32 = &HE

        Dim window As New ApiWindow()

        Dim title As New StringBuilder()

        ' Get the size of the string required to hold the window title.
        Dim size As Int32 = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0)

        ' If the return is 0, there is no title.
        If size > 0 Then
            title = New StringBuilder(size + 1)

            SendMessage(hwnd, WM_GETTEXT, title.Capacity, title)
        End If

        ' Get the class name for the window.
        Dim classBuilder As New StringBuilder(64)
        GetClassName(hwnd, classBuilder, 64)

        ' Set the properties for the ApiWindow object.
        window.ClassName = classBuilder.ToString()
        window.MainWindowTitle = title.ToString()
        window.hWnd = hwnd

        Return window

    End Function

End Class

Open in new window

0
 
mankowitzCommented:
I don't know how you could retreive a value from another program without decompiling it or looking through it with a debugger.

Sending information to another application should not be too hard, using sendkeys. Here is an example: http://msdn.microsoft.com/en-us/library/ms172702(VS.80).aspx
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
In a nutshell, obtain a handle to the TextBox via APIs such as FindWindow()/FindWindowEx() then grab the text from it using SendMessage() and WM_GETTEXT.

Here is an example using NotePad:
Public Class Form1

    Private Const WM_GETTEXT As Integer = &HD
    Private Const WM_GETTEXTLENGTH As Integer = &HE

    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
            (ByVal hWnd1 As IntPtr, ByVal hWnd2 As IntPtr, ByVal lpsz1 As String, _
            ByVal lpsz2 As String) As Integer

    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hWnd As IntPtr, ByVal wMsg As Integer, _
        ByVal wParam As Integer, ByVal lParam As Integer) As Integer

    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hWnd As IntPtr, ByVal wMsg As Integer, _
        ByVal wParam As Integer, ByVal lParam As System.Text.StringBuilder) As Integer

    Private Function GetText(ByVal hWnd As IntPtr) As String
        Dim textLength As Integer = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0) + 1
        Dim sb As New System.Text.StringBuilder(textLength)
        If textLength > 0 Then
            Call SendMessage(hWnd, WM_GETTEXT, textLength, sb)
        End If
        Return sb.ToString
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim ps() As Process = Process.GetProcessesByName("notepad")
        If ps.Length > 0 Then
            Dim noteWnd As IntPtr = ps(0).MainWindowHandle
            Dim editWnd As Integer = FindWindowEx(noteWnd, IntPtr.Zero, "Edit", "")
            Dim sTemp As String = GetText(editWnd)
            MessageBox.Show(sTemp)
        End If
    End Sub

End Class

Open in new window

0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

 
Mike TomlinsonMiddle School Assistant TeacherCommented:
*Oh...to go the opposite direction use WM_SETTEXT.
0
 
_ColdFire_Author Commented:
Idle_Mind , code works for notepad, but it doesn't work for the application i need.
Actually applications name is Garena.exe. I have to enter the room and there is chat window from witch i want to be able to read text and write.

If you don't know that program , then probably you can download it and register and then have a look at it. :P

http://download3.garena.com/Garena4.0Beta.rar
0
 
_ColdFire_Author Commented:
register new account - is free.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Can you post a screenshot of the window for us?

Use Spy++ or the free Winspector (Google it) to inspect the target app.  Drag the "cross hairs" over the target window and report back the classname of it.

If that is a JAVA app then you may have to resort to other lower level approaches...  =\
0
 
_ColdFire_Author Commented:
I need to get a text from the textbox where System messages are displayed.
IMG.png
0
 
_ColdFire_Author Commented:
Class name is RichEdit20W
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Ok...good start!

Do you have Spy++ (it comes with Visual Studio)?  If not, please download WinSpector and use it to find out some useful information about your target app.

I've attached a screenshot of Winspector after I've dragged the cross-hairs onto the edit portion.  This allows you to see the hierarchy of the controls with respect to each other.

This is necessary for us to determine the correct number and/or order of FindWindow()/FindWindowEx() calls to get a handle to your "RichEdit20W" window.

As you can see, in Notepad, the "Edit" window is a direct child of the main window which makes the code very easy.

Your app will probably be more complex and require more in-depth code to get the correct window:
WinspectorWithNotepad.jpg
0
 
_ColdFire_Author Commented:
Could u please download and check it for me.. cuz I really don't want to mess something up.
0
 
_ColdFire_Author Commented:
This is what I get...
RichEdit20W.png
0
 
_ColdFire_Author Commented:
That textbox is far away from main window as I see..
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Haha...it sure is buried deep in there!  Using FindWindow()/FindWindowEx() you have to start with the main window and then get the next parent in the sequence.  When you have multiple classes of the same type at the same level and you need the one that is NOT the first one then you have to call it multiple times to get the correct one.  Pain in the butt...

An alternative approach is to use the EnumWindows()/EnumChildWindows() approach to find the target window:
http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Basic.NET/Q_23357525.html
0
 
_ColdFire_Author Commented:
I have no clue how to use it...
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
I'll see if I can post a clean example of using it later today...   =)
(sorry...busy doing housework this morning!)
0
 
_ColdFire_Author Commented:
I compiled that program and used streamwriter so it writes output to text file and what i have is....
output.txt
0
 
_ColdFire_Author Commented:
new output file without personal information...
output.txt
0
 
_ColdFire_Author Commented:
how can i remove old one ?: D
0
 
_ColdFire_Author Commented:
It works, the thing is, that I have to get list of tcp connections and when player joins (Garena types message) Player joined your game. On tcp connections I can see that somebody connected like localhost:someport (localhost:46910) i have to determinate which connection for which player is .. as it just shows localhost and port but doesnt show players name.. so how can i capture that?!
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
You'd have to show me some examples of what happens when people join, etc. so I could help you parse the data...
0
 
_ColdFire_Author Commented:
just a sec. :)
0
 
_ColdFire_Author Commented:
[23:06:21] [System Message] <[Crack]>[Ping:219]  has joined your game!.

So how can i filter only messages when somebody joined and then create a time stamp when NEW TCP Connection is created for the process on that time.

On the image you can see that somebody is connected to my game and there is local port 6112 which remains same for everyone but remote port is different for every player.

On the image there is port 57341 if there would be other player there would be other connection with different port like 57342 or 61836 .. any free random port. So i have to capture the time when player is connected and time when that TCP connection is established.
TCP.png
0
 
_ColdFire_Author Commented:
So it shows in my application like that

[23:06:21] [System Message] <[Crack]>[Ping:219]  has joined your game!. Port: 57341
0
 
_ColdFire_Author Commented:
Program reads everything that is in textbox of garena but how can I write something into it?
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
I haven't looked at analyzing the strings yet...hopefully I can get to that later today.

As for writing something to the box, try the below out.

I added a second button and some additional code:
    Private Const WM_GETTEXTLENGTH As Integer = &HE
    Private Const EM_SETSEL As Integer = &HB1
    Private Const EM_REPLACESEL As Integer = &HC

    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hwnd As Int32, ByVal wMsg As Integer, ByVal wParam As Integer, _
        ByVal lParam As String) As Integer

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim ps() As Process = Process.GetProcessesByName("garena")
        If ps.Length > 0 Then
            Dim enumerator As New WindowsEnumerator
            For Each child As ApiWindow In enumerator.GetChildWindows(ps(0).MainWindowHandle)
                If child.ClassName.ToLower = "richedit20w" Then
                    Dim textLength As Integer = SendMessage(child.hWnd, WM_GETTEXTLENGTH, 0, 0)
                    SendMessage(child.hWnd, EM_SETSEL, textLength, 0) 
                    SendMessage(child.hWnd, EM_REPLACESEL, 0, "Can you hear me now?" & vbCrLf) 
                    Exit For
                End If
            Next
        End If
    End Sub

Open in new window

0
 
_ColdFire_Author Commented:
code works fine but it clears all chat window before it posts my message, is there any way to fix that?
0
 
_ColdFire_Author Commented:
well, it doesn't work like it should be cuz only I can see that message. Don't overload yourself as this function is not too essential for me... just get on with analyzing the strings when u can.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
That code works with a standard edit control (like in Notepad) and I wasn't too sure it would work with a RichEdit control.

There specific messages for a RichEdit you can use but they require a little more code...think you need EM_EXSETSEL and EMSETEXTEX:
http://msdn.microsoft.com/en-us/library/bb788007(VS.85).aspx
http://msdn.microsoft.com/en-us/library/bb774284(VS.85).aspx
0
 
_ColdFire_Author Commented:
Ok, application works fine, it reads text from garena and it's ok. So now i just need to filter those text messages and show only player join/leave messages and time like hh:mm:ss:miliseconds
0
 
_ColdFire_Author Commented:
time when each player joins or leaves
0
 
_ColdFire_Author Commented:
What's about EM_EXSETSEL and EMSETEXTEX , I don't really know how to use it.. can u give some examples please?
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
I would consider your "core" question WELL answered:

    "I need to get a text from the textbox where System messages are displayed."

With this comment:
http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Studio_.NET_2005/Q_25007794.html#26141485
And your response of:

    "It works"

I suggest you close this question and ask a new one for the parsing aspect as it really isn't related to the original problem...
0
 
_ColdFire_Author Commented:
agree
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.