Capture Text From Another Program 
Author Message
 Capture Text From Another Program

Keep in mind that every text box is a window, and has a window handle. The
Win32 API EnumWindows can be employed to iterate through all of the windows
in the system. It will take some trial and error experimenting before you
can reliably determine which is the window for the text box.

Once you know the text box window handle, you can call the GetWindowText
API.

If you can modify the other program, there are other techniques that might
be easier, but you did not say.

--
Phil Meeks
Systems Consultant
C{*filter*}te, NC


Quote:
> Is this possible?

> My program runs another program via the Shell command.
> Once the shell program is running, it starts to display
> progress messages in a TextBox.  I would like to get my
> calling program to capture the text that is being displayed
> and store it in a log file.  Anybody have any ideas how to
> do this?

> Barry

> Sent via Deja.com http://www.*-*-*.com/
> Share what you know. Learn what you don't.



Mon, 21 Jan 2002 03:00:00 GMT  
 Capture Text From Another Program
Oops, I did not read far enough into the API reference, to wit:

To retrieve the text of a control in another process, send a WM_GETTEXT
message directly instead of calling GetWindowText.

There you are.

--
Phil Meeks
Systems Consultant
C{*filter*}te, NC


Quote:
> Is this possible?

> My program runs another program via the Shell command.
> Once the shell program is running, it starts to display
> progress messages in a TextBox.  I would like to get my
> calling program to capture the text that is being displayed
> and store it in a log file.  Anybody have any ideas how to
> do this?

> Barry

> Sent via Deja.com http://www.*-*-*.com/
> Share what you know. Learn what you don't.



Mon, 21 Jan 2002 03:00:00 GMT  
 Capture Text From Another Program
Is this possible?

My program runs another program via the Shell command.
Once the shell program is running, it starts to display
progress messages in a TextBox.  I would like to get my
calling program to capture the text that is being displayed
and store it in a log file.  Anybody have any ideas how to
do this?

Barry

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.



Tue, 22 Jan 2002 03:00:00 GMT  
 Capture Text From Another Program
Hi Barry,

If the text box in question has the focus while showing the messages you
can use the GetFocus() API to get the handle of this window. Before this
though, you need to call  AttachThreadInput() API to synchronize your
thread input with the thread input of the other window. Once you have
the handle you can use the SendMessage() API to send the WM_GETTEXT
message as Phil suggested in his post.

Here is some code that will give the idea:

1. Open a new project
2. Place a Text1 TextBox on the Form. SET its Multiline property to
TRUE, and also give it a Vertical scroll bar to be able to see all the
text retrieved.
3. Place a Command1 button on the Form.
4. Copy the following code to the Form:

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA"
(ByVal hWnd As Long, ByVal wMsg As Long, wParam As Long, lParam As Any)
As Long
Private Declare Function SetFocusAPI Lib "user32" Alias "SetFocus"
(ByVal hWnd As Long) As Long

Private Declare Function GetFocus Lib "user32" () As Long
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Declare Function AttachThreadInput Lib "user32" (ByVal idAttach
As Long, ByVal idAttachTo As Long, ByVal fAttach As Long) As Long
Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal
hWnd As Long, lpdwProcessId 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 FindWindowEx Lib "user32" Alias "FindWindowExA"
(ByVal hWndParent As Long, ByVal hWndChildAfter As Long, ByVal lpszClass
As String, ByVal lpszName As String) As Long

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

Private Sub Command1_Click()
    Dim hWnd As Long
    Dim sText As String
    Dim sCmd As String
    Dim hProcessID As Long

    'Construct the Shell command
    sCmd = "Notepad.exe c:\autoexec.bat"

    'Start Notepad and open the autoexec.bat file
    hProcessID = Shell(sCmd, vbNormalFocus)

    'Wait until the program loads
    Do While hProcessID = 0
        DoEvents
    Loop

    'Wait a little more
    'Sleep 500

    'get the handle of the Textbox (Edit or Rich Edit control)
    'currently having the keyboard focus.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'NOTE that this function checks the class of
    'the window with focus to determine if it is
    'an Edit or Rich Control. I Some programs use their own
    'class derived from these controls and with diffrent name.
    'Such Edit ontrols will not be recognized.
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    hWnd = GetActiveTextBoxHandle()

    'Get the text from the text box
    If hWnd <> 0 Then
        GetTheText hWnd, sText
    End If

    'Show the retrieved text in the TextBox
    Text1.Text = sText

    'Set focus to text box
    Text1.SetFocus
End Sub

Private Sub Form_Load()
    Command1.Caption = "Get Text"
End Sub
Function GetActiveTextBoxHandle() As Long
    Dim lRetVal As Long
    Dim hForeGroundWindow As Long
    Dim lMyThreadID As Long
    Dim lOtherThreadID As Long
    Dim lOtherProcessID As Long
    Dim hTextBox As Long
    Dim sClassname As String

    GetActiveTextBoxHandle = 0 'Reset the function

    'Get the handle to the foreground window
    hForeGroundWindow = GetForegroundWindow()

    'Check if it is a valid handle
    If hForeGroundWindow <> 0 Then
        'You might include here a code to check if this is the AOL
