Jump to content

How can I get the text of all the Controls sharing the same name?


Recommended Posts

Hello,

I am using a Windows application which has several controls sharing the same name, which is [NAME:textEditNetwork]. When using the ControlGetText function I am returned with the name of the first control, period.

$var = ControlGetText("IxLoad", "", "[NAME:textEditNetwork]") results in $var=Network1, although there are also Network2, Network3, etc. The name of the controls is the only ID which remains constant after GUI restart. I have tried to use a for ... next loop to browse thru all objects w/o any real luck.

I would like to know how to sweep thru the entire GUI and read the TEXT of all the controls sharing a name. I need to save those name into an array and find out their positions.

Thanks a lot,

Ionut

Link to comment
Share on other sites

Is the position of the controls always different? Or are there so much controls to read?

When not you could use this way:

ControlGetText("IxLoad", "", "[X:20;Y:20;W:80;H:30]")

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Link to comment
Share on other sites

Is the position of the controls always different? Or are there so much controls to read?

When not you could use this way:

ControlGetText("IxLoad", "", "[X:20;Y:20;W:80;H:30]")

Hi Funkey,

The position of the controls can be modified by other variables. I can use only the Text of the controls to discriminate among them since all are sharing the same Name. The Text of the Controls is not known apriori opening the application, that's why I need to read it automatically. After scanning the Names, I would like to use them as ControlID for ControlGetPos function and thus have the new coordinates regardless of the Text of the controls.

Thanks,

Ionut

Link to comment
Share on other sites

Maybe this is usefull for you.

Global $Array = _WinGetCtrlInfo(WinGetTitle(''))
Global $sOne = '[0][0] = ' & $Array[0][0] & @CR, $sTwo
For $iCC = 1 To $Array[0][0]
    $sOne &= '[' & $iCC & '][0] = ' & $Array[$iCC][0] & @CR
    $sTwo &= '[' & $iCC & '][1] = ' & $Array[$iCC][1] & @CR
Next
MsgBox(64, 'WinInfo', StringTrimRight($sOne, 1) & @CR & StringTrimRight($sTwo, 1))

Func _WinGetCtrlInfo($hWin)
    If IsString($hWin) Then $hWin = WinGetHandle($hWin)
    Local $sClassList = WinGetClassList($hWin), $iAdd = 1, $aDLL, $sHold
    Local $aSplitClass = StringSplit(StringTrimRight($sClassList, 1), @LF), $aReturn[1][2]
    For $iCount = $aSplitClass[0] To 1 Step - 1
        Local $nCount = 0
        While 1
            $nCount += 1
            If ControlGetHandle($hWin, '', $aSplitClass[$iCount] & $nCount) = '' Then ExitLoop
            If Not StringInStr(Chr(1) & $sHold, Chr(1) & $aSplitClass[$iCount] & $nCount & Chr(1)) Then
                $sHold &= $aSplitClass[$iCount] & $nCount & Chr(1)
                $iAdd += 1
                ReDim $aReturn[$iAdd][2]
                $aReturn[$iAdd - 1][0] = $aSplitClass[$iCount] & $nCount
                $aDLL = DllCall('User32.dll', 'int', 'GetDlgCtrlID', 'hwnd', _
                    ControlGetHandle($hWin, '', $aSplitClass[$iCount] & $nCount))
                If @error = 0 Then
                    $aReturn[$iAdd - 1][1] = $aDLL[0]
                Else
                    $aReturn[$iAdd - 1][1] = ''
                EndIf
            EndIf
        WEnd
    Next
    $aReturn[0][0] = $iAdd - 1
    Return $aReturn
EndFunc

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Link to comment
Share on other sites

Maybe this is usefull for you.

Global $Array = _WinGetCtrlInfo(WinGetTitle(''))
Global $sOne = '[0][0] = ' & $Array[0][0] & @CR, $sTwo
For $iCC = 1 To $Array[0][0]
    $sOne &= '[' & $iCC & '][0] = ' & $Array[$iCC][0] & @CR
    $sTwo &= '[' & $iCC & '][1] = ' & $Array[$iCC][1] & @CR
Next
MsgBox(64, 'WinInfo', StringTrimRight($sOne, 1) & @CR & StringTrimRight($sTwo, 1))

