ionut Posted May 5, 2010 Share Posted May 5, 2010 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 More sharing options...
funkey Posted May 5, 2010 Share Posted May 5, 2010 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 tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
ionut Posted May 5, 2010 Author Share Posted May 5, 2010 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 More sharing options...
funkey Posted May 5, 2010 Share Posted May 5, 2010 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 tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
ionut Posted May 5, 2010 Author Share Posted May 5, 2010 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 Link to comment Share on other sites More sharing options...
wolf9228 Posted May 5, 2010 Share Posted May 5, 2010 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 expandcollapse popup#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 More sharing options...
funkey Posted May 5, 2010 Share Posted May 5, 2010 expandcollapse popup#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 tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
ionut Posted May 5, 2010 Author Share Posted May 5, 2010 expandcollapse popup#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 More sharing options...
ionut Posted May 5, 2010 Author Share Posted May 5, 2010 expandcollapse popup#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 , 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now