[SOLVED] Using a fixed subpattern for changing subpatterns in CONTROL's ClassNN ? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
DRocks
Posts: 565
Joined: 08 May 2018, 10:20

[SOLVED] Using a fixed subpattern for changing subpatterns in CONTROL's ClassNN ?

16 May 2018, 12:06

Hi everyone,

Discovered AHK 3 weeks before now. Its awesome and I want to thank the developpers first.
So before posting I have red the AHK docs ALOT and found many useful info also many useful forums topics.
But I still can't figure out this case. Any help would be greatly appreciated :)

This post is about dealing with variable/changing ClassNN of CONTROLS.

I have managed to deal with variable Windows Classes containing subpatterns because RegEx SetTitleMatchMode allows us to do this very well.
The problem is that it doesn't work for me when its related to variable/changing CONTROL CLASSNN.

Here is a visualisation of what I'm talking about before I go further. WindowSpy reports:
Focused Window: ahk_class WindowsForms10.Window.8.app.0.141b42a_r38_ad1
Focused Control: ClassNN: WindowsForms10.EDIT .app.0.141b42a_r38_ad17

As you can see there are clear subpatterns and this is fine. Its not the problem. I understand them now in this particular program.
Problem is the subpattern, that is changing from client to client with this program (Sage 50 Canadian edition),
is the colored part in the middle of the haystack.

What I want to do now, instead of having a complex RexExMatch() everytime there is a variable CONTROL to act on in the script,
is this:
1. Find what is the active Window's SUBPATTERN on auto-execute of script
2. Store it in a variable containing it as long as the script runs
3. Insert this found and stable subpattern in the middle of ANY variable CONTROL classNN to identifie them without requiring a unneccessary RegExMatch

Why I want this:
-Because, if the common and fixed subpattern is found on auto-execute as shown bellow in code example, then why would it need to RegExMatch each CONTROL CLASSNN anytime I need to use them?
-Documentation seems to say in many palces that RegExMatch is not the fastest performing and I want the fastest/lightest way of coding this script.
-I think it is much easier to find the pattern once on auto-execute and use it everywhere in the script as needed rather than re-running a RegExMatch every time a CONTROL CLASSNN needs to be identified exactly

Here is the code example taken from a part of the script:

Code: Select all

	
;This is PART of auto-execute section:
;Please focus your attention on the fact that I find the current subpattern on auto-execute so the variable contains the subpattern for all windows and controls of this client
	
	SetTitleMatchMode, RegEx 							; Changes WinTitle, WinText, ExcludeTitle, and ExcludeText to accept regular expressions. 
	
	if WinExist(.SAI) 									; Sage openned active client WinTitle Exists
	{
		WinGetTitle, SageActiveClient 						;I use the current Wintitle for my client name in GUI
		;MsgBox %SageActiveClient%
		SageActiveClient:=StrReplace(SageActiveClient, ".SAI")	;I need to get rid of the .SAI extension found in Wintitle previously
		;MsgBox %SageActiveClient%
		WinGetClass, SageWinClassPattern					;I retrieve the Full Class of this main Window because it contains the unique Subpattern and it will be my Haystack from which to retrieve it
		;MsgBox %SageWinClassPattern%						;ahk_class WindowsForms10.Window.8.app.0.141b42a_r38_ad1
		SageWinClassPattern:=SubStr(SageWinClassPattern, 31, -8) ;	       "WindowsForms10.Window.8.app.0." "_r38_ad1" 	            (This Returns found string between start 31 and -8 from the end)
		;MsgBox %SageWinClassPattern%						; 141b42a	 (this is the retrieved and stored to variable subpattern. It is present in all of this program's windows and controls)
	}
	Else
		MsgBox Open the Sage Client before loading the script.
		
;... more code under this auto-execute part

Later in the script only way I can make it work is using RegExMatch like this example which works in my script:

Code: Select all

			Tab::
			; Skip to TRANSPORT
			winget, controls, ControlList, Achats|fournisseurs|Charges ;RegEx TitleMatchMode with different options
			Loop, Parse, controls, `n
				if(RegExMatch(A_LoopField, "WindowsForms10.EDIT.app.0.(?:.*)_r38_ad114", Match)) ; RegExMatch this control with the current subpattern
				{
					ControlClick, %Match%, Achats|fournisseurs|Charges,, Left
					break
				}
			;MsgBox %controls%
			;MsgBox %Match%
			return

I want to do something like this but nothing I tried worked. I need to go back to the complex RegExMatch example as shown before.

Code: Select all

;if something...
ThisButtonClassNN:= WindowsForms10.EDIT.app.0.%SageWinClassPattern%_r38_ad114 ; I want to insert the found subpattern stored in the variable from the auto-execute example
;MsgBox %ThisButtonClassNN% ;Returns: WindowsForms10.EDIT.app.0.141b42a_r38_ad114
ControlClick, %ThisButtonClassNN%, Achats|fournisseurs|Charges,, Left
return
Ok so I think its the clearer I can get because I myself have trouble following all of this complexity.
Is it possible to do something like this, if not what are the best and simplest/most performant solutions?

THANKS a alot in advance for your time and help :)
Alex
User avatar
TLM
Posts: 1608
Joined: 01 Oct 2013, 07:52
Contact:

Re: Using a fixed subpattern for changing subpatterns in CONTROL's ClassNN ?  Topic is solved

16 May 2018, 14:16

You can detect a partial window title using a pattern with SetTitleMatchMode. Regex.
For instance:

Code: Select all

SetTitleMatchMode, RegEx 
WinGetClass, WinClass, ahk_class WindowsForms10\.Window\.8\.app\.0\..*?_r38_ad.*?

Msgbox % WinClass
The dynamic portion of the title can be extracted and assigned to a variable using something like

Code: Select all

;.................
WinClass = ahk_class WindowsForms10.Window.8.app.0.141b42a_r38_ad1
RegExMatch( WinClass, ".*?\.app\.0\.(?<name>.*?)(?<end>_.*?$)", dynamic_ )

msgbox % "WinClassName: " 	dynamic_name
	   . "`nWinClassEnd: " 	dynamic_end
Then you simply have to create a new variable containing the dynamic portion of the title.

Code: Select all

;.................
ClassNN := "WindowsForms10.EDIT .app.0." dynamic_name "_r38_ad17"
You may run into issues using this approach if the the end of the ClassNN is different than the Window Title.
Also, unfortunately SetTitleMatchMode has no effect of a control's text.

Please feel free to ask if you have any questions.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Using a fixed subpattern for changing subpatterns in CONTROL's ClassNN ?

16 May 2018, 14:32

This function may be useful. Cheers.
Being more generic when using WinActivate and ControlSetText - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 24#p186624
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
DRocks
Posts: 565
Joined: 08 May 2018, 10:20

Re: Using a fixed subpattern for changing subpatterns in CONTROL's ClassNN ?

16 May 2018, 16:51

Thank you so much to both of you!

I'm currently testing the first reply and, TLM, your example code is awesome I'm really liking it.
I'm testing different Control fonctions using the retrieved ClassNN and then I will get back to the forum with updates, then I'll try the sec ond reply by jeeswg :)

