Sign in to follow this  
Followers 0
RogFleming

_WinAPI_EnumWindows() how to get more details of control in a gui

4 posts in this topic

I would like to get the ClassNN of a ControlID, so I can create a combobox to pick the control in a meaningful way

ComboBox list

Edit1

Edit2

Edit2

Password

$AppExec = "mstsc.exe.EXE"
If ProcessExists($AppExec) Then
$hWnd = _WinGetByPID(ProcessExists($AppExec))
ConsoleWrite("Window className : "&_WinAPI_GetClassName($hWnd)&@CRLF)
ConsoleWrite("Window Text : "&_WinAPI_GetWindowText($hWnd)&@CRLF)
WinActivate(_WinAPI_GetWindowText($hWnd))
ConsoleWrite("Window Handle that has focus: "&_WinAPI_GetFocus()&@CRLF)
ConsoleWrite("Window Handle CHLD Handle: "&_WinAPI_GetDlgCtrlID($hWnd)&@CRLF)
$found_win = _WinAPI_EnumWindows(True,$hWnd)
_ArrayDisplay($found_win) ; list all the controlID values, but on edit and not it's instance

$s=0
For $t = 1 to UBound($found_win) -1
If $found_win[$t][1] = "Edit" Then
$s=$s+1
ConsoleWrite("Control Id: "&$found_win[$t][0]&@CRLF)
ConsoleWrite("sending to: "&"[CLASSNN:"&$found_win[$t][1]&$s&"]"&@CRLF)
Local $aPos = ControlGetPos(_WinAPI_GetWindowText($hWnd), "","[CLASSNN:"&$found_win[$t][1]&$s&"]")
ConsoleWrite("Window Stats: Position: " & $aPos[0] & "," & $aPos[1] & @CRLF & "Size: " & $aPos[2] & "," & $aPos[3]&@CRLF)
;ControlSend(_WinAPI_GetWindowText($hWnd), "","[CLASSNN:"&$found_win[$t][1]&$s&"]", "test")
ConsoleWrite("Ctrl ID: "&_WinAPI_GetDlgCtrlID($found_win[$t][0])&@CRLF)
EndIf
;ControlSend(_WinAPI_GetWindowText($hWnd), "","[Name:password]", "test123")
Next
EndIf
Exit

How does the AUTIIT Window Info create the [ClassNN:Edit1] Value?

example:

>>>> Control <<<<

Class: Edit

Instance: 2 how does it determine instance?

ClassnameNN: Edit2

Name:

Advanced (Class): [CLASS:Edit; INSTANCE:2]

ID: 1001

Text:

Position: 163, 156

Size: 217, 15

ControlClick Coords: 45, 9

Style: 0x50000380

ExStyle: 0x00000000

Handle: 0x0001061C

Func _AppAutoLogin() using SQL Studio as a appilcation
If WinExists("Connect to Server")= "1" Then
WinActivate("Connect to Server")
LOGDATA($LEVEL, "ETSSO APP SCRIPT", "Logon Dialog Window was found.")
ControlSend("Connect to Server", "", "[CLASSNN:Edit1]", "sqlserver\sqlexpress")
ControlSend("Connect to Server", "", "[CLASSNN:Edit2]", "sa")
ControlSend("Connect to Server", "", "[Name:password]", "Ranger*9")
Send("{ENTER}")
EndIf
EndFunc
Exit

Share this post


Link to post
Share on other sites



I found the solution in another post

$AppExec = "ssms.exe"
$hWnd = _WinGetByPID(ProcessExists($AppExec))
$found_win = _WinAPI_EnumWindows(True,$hWnd)
_ArrayDisplay($found_win)
WinActivate(_WinAPI_GetWindowText($hWnd))
$sClassNameNN = ControlGetFocus(_WinAPI_GetWindowText($hWnd), "")
$hCtrlFocus = ControlGetHandle("", "", $sClassNameNN)
$ctrlFocus = ControlGetID($hCtrlFocus)
MsgBox(64, "Results", "The control with current focus was:" & @CRLF & _
  @TAB & "ClassNameNN = " & $sClassNameNN & @CRLF & _
  @TAB & "HWND = " & $hCtrlFocus & @CRLF & _
  @TAB & "ID = " & $ctrlFocus)
Func ControlGetID($hWnd)
$avRET = DllCall("User32.dll", "int", "GetDlgCtrlID", "hwnd", $hWnd)
If @error or $avRET[0] = 0 then Return SetError(1, 0, 0)
Return $avRET[0]
EndFunc

Share this post


