Sign in to follow this  
Followers 0
coryphaena

Cannot retrieve value from control

9 posts in this topic

I am very much hoping this tool will allow me to automate a screen-scrape of third party applications to which I need an interface (and which do not provide APIs). I am very impressed so far, but...

Some controls seem to return data OK using ControlGetText but others don't - yet the values of these awkward controls appear in the window text as seen by the Window Info tool so they do not seem to be that opaque

So $GetText=ControlGetText($title,"","WindowsForms10.EDIT.app.0.378734a19") is OK

(returns "300 installments of £271.23")

and $GetText=ControlGetText($title,"","WindowsForms10.window.8.app.0.378734a21") is NOT

(returns empty instead of 13.2%)

I understand that custom controls may be a problem but whatever the "8" means in the control Class Name, I would be surprised if it was anything other than a standard windows control and, as I say the Info tool has no problem seeing it

The screen and Window text output are attached

post-18104-1163959444_thumb.jpg

snap1.txt

I have tried getting the Control ID and using GUICtrlRead (note the ControlID changes on every run, hence using the ClassNameNN above) but failed even to get anything from the control that I can read with ControlGetText - am I missing something, are these functios only valid with controls created through AutoIt?

Code snippet for this attempt is:

$ClassNameNN="WindowsForms10.EDIT.app.0.378734a19"

$hCtrlWnd = ControlGetHandle($title,"",$ClassNameNN)

$aReturn = DllCall('User32.dll', 'int', 'GetDlgCtrlID', 'hwnd', $hCtrlWnd)

If @error = 0 then

$CtrlID=$aReturn[0]

$ReadValue=GUICtrlRead($CtrlID)

EndIf

$GetText=ControlGetText($title,"",$ClassNameNN)

MsgBox(0, "RESULTS", _

"$ClassNameNN : " & $ClassNameNN & @CRLF & _

"$hCtrlWnd : " & $hCtrlWnd & @CRLF & _

"$CtrlID : " & $CtrlID & @CRLF & _

"$ReadValue = " & $ReadValue & @CRLF & _

"$GetText = " & $GetText )

Snapshot of the result box also attached

post-18104-1163959859_thumb.jpg

Cannot find anything that addresses this directly in other posts - any advice appreciated

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

...are these functios only valid with controls created through AutoIt?...

No. ControlGetText works on other apps. (See the example code in the help file, it works with Notepad.)

I do not know what to suggest you try next... but I can give your post a free bump to the top in the hopes that others might have a suggestion.

Nice first post... good details.

Welcome to the forums...

Edited by herewasplato

[size="1"][font="Arial"].[u].[/u][/font][/size]

Share this post


Link to post
Share on other sites

Hello coryphaena.

I do not know if I can help, but let's give it a try.

I have tried getting the Control ID and using GUICtrlRead (note the ControlID changes on every run, hence using the ClassNameNN above) but failed even to get anything from the control that I can read with ControlGetText - am I missing something, are these functios only valid with controls created through AutoIt?

Cannot find anything that addresses this directly in other posts - any advice appreciated

As far as I know, it is not possible to ready with GUICtrlRead() anything but au3 generated GUI's.

From what i understand, it is not possible to identify the control accurately by using the ControlID, or at least to get the right readout.

Please let me suggest 2 barbaric methods that you might find useful, or, if not at least entertaining ;)

1. If you can select a field by using a control, do a ControlFocus ()on it, and then, read the field "manually send("^a") $output=ClipGet()

It should work. you may need to work a bit with the data that you get this way, but at least you get it.

2. If the field can not be really selected by using a control, barbarically do a MouseClick () in the needed field to read the needed data just as above. Moving from one field to the other may work better with send("{tab}").

Please be advised that it is possible to get some errors this way, at it might be a good idea to put in some kind of error checking of the data that you get.

Share this post


Link to post
Share on other sites

No. ControlGetText works on other apps. (See the example code in the help file, it works with Notepad.)

I do not know what to suggest you try next... but I can give you post a free bump to the top in the hopes that others might have a suggestion.

Nice first post... good details.

Welcome to the forums...

Thanks for your support... tried the ClipGet() approach and it works - this is certainly better than parsing the entire window text!

Still curious about the behaviour I am seeing though, the 'problem' control is read only (although selectable, fortunately)

Share this post


Link to post
Share on other sites