Func _WinGetCtrlInfo($hWin)
    If IsString($hWin) Then $hWin = WinGetHandle($hWin)
    Local $sClassList = WinGetClassList($hWin), $iAdd = 1, $aDLL, $sHold
    Local $aSplitClass = StringSplit(StringTrimRight($sClassList, 1), @LF), $aReturn[1][2]
    For $iCount = $aSplitClass[0] To 1 Step - 1
        Local $nCount = 0
        While 1
            $nCount += 1
            If ControlGetHandle($hWin, '', $aSplitClass[$iCount] & $nCount) = '' Then ExitLoop
            If Not StringInStr(Chr(1) & $sHold, Chr(1) & $aSplitClass[$iCount] & $nCount & Chr(1)) Then
                $sHold &= $aSplitClass[$iCount] & $nCount & Chr(1)
                $iAdd += 1
                ReDim $aReturn[$iAdd][2]
                $aReturn[$iAdd - 1][0] = $aSplitClass[$iCount] & $nCount
                $aDLL = DllCall('User32.dll', 'int', 'GetDlgCtrlID', 'hwnd', _
                    ControlGetHandle($hWin, '', $aSplitClass[$iCount] & $nCount))
                If @error = 0 Then
                    $aReturn[$iAdd - 1][1] = $aDLL[0]
                Else
                    $aReturn[$iAdd - 1][1] = ''
                EndIf
            EndIf
        WEnd
    Next
    $aReturn[0][0] = $iAdd - 1
    Return $aReturn
EndFunc

Hi,

I've tried this script on AutoIT and Notepad and it works nicely. But it does not scale for my application, where there are a lot of classes used(334). Here's the first lines of the output to console:

WinInfo[0][0] = 334

[1][0] = IXVDummyWindow1

[2][0] = WindowsForms10.window.8.app.0.bf77711

[3][0] = WindowsForms10.window.8.app.0.bf77712

[4][0] = WindowsForms10.window.8.app.0.bf77713

[5][0] = WindowsForms10.window.8.app.0.bf77714

[6][0] = WindowsForms10.window.8.app.0.bf77715

[7][0] = WindowsForms10.window.8.app.0.bf77716

[8][0] = WindowsForms10.window.8.app.0.bf77717

[9][0] = WindowsForms10.window.8.app.0.bf77718

which I am not sure how to use.

I've attached a snapshot of my application. What I'm trying to find out is the position of Controls Network1, Network3,etc.

Thanks for your help,

Ionut

post-56932-12730738827675_thumb.jpg

Link to comment
Share on other sites

Hello,

I am using a Windows application which has several controls sharing the same name, which is [NAME:textEditNetwork]. When using the ControlGetText function I am returned with the name of the first control, period.

$var = ControlGetText("IxLoad", "", "[NAME:textEditNetwork]") results in $var=Network1, although there are also Network2, Network3, etc. The name of the controls is the only ID which remains constant after GUI restart. I have tried to use a for ... next loop to browse thru all objects w/o any real luck.

I would like to know how to sweep thru the entire GUI and read the TEXT of all the controls sharing a name. I need to save those name into an array and find out their positions.

Thanks a lot,

Ionut

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <Array.au3>
Global $ChildArray  , $PTR_Chi

$PID = Run("calc.exe", "", @SW_MAXIMIZE)
WinWaitActive("Calculator")
$WinHandle = WinGetHandle("Calculator", "")
$RTArray = ChildWindows($WinHandle)
_ArrayDisplay($RTArray, "")
ProcessClose ($PID)


Func ChildWindows($WinHandle)
$WindowArray =  GetChildWindows($WinHandle)
Dim $RTArray[1][6]
For $i = 0 To  UBound($WindowArray) - 1
$RTArray[UBound($RTArray) - 1][0] = $WindowArray[$i]
$RTArray[UBound($RTArray) - 1][1] = ControlGetText ($WinHandle, "",$WindowArray[$i])
$pos = ControlGetPos($WinHandle, "",$WindowArray[$i])
$RTArray[UBound($RTArray) - 1][2] = $pos[0]
$RTArray[UBound($RTArray) - 1][3] = $pos[1]
$RTArray[UBound($RTArray) - 1][4] = $pos[2]
$RTArray[UBound($RTArray) - 1][5] = $pos[3]
ReDim $RTArray[UBound($RTArray) + 1][6]
Next
ReDim $RTArray[UBound($RTArray) - 1][6]
Return $RTArray
EndFunc


Func  GetChildWindows($hWndParent)
If Not ($PTR_Chi) Then $PTR_Chi = RegisterEnumChildProc("CALLBACK_EnumChildProc")
EnumChildWindows($hWndParent , $PTR_Chi)
ReDim $ChildArray[UBound($ChildArray) - 1]
Return $ChildArray
EndFunc

Func  EnumChildWindows($hWndParent , $lpEnumFunc)
Local $lParam = 0
Global $ChildArray = 0
Dim $ChildArray[1]
$BOOL = DllCall("user32.dll","int","EnumChildWindows","hwnd",$hWndParent,"ptr",$lpEnumFunc,"int",$lParam)
if Not @error Then Return SetError(@error,"",$BOOL[0])
Return SetError(@error,"",False)
EndFunc

