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.