window
        'by checking the window title
        'You can retrieve it with the GetText() API

        'Get your thread's ID
        lMyThreadID = GetCurrentThreadId()

        'Get the thread's ID of the other program
        lOtherThreadID = GetWindowThreadProcessId(hForeGroundWindow,
lOtherProcessID)

        'Attach your program to the thread input of the other program
        'You need this in order to be able to use GetFocus() on the
        'other window.
        lRetVal = AttachThreadInput(lOtherThreadID, lMyThreadID, 1)

        If lRetVal <> 0 Then
            'Success

            'Get the handle of the window currently having the keyboard
focus
            hTextBox = GetFocus()

            If hTextBox <> 0 Then
                'Success

                'Check if this is a text box window (control)
                sClassname = String$(100, Chr$(0))
                lRetVal = GetClassName(hTextBox, sClassname,
Len(sClassname))

                If lRetVal > 0 Then
                    'Success
                    sClassname = Left$(sClassname, lRetVal) 'get rid of
the terminating Null

                    If UCase$(sClassname) = "EDIT" Or _
                        UCase$(sClassname) = "THUNDERRT5TEXTBOX" Or _
                        UCase$(sClassname) = "RICHCNTL" Or _
                        UCase$(sClassname) = "RICHEDIT" Then
                        'Yes it is a text box control
                        GetActiveTextBoxHandle = hTextBox
                    End If
                End If
            End If
        End If
    End If

    'Detach from the other thread's input queue
    lRetVal = AttachThreadInput(lOtherThreadID, lMyThreadID, 0)
End Function
Sub GetTheText(hWnd As Long, sText As String)
    'hWnd - handle to the edit control(text box)
    'sText- will contain the text retrieved

    Dim lRetVal As Long

    'Get the length of the text in the text box
    lRetVal = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0&)

    'Allocate the memmory
    sText = String$(lRetVal + 1, Chr$(0))

    'Retrieve the text
    lRetVal = SendMessage(hWnd, WM_GETTEXT, ByVal Len(sText), ByVal
sText)

    'Get rid of the terminating Null
    sText = Left$(sText, lRetVal)
    'Debug.Print sText
End Sub

5. Run the Project and press the Command button. The Notepad should
start with the Autoexec.bat file opened and also the same text should be
visible in the Text Box of your program. If for some reason you do not
have an Autoexec.bat file - edit the sCmd string in the Command1_Click()
so that Notepad loads another text file.

NOTE that the GetActiveTextBoxHandle() may not recognize all Edit
Controls. It recognize only those I am aware about. If the program you
start derives its own Edit Control class with different name it will not
be recognized. You can add its class to the long If .. Then statement to
fix the problem. Or you cane remove this IF..Then altogether, so that
the text will be retrieved from whatever window has the focus.

Regards,
         Stoil

Quote:

> Is this possible?

> My program runs another program via the Shell command.
> Once the shell program is running, it starts to display
> progress messages in a TextBox.  I would like to get my
> calling program to capture the text that is being displayed
> and store it in a log file.  Anybody have any ideas how to
> do this?

> Barry

> Sent via Deja.com http://www.deja.com/
> Share what you know. Learn what you don't.



Tue, 22 Jan 2002 03:00:00 GMT  
 Capture Text From Another Program
If you need the text as it appears, such as with a multilevel progress
(ie. "Processing..." then "Negotiating...") then, I suggest subclassing
using the WM_SETTEXT or WM_CHAR message to catch each message sent.
Should you only need to capture the text box after all processes have
been completed, continually check the contents of the text box until
they are no longer changing (subclassing would also do the trick here,
but using a timer in conjunction with the window handle would also work)
and use the SendMessage / WM_GETTEXT combo described by the previous 2
comments.
Quote:

> Is this possible?

> My program runs another program via the Shell command.
> Once the shell program is running, it starts to display
> progress messages in a TextBox.  I would like to get my
> calling program to capture the text that is being displayed
> and store it in a log file.  Anybody have any ideas how to
> do this?

> Barry

> Sent via Deja.com http://www.deja.com/
> Share what you know. Learn what you don't.



Tue, 29 Jan 2002 03:00:00 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. How can I screen capture text from another program

2. Capture Text From Another Program

3. Capturing Text From Another Program

4. capturing the text in another program's window

5. Capture Documenter output under program control

6. Capture output from command line program

7. Screen Capture Program

8. Reading text from another program's Rich Text Box

9. How to Capture Dos Output in VB4 Program (HELP)

10. How do I capture other programs print output

11. capturing ouput of a DOS program

12. Running program and capturing output

 

 
Powered by phpBB® Forum Software