Good evening
User avatar
TLM
Posts: 1608
Joined: 01 Oct 2013, 07:52
Contact:

Re: Using a fixed subpattern for changing subpatterns in CONTROL's ClassNN ?

16 May 2018, 17:57

No problems :)
Semi-Protip with MDI ( dynamic ) window control names:
You can loop through the generated control names/handles each time and use things like control position ( x, y coordinates ),
size etc to evaluate and extract the correct control name/handle.

Let me know if you need help with this.
DRocks
Posts: 565
Joined: 08 May 2018, 10:20

Re: Using a fixed subpattern for changing subpatterns in CONTROL's ClassNN ?

17 May 2018, 12:49

Hey so here are some feedbacks on your methods TLM!

Its a great news that it works! With this Im able to do exactly what was the request in first post and its a great acheivement for me so thanks ALOT!! Right now its the best method I am able to use because the subpattern is determined on script startup and its usable on any Control ClassNN!

Im also interested in the tip you gave me about getting the Coordinates of controls.
And also, wondering if we can do things like:
-identify a descriptive text field which is beside or above the actual control we want to retrieve its unique ClassNN or ID. Then...
-use this text fields coordinates as reference for the wanted control's position and ClassNN.

I ask this because the text fields in my program are more stable than the ClassNN ENDINGS of these controls so I can have 2 or 3 possible endings on different clients file for example.

Thanks again :)

Edit: should i start a new topic precisely with that or stick to this one?
User avatar
TLM
Posts: 1608
Joined: 01 Oct 2013, 07:52
Contact:

Re: Using a fixed subpattern for changing subpatterns in CONTROL's ClassNN ?

17 May 2018, 12:59

DRocks wrote:Im also interested in the tip you gave me about getting the Coordinates.
And also wondering if we can do things like:
-identify a descriptive text field which is beside or above the actual control we want to retrieve unique ClassNN or ID
-use this text fields coordinate as reference for the wanted control's position. I say this because the text fields in my program are more stable than the ClassNN ENDINGS of these controls
Glad to hear everything is working out for you.
Looping through a window's controls with ControlGet to obtain the control's handle / hwnd / id gives you a lot of options for manipulation.
The data can easily be stored and recalled to and from variables or better yet an array of control details populated from within the loop.

So I'd say yes :)
DRocks
Posts: 565
Joined: 08 May 2018, 10:20

Re: [SOLVED] Using a fixed subpattern for changing subpatterns in CONTROL's ClassNN ?

17 May 2018, 19:27

Hello Jeeswg,

I'm studying your function and honestly I have a really hard time figuring out. It seems that the end resultat would be more convenient than typing out manually my custom ClassNN from the example show above, but I misunderstand how to implement yours.

Could you please update the original post where you published it with comments? :)
No pressure and thanks in advance


EDIT: thanks again TLM I'm digging deeper and trying to figure out stuff before I am able to understand your more advanced application tips :)

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: AHK_user, just me, sharonhuston and 212 guests