1. If you can select a field by using a control, do a ControlFocus ()on it, and then, read the field "manually send("^a") $output=ClipGet()

This works! (needed ^c to get the text onto the clipboard but that did not take too long to figure out)

But having seen your Icon/signature I am worried you may be working too hard - please try not to kill yourself as I may need your advice again - many thanks!

Share this post


Link to post
Share on other sites

Turned into a function:

Func _CtrlGetTextClipboard($wndTitle, $ctrlName)
; Save the currently active window and control focus
    $currentTitle = WinGetTitle("","")
    $currentFocus = ControlGetFocus($currentTitle)

; Set the control focus, select the entire text and copy it to the clipboard
;  Control A does not always work
    ControlFocus($wndTitle, "", $ctrlName)
    Send("{END}^+{HOME}^c{END}")
    $rtn = ClipGet()
    
; Return focus to the original window and control
    WinActivate($currentTitle, "")
    ControlFocus($currentTitle, "", $currentFocus)
    
    Return $rtn
EndFunc

Share this post


Link to post
Share on other sites

Dave

Thanks for this refinement... i have been working on and off with AutoIt over past few weeks and referencing controls seems to be a black art as most of the apps I am looking at use .NET (or the VB6 stuff like msoCommandBar etc.) and they frequently do not respond to ControlGetText and similar functions

The other fun bit is that the ControlIDs change (I mostly find the ClassNameNN to be reliable but it has a hashed element under .NET I think)...

So - to get to the point - I am now trying to determine a Control's ID with DllCall('user32.dll', 'int', 'GetDlgCtrlID', 'hwnd', $hwnd) but I need the current active control's hWnd first and DllCall('user32.dll', 'hwnd', 'GetFocus') seems to return 0 every time...

Any ideas? Snippet follows

==========================================

$sTitle="Prestige - [Menu : Form]"

If WinExists($sTitle,"") Then

WinActivate($sTitle,"")

$e=_GetFocus()

ConsoleWrite($e & @LF)

$e=_GetDlgCtrlID($e)

ConsoleWrite($e & @LF)

EndIf

Exit

Func _GetDlgCtrlID($hwnd)

$ID = DllCall('user32.dll', 'int', 'GetDlgCtrlID', 'hwnd', $hwnd)

if IsArray ($ID) Then Return $ID[0]

Return 0

EndFunc ;==>GetDlgCtrlID

Func _GetFocus()

$hwnd = DllCall('user32.dll', 'hwnd', 'GetFocus')

if IsArray ($hwnd) Then Return $hwnd[0]

Return 0

EndFunc ;==>GetFocus

==========================================

Turned into a function:

Func _CtrlGetTextClipboard($wndTitle, $ctrlName)
; Save the currently active window and control focus
    $currentTitle = WinGetTitle("","")
    $currentFocus = ControlGetFocus($currentTitle)

; Set the control focus, select the entire text and copy it to the clipboard
;  Control A does not always work
    ControlFocus($wndTitle, "", $ctrlName)
    Send("{END}^+{HOME}^c{END}")
    $rtn = ClipGet()
    
; Return focus to the original window and control
    WinActivate($currentTitle, "")
    ControlFocus($currentTitle, "", $currentFocus)
    
    Return $rtn
EndFunc

Share this post


Link to post
Share on other sites

May be you can use the Microsoft Active Accessibility technology instead. See this Topic.

Share this post


Link to post
Share on other sites

coryphaena,

Hello! Try this:

$sTitle="Prestige - [Menu : Form]"
If WinExists($sTitle,"") Then 
    WinActivate($sTitle,"")

    $controlName = ControlGetFocus( $sTitle )
    $e=ControlGetHandle( $sTitle, "", $controlName )
    ConsoleWrite($e & @LF)

    $e=_GetDlgCtrlID($e)
    ConsoleWrite($e & @LF)
EndIf
Exit

Func _GetDlgCtrlID($hwnd)
    $ID = DllCall('user32.dll', 'int', 'GetDlgCtrlID', 'hwnd', $hwnd)
    if IsArray ($ID) Then Return $ID[0]
    Return 0
EndFunc;==>GetDlgCtrlID

Func _GetFocus()
    $hwnd = DllCall('user32.dll', 'hwnd', 'GetFocus')
    if IsArray ($hwnd) Then Return $hwnd[0]
    Return 0
EndFunc;==>GetFocus

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