Jump to content

Recommended Posts

Posted (edited)

Anyway to easily enumerate all controls (i.e. control classes, instances, etc.) in a 3rd party app?

A business app I'm working on has all of the controls with their own classes and correct instances, but I don't know of an easy way to target each control in a loop without manually inputting the control info.

Edited by mechaflash213
  Reveal hidden contents

 

Posted

Something like this loop for each class? Else, would you re-explain?

#include <Array.au3>
$iArrayCounter = 1
Dim $aControls[$iArrayCounter][3]
Dim $aControlTypes[3]=["Edit","Button","etc"]
For $i = 0 To Ubound ($aControlTypes)-1
 $iInstance = 1
 While 1
  $hControl = ControlGetHandle("DevTrack", "", "[CLASSNN:" & $aControlTypes[$i] & $iInstance & "]")
  If IsHWnd ( $hControl ) Then
   ReDim $aControls[$iArrayCounter][3]
   $aControls[$iArrayCounter-1][0]=$aControlTypes[$i]
   $aControls[$iArrayCounter-1][1]=$iInstance
   $aControls[$iArrayCounter-1][2]=$hControl
   $iArrayCounter += 1
  Else
   ExitLoop
  EndIf
  $iInstance += 1
 WEnd
Next
_ArrayDisplay ($aControls)
IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.
Posted

  On 8/17/2012 at 5:55 PM, 'jdelaney said:

Something like this loop for each class? Else, would you re-explain?

#include <Array.au3>
$iArrayCounter = 1
Dim $aControls[$iArrayCounter][3]
Dim $aControlTypes[3]=["Edit","Button","etc"]
For $i = 0 To Ubound ($aControlTypes)-1
$iInstance = 1
While 1
$hControl = ControlGetHandle("DevTrack", "", "[CLASSNN:" & $aControlTypes[$i] & $iInstance & "]")
If IsHWnd ( $hControl ) Then
ReDim $aControls[$iArrayCounter][3]
$aControls[$iArrayCounter-1][0]=$aControlTypes[$i]
$aControls[$iArrayCounter-1][1]=$iInstance
$aControls[$iArrayCounter-1][2]=$hControl
$iArrayCounter += 1
Else
ExitLoop
EndIf
$iInstance += 1
WEnd
Next
_ArrayDisplay ($aControls)

Now if that could be modified to automatically find out what the classes are without specifying them, that would be what I was looking for.
  Reveal hidden contents

 

Posted (edited)

Find me a way to get HWND -> Class, and I can do just that, using something like:

ControlGetHandle("Yourwindow", "", "[REGEXPCLASS:" & $aControlTypes[$i] & "; INSTANCE:" & $iInstance & "]")

aaaaand, possibly found it:

Func GetClassName($hWnd)

$Rt = DllCall("User32.dll","int","GetClassNameW","HWND",$hWnd,"wstr","","int",5000)

if @error Or $Rt[0] = 0 Then Return SetError(1,0,0)

Return SetError(0,0,$Rt[2])

EndFunc

Edited by jdelaney
IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.
Posted (edited)

Your welcome :)

$iArrayCounter = 1
Dim $aControls[$iArrayCounter][3]
Dim $aControlTypes[3]=["Edit","Button","etc"]
Dim $aControlTypes[1]=["[Ww]+"]
For $i = 0 To Ubound ($aControlTypes)-1
$iInstance = 1
While 1 ; loop through all instances
$sRegExp = $aControlTypes[0]
$hControl = ControlGetHandle("DevTrack", "", "[REGEXPCLASS:" & $sRegExp & "; INSTANCE:" & $iInstance & "]")
If Not IsHWnd ( $hControl ) Then ExitLoop
While 1; loop through all class types within each instance
$hControl = ControlGetHandle("DevTrack", "", "[REGEXPCLASS:" & $sRegExp & "; INSTANCE:" & $iInstance & "]")
If IsHWnd ( $hControl ) Then
    $sControlType = GetClassName($hControl)
    $sRegExp = $sRegExp & "[^" & $sControlType & "]"
    ReDim $aControls[$iArrayCounter][3]
    $aControls[$iArrayCounter-1][0]=$sControlType
    $aControls[$iArrayCounter-1][1]=$iInstance
    $aControls[$iArrayCounter-1][2]=$hControl
    $iArrayCounter += 1
Else
    ExitLoop
EndIf
WEnd
$iInstance += 1
WEnd
Next
_ArrayDisplay ($aControls)
Func GetClassName($hWnd)
$Rt = DllCall("User32.dll","int","GetClassNameW","HWND",$hWnd,"wstr","","int",5000)
if @error Or $Rt[0] = 0 Then Return SetError(1,0,0)
Return SetError(0,0,$Rt[2])
EndFunc

edit: almost, some itteration issues

Edited by jdelaney
IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.
Posted

Simplified...got all the control types, then used my original loop:

