Results 1 to 15 of 15

Thread: Help with FindWindow & SendMessage for username & pw text boxes

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Aug 2007
    Posts
    70

    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
    Last edited by jwetzler; Jan 18th, 2013 at 11:16 PM.

  2. #2
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    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.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Aug 2007
    Posts
    70

    Re: Help with FindWindow & SendMessage for username & pw text boxes

    Quote Originally Posted by Bonnie West View Post
    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.

  4. #4
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    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
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Aug 2007
    Posts
    70

    Re: Help with FindWindow & SendMessage for username & pw text boxes

    Quote Originally Posted by Bonnie West View Post
    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.

  6. #6
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    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?
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Aug 2007
    Posts
    70

    Re: Help with FindWindow & SendMessage for username & pw text boxes

    Quote Originally Posted by Bonnie West View Post
    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?

    Name:  Login.jpg
Views: 1209
Size:  25.8 KB

  8. #8
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    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.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  9. #9
    I'm about to be a PowerPoster! Hack's Avatar
    Join Date
    Aug 2001
    Location
    Searching for mendhak
    Posts
    58,333

    Re: Help with FindWindow & SendMessage for username & pw text boxes

    Why are you trying to login to a Supervisor workstation?

    Are you a supervisor?

  10. #10

    Thread Starter
    Lively Member
    Join Date
    Aug 2007
    Posts
    70

    Re: Help with FindWindow & SendMessage for username & pw text boxes

    Quote Originally Posted by Hack View Post
    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.

  11. #11
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    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.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  12. #12

    Thread Starter
    Lively Member
    Join Date
    Aug 2007
    Posts
    70

    Re: Help with FindWindow & SendMessage for username & pw text boxes

    Quote Originally Posted by Bonnie West View Post
    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.

  13. #13
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    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.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  14. #14

    Thread Starter
    Lively Member
    Join Date
    Aug 2007
    Posts
    70

    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.

  15. #15
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    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
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width