When I run this script, I have a notepad window open with "test.txt - Notepad" as the text. The id variable gets properly filled with the hwnd array from the subfunction ControlListHwnd. Then it loops through all of the control items it found for notepad (there are very few).
Script:
!t:: ;To retrieve the formatted text and paste:
{
DetectHiddenText, On
DetectHiddenWindows, On
MsgBox, Starting
WinGet, id, ControlListHwnd, test.txt - Notepad, , Program Manager
Loop, Parse, id, `n
{
this_id := %A_LoopField%
;this_id := id%id_Index%
;this_id := id
;WinActivate, ahk_id %this_id%
WinGetClass, this_class, ahk_id %this_id%
WinGetTitle, this_title, ahk_id %this_id%
;MsgBox, 4, , Visiting All Windows`n%A_Index% of %id%`nahk_id %this_id%`nahk_class %this_class%`n%this_title%`n`nContinue?
ControlHwnd := %A_LoopField%
ControlGetText, outputText, , ahk_id %ControlHwnd%
MsgBox, 4, , All Controls`n id - %A_LoopField% `n Control Text - %outputText%`n Class - %this_class% `n Title - %this_title% `n `n Continue?
IfMsgBox, NO, break
}
MsgBox, Finished - %id% - end
return
}
When it loops through, it should display a messagebox that contains the text, class, and title from the control queried.
Does it look like I am passing the hwnd incorrectly? Or else is there a better way to do this?
In the past I used direct Dll calls to User32\GetWindow, hoping I can do this with AutoHotkey with it's existing functions.
This is a classic mistake of confusing legacy syntax with the new expression syntax.
These two lines specifically:
this_id := %A_LoopField%
ControlHwnd := %A_LoopField%
In legacy assignment (=
) you'd indeed reference a variable by wrapping it in % %
, but in an expression (which you what you get when you use :=
) you reference variables by just typing it in:
this_id := A_LoopField
ControlHwnd := A_LoopField
No %
s.
Misc stuff:
Hotkey labels do not need to be wrapped in { }
s, in case you didn't know.
And there's no need to set
DetectHiddenText, On
DetectHiddenWindows, On
every time you run your hotkey. You can just set them once at the top of your script.
Here's your full script using expression syntax.
Overall, I'd recommend to stop using legacy syntax, it's not 2008 anymore.
You can get started on learning the difference between legacy and expression syntaxes here
DetectHiddenText, On
DetectHiddenWindows, On
!t::
MsgBox, Starting
;parameters that are started with a % followed up by a space
;are automatically evaluated as expressions
;using it to just be able to quate straight text parameters
;could be considered overkill, but I'll just convert everything
;to expression syntax for the sake of the demonstration
;also, I'd change "test.txt - Notepad" to "ahk_exe notepad.exe"
WinGet, id, ControlListHwnd, % "test.txt - Notepad", , % "Program Manager"
Loop, Parse, id, `n
{
this_id := A_LoopField
WinGetClass, this_class, % "ahk_id " this_id
WinGetTitle, this_title, % "ahk_id " this_id
ControlHwnd := A_LoopField
ControlGetText, outputText, , % "ahk_id " ControlHwnd
MsgBox, 4, , % "All Controls`n id - " A_LoopField "`n Control Text - " outputText "`n Class - " this_class "`n Title - " this_title "`n `n Continue?"
IfMsgBox, No
break
}
MsgBox, % "Finished - " id " - end"
return