#include <Array.au3>
$iArrayCounter = 1
Dim $aControls[$iArrayCounter][3]
Dim $aControlTypes[1]
$sRegExp = ""
; get all classes
While 1; loop through all class types within each instance
 $hControl = ControlGetHandle("DevTrack", "", "[REGEXPCLASS:" & $sRegExp & "]")
 If IsHWnd($hControl) Then
  $sControlType = GetClassName($hControl)
  If $iArrayCounter > 1 Then
   $sRegExp = StringLeft($sRegExp, StringLen($sRegExp) - 1)
   $sRegExp = $sRegExp & "|^" & $sControlType & "]"
  Else
   $sRegExp = "[^" & $sControlType & "]"
  EndIf
  ConsoleWrite ( $sRegExp & @CRLF )
  ReDim $aControlTypes[$iArrayCounter]
  $aControlTypes[$iArrayCounter - 1] = $sControlType
  $iArrayCounter += 1
  ConsoleWrite ( $sControlType & @CRLF )
 Else
  ExitLoop
 EndIf
WEnd
$iArrayCounter = 1
Dim $aControls[$iArrayCounter][3]
For $i = 0 To Ubound ($aControlTypes)-1
 $iInstance = 1
 While 1
  $hControl = ControlGetHandle("DevTrack", "", "[CLASSNN:" & $aControlTypes[$i] & $iInstance & "]")
  If IsHWnd ( $hControl ) Then
   ReDim $aControls[$iArrayCounter][3]
   $aControls[$iArrayCounter-1][0]=$aControlTypes[$i]
   $aControls[$iArrayCounter-1][1]=$iInstance
   $aControls[$iArrayCounter-1][2]=$hControl
   $iArrayCounter += 1
  Else
   ExitLoop
  EndIf
  $iInstance += 1
 WEnd
Next
_ArrayDisplay ( $aControls )
Func GetClassName($hWnd)
 $Rt = DllCall("User32.dll", "int", "GetClassNameW", "HWND", $hWnd, "wstr", "", "int", 5000)
 If @error Or $Rt[0] = 0 Then Return SetError(1, 0, 0)
 Return SetError(0, 0, $Rt[2])
EndFunc   ;==>GetClassName
IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.
Posted

sweeeeeeeet. Works uber great. Now go make this a UDF and share your brilliance :thumbsup:

Thanx JD

  Reveal hidden contents

 

Posted

Adjusted to be called as a function with example usage.

#include <Array.au3>
Local $hWnd
$hWnd = WinGetHandle("All My Papers Demonstration Software")
$aControlClasses = _WinControls_Enumerate($hWnd)
_ArrayDisplay($aControlClasses)

Func _WinControls_Enumerate(Const $hWinHandle) ; Pass a window handle to this function. Outputs a 2D-3Index array of control Classes, Instances, and Handles of a window
    Local $iArrayCounter = 1, $sRegExp = "", $sWinHandle
    Dim $aControls[$iArrayCounter][3]
    Dim $aControlTypes[1]

    ; get all classes
    While 1; loop through all class types within each instance
        $hControl = ControlGetHandle($hWinHandle, "", "[REGEXPCLASS:" & $sRegExp & "]")
        If IsHWnd($hControl) Then
            $sControlType = GetClassName($hControl)
            If $iArrayCounter > 1 Then
                $sRegExp = StringLeft($sRegExp, StringLen($sRegExp) - 1)
                $sRegExp = $sRegExp & "|^" & $sControlType & "]"
            Else
                $sRegExp = "[^" & $sControlType & "]"
            EndIf
            ConsoleWrite ( $sRegExp & @CRLF )
            ReDim $aControlTypes[$iArrayCounter]
            $aControlTypes[$iArrayCounter - 1] = $sControlType
            $iArrayCounter += 1
            ConsoleWrite ( $sControlType & @CRLF )
            Else
            ExitLoop
        EndIf
    WEnd
    $iArrayCounter = 1
    Dim $aControls[$iArrayCounter][3]
    For $i = 0 To Ubound ($aControlTypes)-1
        $iInstance = 1
        While 1
            $hControl = ControlGetHandle($hWinHandle, "", "[CLASSNN:" & $aControlTypes[$i] & $iInstance & "]")
            If IsHWnd ( $hControl ) Then
                ReDim $aControls[$iArrayCounter][3]
                $aControls[$iArrayCounter-1][0]=$aControlTypes[$i]
                $aControls[$iArrayCounter-1][1]=$iInstance
                $aControls[$iArrayCounter-1][2]=$hControl
                $iArrayCounter += 1
            Else
                ExitLoop
            EndIf
            $iInstance += 1
        WEnd
    Next
    Return $aControls
EndFunc

    Func GetClassName($hWnd)
        $Rt = DllCall("User32.dll", "int", "GetClassNameW", "HWND", $hWnd, "wstr", "", "int", 5000)
        If @error Or $Rt[0] = 0 Then Return SetError(1, 0, 0)
        Return SetError(0, 0, $Rt[2])
    EndFunc   ;==>GetClassName
  Reveal hidden contents

 

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
×
×
  • Create New...