Func RegisterEnumChildProc($lpEnumFunc)
$handle = DLLCallbackRegister ($lpEnumFunc, "int", "hwnd;int")
Return DllCallbackGetPtr($handle)
EndFunc


Func CALLBACK_EnumChildProc($hwnd,$lParam)
For $i = 0 To UBound($ChildArray) - 1
if $ChildArray[$i] == $hwnd Then Return False
Next
$ChildArray[UBound($ChildArray) - 1] = $hwnd
ReDim $ChildArray[UBound($ChildArray) + 1]
Return True
EndFunc

صرح السماء كان هنا

 

Link to comment
Share on other sites

#Include <Array.au3>

Global $sTitle = "IxLoad"
Global $sMatch = "Network"
Global $aCtrl = _WinGetCtrlInfo(WinGetTitle($sTitle))

_ArrayDisplay($aCtrl)

Local $aNetworkCtrl[2][5] = [["Text", "X", "Y", "W", "H"]]
Local $sTemp, $aTemp, $j = 2

For $i = 1 To $aCtrl[0][0]
 $sTemp = ControlGetText($sTitle, "", $aCtrl[$i][0])
 If StringInStr($sTemp , $sMatch) Then
  $aTemp = ControlGetPos($sTitle, "", $aCtrl[$i][0])
  $aNetworkCtrl[$j - 1][0] = $sTemp
  $aNetworkCtrl[$j - 1][1] = $aTemp[0]
  $aNetworkCtrl[$j - 1][2] = $aTemp[1]
  $aNetworkCtrl[$j - 1][3] = $aTemp[2]
  $aNetworkCtrl[$j - 1][4] = $aTemp[3]
  $j +=1
  ReDim $aNetworkCtrl[$j][5]
 EndIf
Next

ReDim $aNetworkCtrl[$j - 1][5]
_ArrayDisplay($aNetworkCtrl)

Exit


Func _WinGetCtrlInfo($hWin)
    If IsString($hWin) Then $hWin = WinGetHandle($hWin)
    Local $sClassList = WinGetClassList($hWin), $iAdd = 1, $aDLL, $sHold
    Local $aSplitClass = StringSplit(StringTrimRight($sClassList, 1), @LF), $aReturn[1][2]
    For $iCount = $aSplitClass[0] To 1 Step - 1
        Local $nCount = 0
        While 1
            $nCount += 1
            If ControlGetHandle($hWin, '', $aSplitClass[$iCount] & $nCount) = '' Then ExitLoop
            If Not StringInStr(Chr(1) & $sHold, Chr(1) & $aSplitClass[$iCount] & $nCount & Chr(1)) Then
                $sHold &= $aSplitClass[$iCount] & $nCount & Chr(1)
                $iAdd += 1
                ReDim $aReturn[$iAdd][2]
                $aReturn[$iAdd - 1][0] = $aSplitClass[$iCount] & $nCount
                $aDLL = DllCall('User32.dll', 'int', 'GetDlgCtrlID', 'hwnd', _
                    ControlGetHandle($hWin, '', $aSplitClass[$iCount] & $nCount))
                If @error = 0 Then
                    $aReturn[$iAdd - 1][1] = $aDLL[0]
                Else
                    $aReturn[$iAdd - 1][1] = ''
                EndIf
            EndIf
        WEnd
    Next
    $aReturn[0][0] = $iAdd - 1
    Return $aReturn
EndFunc

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Link to comment
Share on other sites

#Include <Array.au3>

Global $sTitle = "IxLoad"
Global $sMatch = "Network"
Global $aCtrl = _WinGetCtrlInfo(WinGetTitle($sTitle))

_ArrayDisplay($aCtrl)

Local $aNetworkCtrl[2][5] = [["Text", "X", "Y", "W", "H"]]
Local $sTemp, $aTemp, $j = 2

For $i = 1 To $aCtrl[0][0]
 $sTemp = ControlGetText($sTitle, "", $aCtrl[$i][0])
 If StringInStr($sTemp , $sMatch) Then
  $aTemp = ControlGetPos($sTitle, "", $aCtrl[$i][0])
  $aNetworkCtrl[$j - 1][0] = $sTemp
  $aNetworkCtrl[$j - 1][1] = $aTemp[0]
  $aNetworkCtrl[$j - 1][2] = $aTemp[1]
  $aNetworkCtrl[$j - 1][3] = $aTemp[2]
  $aNetworkCtrl[$j - 1][4] = $aTemp[3]
  $j +=1
  ReDim $aNetworkCtrl[$j][5]
 EndIf
