Problem where Edit controls in a program are jumping around and trying to RegExMatch the correct ones

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Off Topic
Posts: 43
Joined: 07 Oct 2017, 20:57

Problem where Edit controls in a program are jumping around and trying to RegExMatch the correct ones

18 Feb 2018, 14:50

Hi guys. I have this problem in Adobe Illustrator where certain edit controls that I want the information of (like x and y coordinates, width and height parameters) will jump around depending on what tool is active or what's currently selected (if a rectangle, if text, if multiple objects, etc). So I'm trying to get a list of all controls, omit everything that isn't an Edit control, then scan through these edit controls and determine what context I'm currently in. I don't know of another way to do this and I'm brand new to RegEx so I'm not sure what I'm doing wrong. Here's part of the pattern I'm trying to capture:

Image

And a .pdf version with easy column copying in case that helps:

[The extension pdf has been deactivated and can no longer be displayed.]

My reasoning is, if I can identify something unique to each of these contexts (highlighted in gold, not finished atm because there are more of these), then I'll be able to use RegExMatch to determine which context I'm in and I can then draw the correct parameters from the correct Edit controls. I've successfully done this:

Code: Select all

; Find Artboard
+F24::
match := []
WinGet, ControlList, ControlList, A

Artboard := ""
vOutput := ""

p := 1, m := ""
while p := RegExMatch(ControlList, "(Edit[0-9]+)", m, p + StrLen(m)) {
    match%A_Index% := m1
    finalCount := A_Index
}

Loop, 40
{
	CurrMatch := (A_Index + 100)     ;   This control is always in the 100 to 140 range
	ControlGetText, conMatch, % match%CurrMatch%, ahk_class illustrator
	If (RegExMatch(conMatch, "(Artboard)$") != 0)
	{
		Artboard := match%currMatch%
	}
}
MsgBox % vOutput
Return
My problem is that I can only seem to get reliable results when I use only one variable and one RegExMatch. If I append another condition for another match, like to search for which edit's contents end with "Stock" or "Auto" with the same above technique, I'm getting unreliable and inaccurate results. I get correct information if I do one at a time, but not if the following:

Code: Select all

; variables are global
ScanForEdits(){
match := []
WinGet, ControlList, ControlList, A

Artboard := ""
vOutput := ""

p := 1, m := ""
while p := RegExMatch(ControlList, "(Edit[0-9]+)", m, p + StrLen(m)) {
    match%A_Index% := m1
    finalCount := A_Index
}

Loop, 40
{
	CurrMatch := (A_Index + 100)
	ControlGetText, conMatch, % match%CurrMatch%, ahk_class illustrator
	If (RegExMatch(conMatch, "(Artboard)$") != 0)
	{
		Artboard := match%currMatch%
	}
	;                                           ; Always reports 125
	; If (RegExMatch(conMatch, "(ock)$") != 0)
	; {
	; 	StockVar := match%currMatch%
	; }
}

												; Always reports 125
; Loop, 40
; {
; 	CurrMatch := (A_Index + 100)
; 	ControlGetText, conMatch, % match%CurrMatch%, ahk_class illustrator
; 	If (RegExMatch(conMatch, "(ock)$") != 0)
; 	{
; 		StockVar := match%currMatch%
; 	}
; }
Return
}
No matter if I append it to the same loop or if I separate them as loops. The only time it works is in one of my tests:

Code: Select all

Loop, 40
{
	CurrMatch := (A_Index + 100)

	ControlGetText, conMatch, % match%CurrMatch%, ahk_class illustrator
	If (RegExMatch(conMatch, "(Artboard)$") != 0)
	{
		Artboard := match%currMatch%
	}
}

