Help with FindWindow & SendMessage for username & pw text boxes
I'm needing a little help with using FindWindow, FindWindowEx, and SendMessage in order to pass a username and password to a login dialogue box from another application.
I am trying to pass a username & password to an application, and make it hit the "ok" button. The issue that I am having is that both of the text boxes used for username & password have the class of "Edit" and are both blank.
How do i determine which textbox is which, and send the correct login info to them?
I had this working with another application, but when I tried it with Internet Explorer login prompt, and with another app, I get an error message. Here is the code that I'm using, but I get a debug error.
I have to say that I'm not super efficient in coding, but I can normally adapt simple code to my needs, but I don't understand why I'm getting an error. All help is much appreciated!
Code:
Option Explicit
'Run the control.exe in the app.path and execute this code.
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) 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 Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
'Used here to retrive the child windows from a given parent window
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
'used here to obtain the top position of the Text Boxes in the Screen.
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
'Used to get the Class names of the controls
Private Const WM_SETTEXT = &HC
Private Const GW_HWNDNEXT = 2
Private Const GW_CHILD = 5
Private Type RECT 'GetWindowRect use this structure to store the values it ritrive.
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private StrClass As String * 255
Code:
Private Sub Command1_Click()
Dim lhnd As Long 'parent window handle
Dim lhndChild As Long 'child window handle
Dim TxtUnameHnd As Long 'The user name text box handle
Dim txtPassHnd As Long 'the password text box handle
Dim lngresult As Long
Dim i As Integer 'Used with instr() To manipulate the class text returned.
Dim StrClassName As String 'GetClassName used this buffer to store the class name
Dim rec As RECT
Dim strItems(1, 1) As Long 'Initializing a two Diamensional Array to hold the Handles and RECT's Top value of the two text boxes.
Dim p As Integer 'Used with arry element position.
lhnd = FindWindow(vbNullString, "User Logon") 'Returns the specified windows Handle
lhndChild = GetWindow(lhnd, GW_CHILD) 'Retrieves handles of the child windows in the 'user logon' window....not sure why this is needed.
Do
lhndChild = GetWindow(lhndChild, GW_HWNDNEXT) 'Get text of the fist child window
If lhndChild = 0 Then Exit Do 'IF no more child window to ritrive, then exit.
Call GetClassName(lhndChild, StrClass, 255) 'get class name of the first child window
i = InStr(1, StrClass, Chr$(0)) 'trim the Null Charactors of strClass buffer
If Left$(StrClass, i - 1) = "Edit" Then 'Check weather the contol class name is a TextBox (ThunderRT6TextBox).
GetWindowRect lhndChild, rec 'Get that windows screen top position.
strItems(p, 0) = lhndChild 'store the handle in the arrys. <------Run Time Error 9 Subscript out of range.
strItems(p, 1) = rec.Top ' Strore the top value in the arry.
p = p + 1
End If
Loop
'Find the Username text box by Manipulating the top positions of the two text boxes.
If strItems(0, 1) < strItems(1, 1) Then
TxtUnameHnd = strItems(0, 0) 'assign the handle
txtPassHnd = strItems(1, 0)
Else
TxtUnameHnd = strItems(1, 0) 'assign the handle
txtPassHnd = strItems(0, 0)
End If
lngresult = SendMessage(TxtUnameHnd, WM_SETTEXT, 0&, ByVal "Test")
lngresult = SendMessage(txtPassHnd, WM_SETTEXT, 0&, ByVal "Password")
End Sub
Re: Help with FindWindow & SendMessage for username & pw text boxes
Have you tried dimensioning p As Long? Try tracking the values of the strItems array by stepping through the Do..Loop (press F8) and see at which point you get the "Subscript out of range" error. You may also use a UDT array instead of a 2-dimensional array for faster access.
Re: Help with FindWindow & SendMessage for username & pw text boxes
Quote:
Originally Posted by
Bonnie West
Have you tried dimensioning p As Long? Try tracking the values of the strItems array by stepping through the Do..Loop (press F8) and see at which point you get the "Subscript out of range" error. You may also use a UDT array instead of a 2-dimensional array for faster access.
I tried to Dim 'p' as Long but still gave me the same debug error message.
It keeps on erroring out at:
strItems(p, 0) = lhndChild 'store the handle in the arrys.
when hitting F8 and stepping through it.
Re: Help with FindWindow & SendMessage for username & pw text boxes
That's probably because you've declared the strItems array as:
Code:
Dim strItems(0 To 1, 0 To 1) As Long
There are two dimensions in the array, but each dimension is limited to only 2 elements (from 0 to 1). Perhaps, you may find it easier if you use a UDT array instead, sort of like this:
Code:
Private Type WindowInfo
hWnd As Long
Top As Long
End Type
Private Sub Command1_Click()
Dim strItems() As WindowInfo
. . .
ReDim strItems(0 To 0) As WindowInfo
. . .
If . . .
strItems(p).hWnd = lhndChild
strItems(p).Top = rec.Top
p = p + 1
ReDim Preserve strItems(0 To p) As WindowInfo
End If
. . .
End Sub
Re: Help with FindWindow & SendMessage for username & pw text boxes
Quote:
Originally Posted by
Bonnie West
That's probably because you've declared the strItems array as:
Code:
Dim strItems(0 To 1, 0 To 1) As Long
There are two dimensions in the array, but each dimension is limited to only 2 elements (from 0 to 1). Perhaps, you may find it easier if you use a UDT array instead, sort of like this:
Code:
Private Type WindowInfo
hWnd As Long
Top As Long
End Type
Private Sub Command1_Click()
Dim strItems() As WindowInfo
. . .
ReDim strItems(0 To 0) As WindowInfo
. . .
If . . .
strItems(p).hWnd = lhndChild
strItems(p).Top = rec.Top
p = p + 1
ReDim Preserve strItems(0 To p) As WindowInfo
End If
. . .
End Sub
Bonnie, I haven't used a UDT array before, infact I'm pretty new when it comes to arrays.
What part of my code do I need to strip out, and replace with the UDT array, and what parts of my code do I need to leave in?
What's weird is that the original code works fine if I create an .exe that has two textboxes...but when I try testing it on the real production app it doesn't work for some reason.
Re: Help with FindWindow & SendMessage for username & pw text boxes
You probably need to familiarize yourself first with the concepts of Arrays and UDTs. However, if you're in a hurry, then you just need to replace all instances of strItems(p, 0) with strItems(p).hWnd and strItems(p, 1) with strItems(p).Top. BTW, the strItems array name doesn't quite describe what that array really is. Perhaps, udtTxtBoxes might be more meaningful?
1 Attachment(s)
Re: Help with FindWindow & SendMessage for username & pw text boxes
Quote:
Originally Posted by
Bonnie West
You probably need to familiarize yourself first with the concepts of
Arrays and
UDTs. However, if you're in a hurry, then you just need to replace all instances of
strItems(p, 0) with
strItems(p).hWnd and
strItems(p, 1) with
strItems(p).Top. BTW, the strItems array name doesn't quite describe what that array really is. Perhaps, udtTxtBoxes might be more meaningful?
I just realized that there are 3 textboxes on the login dialogue box. The very first textbox is disabled, and I didn't think that it would go into our equation. But I just realized that VB doesn't care if that textbox is disabled or not, it will still find it.
So that must be why it was erroring out in the array, because we need one that will support 3 values instead of 2 right? Is there an easy way to tell it to disregard the disabled text box? Or is there any easy way to modify the code to only pass the login info to the bottom two text boxes?
Attachment 95411
Re: Help with FindWindow & SendMessage for username & pw text boxes
You may test if a textbox is disabled through the IsWindowEnabled API function.
Code:
Private Declare Function IsWindowEnabled Lib "user32.dll" (ByVal hWnd As Long) As Long
You may ignore the disabled textbox if that function returns zero.
Re: Help with FindWindow & SendMessage for username & pw text boxes
Why are you trying to login to a Supervisor workstation?
Are you a supervisor?
Re: Help with FindWindow & SendMessage for username & pw text boxes
Quote:
Originally Posted by
Hack
Why are you trying to login to a Supervisor workstation?
Are you a supervisor?
No I'm not a supervisor, I'm just the guy that supports them. ha.
The screen shot is actually of an application that our supervisors use in our call center. The app shows the state of all of the call center reps that are logged into their phone. So it will show them Hold Time, Schedule Adherence, Length of Calls, etc etc. Basically is used by the supervisors to see which reps are on long calls, or have had their customers on hold too long, that way they can go help the rep and reduce the length of their call.
I've been tasked with finding a way to get this to display on all of the TV's in our call center (which is complete). I just have to come up with a way to automate the logon process for this app, so that we don't have to do it manually every morning. The PC is in our locked data center, and I have setup a generic login for the IEX software.
I just need to make an app to pass the generic login info to IEX now.
Any thoughts? I tried switching my code up like bonnie suggested, but couldn't get the grasp of it.
Re: Help with FindWindow & SendMessage for username & pw text boxes
In the User Logon dialog box, what happens when you press Alt-N and Alt-P? I suppose the respective textboxes gets the focus, don't they? If so, then you may be able to employ the SendKeys statement to programmatically type the login info.
Re: Help with FindWindow & SendMessage for username & pw text boxes
Quote:
Originally Posted by
Bonnie West
In the User Logon dialog box, what happens when you press Alt-N and Alt-P? I suppose the respective textboxes gets the focus, don't they? If so, then you may be able to employ the
SendKeys statement to programmatically type the login info.
Yeah SendKeys would work, I was just hoping to do it using send message instead. That way it will pass the correct info even with out focus.
I could probably do something like AppActivate("User Logon") and then use SendKeys to have it either tab to the username field or use Alt-N/P.
Re: Help with FindWindow & SendMessage for username & pw text boxes
You may also set the focus to the dialog box with either the SetForegroundWindow or SetFocus APIs.
Re: Help with FindWindow & SendMessage for username & pw text boxes
Bonnie, when using UDT arrays...do I have to specify how many elements I need, or is it dynamic?
The main problem I have for my original code is that the array appears to be setup to only store the handles of 2 text boxes.
And now I need to be able to store the handles of 3 text boxes. When it finds the 3rd text box it's throwing an error b/c the array isn't setup for 3.
Re: Help with FindWindow & SendMessage for username & pw text boxes
UDT arrays are just like any other arrays; they can be fixed size or dynamic.
Dimension your original array as:
Code:
Dim strItems(0 To 2, 0 To 1) As Long