Next

ReDim $aNetworkCtrl[$j - 1][5]
_ArrayDisplay($aNetworkCtrl)

Exit


Func _WinGetCtrlInfo($hWin)
    If IsString($hWin) Then $hWin = WinGetHandle($hWin)
    Local $sClassList = WinGetClassList($hWin), $iAdd = 1, $aDLL, $sHold
    Local $aSplitClass = StringSplit(StringTrimRight($sClassList, 1), @LF), $aReturn[1][2]
    For $iCount = $aSplitClass[0] To 1 Step - 1
        Local $nCount = 0
        While 1
            $nCount += 1
            If ControlGetHandle($hWin, '', $aSplitClass[$iCount] & $nCount) = '' Then ExitLoop
            If Not StringInStr(Chr(1) & $sHold, Chr(1) & $aSplitClass[$iCount] & $nCount & Chr(1)) Then
                $sHold &= $aSplitClass[$iCount] & $nCount & Chr(1)
                $iAdd += 1
                ReDim $aReturn[$iAdd][2]
                $aReturn[$iAdd - 1][0] = $aSplitClass[$iCount] & $nCount
                $aDLL = DllCall('User32.dll', 'int', 'GetDlgCtrlID', 'hwnd', _
                    ControlGetHandle($hWin, '', $aSplitClass[$iCount] & $nCount))
                If @error = 0 Then
                    $aReturn[$iAdd - 1][1] = $aDLL[0]
                Else
                    $aReturn[$iAdd - 1][1] = ''
                EndIf
            EndIf
        WEnd
    Next
    $aReturn[0][0] = $iAdd - 1
    Return $aReturn
EndFunc

Funkey,

This is exactly what I was looking for. Thanks a lot for your help! I really appreciate it!

Regards,

Ionut

Link to comment
Share on other sites

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <Array.au3>
Global $ChildArray  , $PTR_Chi

$PID = Run("calc.exe", "", @SW_MAXIMIZE)
WinWaitActive("Calculator")
$WinHandle = WinGetHandle("Calculator", "")
$RTArray = ChildWindows($WinHandle)
_ArrayDisplay($RTArray, "")
ProcessClose ($PID)


Func ChildWindows($WinHandle)
$WindowArray =  GetChildWindows($WinHandle)
Dim $RTArray[1][6]
For $i = 0 To  UBound($WindowArray) - 1
$RTArray[UBound($RTArray) - 1][0] = $WindowArray[$i]
$RTArray[UBound($RTArray) - 1][1] = ControlGetText ($WinHandle, "",$WindowArray[$i])
$pos = ControlGetPos($WinHandle, "",$WindowArray[$i])
$RTArray[UBound($RTArray) - 1][2] = $pos[0]
$RTArray[UBound($RTArray) - 1][3] = $pos[1]
$RTArray[UBound($RTArray) - 1][4] = $pos[2]
$RTArray[UBound($RTArray) - 1][5] = $pos[3]
ReDim $RTArray[UBound($RTArray) + 1][6]
Next
ReDim $RTArray[UBound($RTArray) - 1][6]
Return $RTArray
EndFunc


Func  GetChildWindows($hWndParent)
If Not ($PTR_Chi) Then $PTR_Chi = RegisterEnumChildProc("CALLBACK_EnumChildProc")
EnumChildWindows($hWndParent , $PTR_Chi)
ReDim $ChildArray[UBound($ChildArray) - 1]
Return $ChildArray
EndFunc

Func  EnumChildWindows($hWndParent , $lpEnumFunc)
Local $lParam = 0
Global $ChildArray = 0
Dim $ChildArray[1]
$BOOL = DllCall("user32.dll","int","EnumChildWindows","hwnd",$hWndParent,"ptr",$lpEnumFunc,"int",$lParam)
if Not @error Then Return SetError(@error,"",$BOOL[0])
Return SetError(@error,"",False)
EndFunc

Func RegisterEnumChildProc($lpEnumFunc)
$handle = DLLCallbackRegister ($lpEnumFunc, "int", "hwnd;int")
Return DllCallbackGetPtr($handle)
EndFunc


Func CALLBACK_EnumChildProc($hwnd,$lParam)
For $i = 0 To UBound($ChildArray) - 1
if $ChildArray[$i] == $hwnd Then Return False
Next
$ChildArray[UBound($ChildArray) - 1] = $hwnd
ReDim $ChildArray[UBound($ChildArray) + 1]
Return True
EndFunc

Hi Wolf/Spammer :idea:,

Your piece of script works really fast!!! I will keep it as a reference point and fine tune it to fit my requirements.

Thanks a lot,

Ionut

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...