Loop, % finalCount
{
	CurrMatch := A_Index

	ControlGetText, conMatch, % match%CurrMatch%, ahk_class illustrator
	If (RegExMatch(conMatch, "(ock)$") != 0)
	{
		StockNum := match%currMatch%
	}
}
But I can't recreate it and I don't understand why. I can copy and paste this section (and the entire hotkey) and replace the "(ock)$" with "(Auto)$" and suddenly only the first RegExMatch yields a result despite me taking a RegExMatch that I know is working (from having it isolated on a different hotkey) and pasting it here, and I don't know why. What am I doing wrong here? I realize this might be a dumb way to approach this but I don't know of a better method to determine how I know which Edit controls that my x, y, w, and h parameters will be in, Illustrator has 140+ edit controls and it wouldn't be easy to determine the x,y,w or h from contents alone (often I'll have x "0 pt" like many other boxes, or stroke width will be "20 pt" and could be mistaken for a w/h parameter, etc.)
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Problem where Edit controls in a program are jumping around and trying to RegExMatch the correct ones

18 Feb 2018, 15:50

- The key facts are: how many Edit controls are there, and are their physical positions (relative to the top-left corner) constant, or do they move about.
- Here is some relevant code:

Code: Select all

q:: ;refer to Edit controls by their hWnd or by their coordinates
WinGet, hWnd, ID, A
oEdit := {}, oEdit2 := {}
Loop
{
	ControlGet, hCtl, Hwnd,, % "Edit" A_Index, % "ahk_id " hWnd
	if !hCtl
		break
	ControlGetPos, vCtlX, vCtlY, vCtlW, vCtlH, % "Edit" A_Index, % "ahk_id " hWnd
	oEdit[A_Index] := hCtl
	if !oEdit2.HasKey(vCtlX)
		oEdit2[vCtlX] := []
	oEdit2[vCtlX, vCtlY] := hCtl
	vCount := A_Index
}
MsgBox, % vCount "`r`n" vCtlX " " vCtlY
hCtl1 := oEdit[vCount]
hCtl2 := oEdit2[vCtlX, vCtlY]
MsgBox, % hCtl1 "`r`n" hCtl2
ControlGetText, vText1,, % "ahk_id " oEdit[vCount]
ControlGetText, vText2,, % "ahk_id " oEdit2[vCtlX, vCtlY]
MsgBox, % vText1 "`r`n" vText2
return
- You could also try AccViewer, anything that it can retrieve, can be retrieved via the Acc library functions:
Acc library (MSAA) and AccViewer download links - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=26201
- Re. RegEx, some possibilities:

Code: Select all

WinGet, vCtlList, ControlList, A
RegExReplace(vCtlList, "Edit\d",, vCount)
MsgBox, % vCount

;if RegExMatch(conMatch, "Artboard$")
;if RegExMatch(conMatch, "(Stock|Auto)$")
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Off Topic
Posts: 43
Joined: 07 Oct 2017, 20:57

Re: Problem where Edit controls in a program are jumping around and trying to RegExMatch the correct ones

19 Feb 2018, 00:41

jeeswg wrote:- The key facts are: how many Edit controls are there, and are their physical positions (relative to the top-left corner) constant, or do they move about.
Hey jeeswg, thanks for the help yet another time, I got AccViewer running and it's very helpful, I'll use it. The total number of Edit controls will change from around 130 to 140 depending on what's selected, but the positioning of the ones I care about most doesn't change when not hidden. This is the panel I'm trying to use it on:

Image

I didn't realize until well into this that undocking it makes the numbers much more stable, the top are identified by hWnd (in the code below) and the bottom are by straight Edit number, which is how I was doing it up to this point. It works for basic shapes but it makes a mess of things pretty quickly, if you watch the panel during this you'll see how it's rebuilding and how inaccurate the bottom one can get. I spent a while using and testing your code but I've found the simplest solution is to just undock the panel, select a configuration I know is guaranteed, take the hWnds from known Edit numbers and then constantly draw information from the hWnds afterwards. I suspect it's because I don't really understand the positioning part of your code though, I normally wouldn't have this undocked and those Edit controls are pretty steady position-wise for nearly any context except a few tools or no selection. I can't make out how, if I know the coordinates:

Code: Select all

Edit28 x2285, y269, w75, h19
Edit27 x2285, y308, w75, h19
Edit25 x2415, y269, w75, h19
Edit24 x2415, y308, w75, h19
I can retrieve the hWnd from the coordinates rather than the Edit number. I'm afraid this part of your code is over my head:

Code: Select all

	oEdit[A_Index] := hCtl
	if !oEdit2.HasKey(vCtlX)
		oEdit2[vCtlX] := []
	oEdit2[vCtlX, vCtlY] := hCtl
	vCount := A_Index
I can't make out what's happening here in the context or how I can implement known coordinates (rather than just using the ClassNN). I know that this loops through all the Edits, and I did succeed in RegExMatch with it, though it seems like it might be a burden to want this to constantly RegExMatch all 140 controls as I have the program open. I did get it to work:

Code: Select all

F20::
; q:: ;refer to Edit controls by their hWnd or by their coordinates
WinGet, hWnd, ID, A
oEdit := {}, oEdit2 := {}
Loop
{	
	ControlGet, hCtl, Hwnd,, % "Edit" A_Index, % "ahk_id " hWnd
	if !hCtl
		break
	ControlGetPos, vCtlX, vCtlY, vCtlW, vCtlH, % "Edit" A_Index, % "ahk_id " hWnd
	oEdit[A_Index] := hCtl
	if !oEdit2.HasKey(vCtlX)
		oEdit2[vCtlX] := []
	oEdit2[vCtlX, vCtlY] := hCtl
	ControlGetText, vText0,, % "ahk_id " oEdit2[vCtlX, vCtlY]
	vCount := A_Index
	
	if (vText0 = "ffffff")
	{
		MsgBox % "Found target Edit:" "`r`n" 
		. "[x" vCtlX ", y" vCtlY ", w" vCtlW ", h" vCtlH "]" "`r`n" 
		. "Edit" vCount ": " vText0 "`r`n" 
		. "Hwnd:" hCtl

		ColorControl := hCtl
	}
}
MsgBox % ColorControl
return
But ultimately it doesn't seem too bad a compromise to undock the panel, assign the hWnds from the known Edit numbers:

Code: Select all

global ParamTargets1 := ["102","101","100","99","14","123"]
global Params := ["x","y","w","h","c","A"]

^F20::
vOutput := ""
CtrlOut := ""

WinGet, hWnd, ID, A

Loop, % ParamTargets1.Length()
{
	ControlGet, hCtl, Hwnd,, % "Edit" ParamTargets1[A_Index], % "ahk_id " hWnd
	Marker%A_Index% := Params[A_Index]
	Marker := Params[A_Index]
	hCtl%Marker% := hCtl
	ControlGetText, vText%Marker%,, % "ahk_id " hCtl
	vOutput .= Marker%A_Index% vText%Marker% "`r`n" 
	CtrlOut .= Marker " Edit" ParamTargets1[A_Index] " " hCtl "`r`n"
}
MsgBox % CtrlOut
MsgBox % vOutput
Return
Then loop through these on a Timer using the hWnds to identify them:

Code: Select all

Loop, % ParamTargets1.Length()
{
	Marker := Params[A_Index]
	cHwnd := hCtl%Marker%
	ControlGetText, vText0%Marker%,, % "ahk_id " cHwnd
	vText%Marker% := RTrim(vText0%Marker%, " pt")
}
This gives me easy variables to work with for the current information like vTextx, vTexty, vTextw, vTexth, etc., which was ultimately what I was aiming for. I don't mind doing it this way but if you could give a bit of explanation on the coordinates or so I could try and keep the panel docked I'd appreciate it.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Problem where Edit controls in a program are jumping around and trying to RegExMatch the correct ones

19 Feb 2018, 01:03

- In reference to:

Code: Select all

	oEdit[A_Index] := hCtl
	if !oEdit2.HasKey(vCtlX) ;it's possible that these 2 lines are unnecessary
		oEdit2[vCtlX] := [] ;it's possible that these 2 lines are unnecessary
	oEdit2[vCtlX, vCtlY] := hCtl
	vCount := A_Index
- What I was doing here was:
creating a key: oEdit[n], the nth Edit control has a particular window handle
creating a key: oEdit2[x,y], the Edit control at (x,y) has a particular window handle
note: the objects, oEdit and oEdit2, are completely separate
- That may or may not be useful, I'm not sure quite what's going on with all of those Edit controls: their positions/ClassNNs/quantity.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 330 guests