Link to post
Share on other sites

how do I get the same output from ControlGetFocus ( "title" [, "text"] )

with the array handles generated by _WinAPI_EnumWindows(True,$hWnd)

Share this post


Link to post
Share on other sites

I found a few options, later on in my research:

Func AddClass(ByRef $Texts, $Text, $Class)

For $I = 1 To $Texts[0][0]
If $Text == $Texts[$I][0] Then
$Texts[$I][1] &= @LF & $Class
Return
EndIf
Next

; This point is reached if the text doesn't already exist in the list.
$Texts[0][0] += 1
$Texts[$Texts[0][0]][0] = $Text
$Texts[$Texts[0][0]][1] = $Class

EndFunc   ;==>AddClass

Func WinGetClassesByText($Title, $Text = '')
Local $Classes = WinGetControlIDs($Title, $Text)
Local $Texts[$Classes[0] + 1][2]
$Texts[0][0] = 0
For $I = 1 To $Classes[0]
  AddClass($Texts, ControlGetText($Title, $Text, $Classes[$I]), $Classes[$I])
Next
LOGDATA($LEVEL, "ETSSO WIZARD DEBUG",$Texts& " Was found.")
Return $Texts
EndFunc   ;==>WinGetClassesByText

Func WinGetControlIDs($sTitle, $sText = '')
Local $avClasses[1], $iCounter, $sClasses, $sClassStub, $sClassStubList
; Request an unnumbered class list.
$sClassStubList = WinGetClassList($sTitle, $sText)
; Return an empty response if no controls exist.
; Additionally set @Error if the specified window was not found.
If $sClassStubList = '' Then
  If @error Then SetError(1)
  $avClasses[0] = 0
  Return $avClasses
EndIf
; Prepare an array to hold the numbered classes.
ReDim $avClasses[StringLen($sClassStubList) - _
   StringLen(StringReplace($sClassStubList, @LF, '')) + 1]
; The first element will contain a count.
$avClasses[0] = 0
; Count each unique class, enumerate them in the array and remove them from
; the string.
Do
  $sClassStub = _
    StringLeft($sClassStubList, StringInStr($sClassStubList, @LF))
  $iCounter = 0
  While StringInStr($sClassStubList, $sClassStub)
   $avClasses[0] += 1
   $iCounter += 1
   $avClasses[$avClasses[0]] = _
     StringTrimRight($sClassStub, 1) & $iCounter
   $sClassStubList = _
     StringReplace($sClassStubList, $sClassStub, '', 1)
  WEnd
Until $sClassStubList = ''
LOGDATA($LEVEL, "ETSSO WIZARD DEBUG",$sClassStubList& " Was found.")
LOGDATA($LEVEL, "ETSSO WIZARD DEBUG",$avClasses& " Was found.")
Return $avClasses
EndFunc   ;==>WinGetControlIDs

and the one I finally used

Func _GetClasses($sTitle, $sText = '')
Local $iCount_Button = 0, $iCount_Edit = 0, $iCount_Static = 0
Local $aClasses = StringSplit(WinGetClassList($sTitle, $sText), @LF)
Local $aClassID[$aClasses[0] + 1] = [$aClasses[0]]
For $i = 1 To $aClasses[0]
  Switch $aClasses[$i]
   Case $aClasses[$i] = "Button"
    $iCount_Button += 1
    $aClassID[$i] = $aClasses[$i] & $iCount_Button
   Case $aClasses[$i] = "Edit"
    $iCount_Edit += 1
    $aClassID[$i] = $aClasses[$i] & $iCount_Edit
    $aClasses[$i] = "Input"
   Case $aClasses[$i] = "Static"
    $iCount_Static += 1
    $aClassID[$i] = $aClasses[$i] & $iCount_Static
    $aClasses[$i] = "Label"
   Case Else
    If $aClasses[$i] <> "" Then
     $aClassID[$i] = $aClasses[$i] & "?"
    EndIf
  EndSwitch
Next
; Combine the results.
Local $sReturn = ""
For $i = 1 To $aClassID[0]
  LOGDATA($LEVEL, "ETSSO WIZARD DEBUG", $aClassID[$i]& " Was found.")
  GUICtrlSetData($ClientAppLogonCtrl,  $aClassID[$i]) ; add other item
  GUICtrlSetData($ClientAppPasswdCtrl,  $aClassID[$i]) ; add other item
  GUICtrlSetData($ClientAppSubmitCtrl,  $aClassID[$i]) ; add other item
Next
Return
EndFunc   ;==>_GetClasses

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0