Selecting a tab in another program

Get help with using AutoHotkey and its commands and hotkeys
User avatar
jeeswg
Posts: 6722
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Selecting a tab in another program

06 Jun 2017, 16:16

None of the scripts need AccViewer, although they made need Acc.ahk.

If a script uses a function beginning with 'Acc_', then you need to include (#Include) Acc.ahk, or you need to copy the functions into your script, or (although not recommended in this case) you could copy bits of code from the functions into your script.

The script you mentioned does not have any 'Acc_' functions in it, so does not require Acc.ahk.

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

I was surprised that none of these have text:
Parameters/Prolog/Metadata/Data/Epilog.
What control(s) corresponds to those tab headers.

#327701 Turbo Integrator
#327702 Advanced
#327703 Variables
#327704 Data Source
#327705 Turbo Integrator
#327706 Connection
#327707 Turbo Integrator
#327708 Connection
#327709 Schedule

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

One thing that might be useful is to check the parent windows for the Edit controls e.g.:

If the MsgBox gives 2 different hWnds then that information may be useful.

Code: Select all

;q:: ;control get parent
WinGet, hWnd, ID, A
ControlGet, hCtl, Hwnd,, Edit1, % "ahk_id " hWnd
hWnd2 := DllCall("user32\GetParent", Ptr,hCtl, Ptr)
hWnd2 := Format("0x{:x}", hWnd2)
WinGetClass, vWinClass, % "ahk_id " hWnd
WinGetClass, vWinClass2, % "ahk_id " hWnd2
MsgBox % hWnd " " vWinClass "`r`n" hWnd2 " " vWinClass2
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Wigi
Posts: 93
Joined: 05 Jun 2017, 10:52
Contact:

Re: Selecting a tab in another program

06 Jun 2017, 16:35

Hi,

Thank you for the explanations, then I will use SendMessage for the tab that is selected :-)

Regarding the controls without text: I guess that these are the tabs in the upper row / multipage (what you want to call them).
I cannot find Connection and Turbo Integrator, but probably these will become visible depending on the choices in the data source. Blame IBM ;-)

For your last question: see the picture. Whatever tab I click on and execute the script, it gives me different hWnds in the msgbox.
00.JPG
00.JPG (144.19 KiB) Viewed 1799 times
User avatar
jeeswg
Posts: 6722
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Selecting a tab in another program

06 Jun 2017, 16:45

Try this and post a screenshot again:

Code: Select all

q:: ;control get parent
DetectHiddenWindows, On
WinGet, hWnd, ID, A
ControlGet, hCtl, Hwnd,, Edit1, % "ahk_id " hWnd
hWnd2 := DllCall("user32\GetParent", Ptr,hCtl, Ptr)
hWnd2 := Format("0x{:x}", hWnd2)
WinGetClass, vWinClass, % "ahk_id " hWnd
WinGetClass, vWinClass2, % "ahk_id " hWnd2
WinGetTitle, vWinTitle, % "ahk_id " hWnd
WinGetTitle, vWinTitle2, % "ahk_id " hWnd2
;ControlGetText, vText,, % "ahk_id " hWnd
;ControlGetText, vText2,, % "ahk_id " hWnd2
WinGetText, vText, % "ahk_id " hWnd
WinGetText, vText2, % "ahk_id " hWnd2

	vText := StrReplace(vText, "`r", " ")
	vText := StrReplace(vText, "`n", " ")
	if (StrLen(vText) > 50)
		vText := SubStr(vText, 1, 50) "..."

	vText2 := StrReplace(vText2, "`r", " ")
	vText2 := StrReplace(vText2, "`n", " ")
	if (StrLen(vText2) > 50)
		vText2 := SubStr(vText2, 1, 50) "..."

MsgBox % hWnd "`r`n" vWinClass "`r`n" vWinTitle "`r`n" vText "`r`n`r`n" hWnd2 "`r`n" vWinClass2 "`r`n" vWinTitle2 "`r`n" vText2
return
Btw sometimes with tab controls, if you get a list of a window's controls, when you first show the window, and then click various tabs, and then get a list of controls, the number, and possibly the order, will be different.
Last edited by jeeswg on 06 Jun 2017, 17:14, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Wigi
Posts: 93
Joined: 05 Jun 2017, 10:52
Contact:

Re: Selecting a tab in another program

06 Jun 2017, 17:03

Here it is
00.JPG
00.JPG (305.3 KiB) Viewed 1789 times
User avatar
jeeswg
Posts: 6722
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Selecting a tab in another program

06 Jun 2017, 17:12

Cheers, well the idea is that for the Edit controls you might be able to retrieve the tab header, which could be useful for what you want to achieve.

E.g.

Code: Select all

q:: ;Edit controls - get window title of parent window
WinGet, hWnd, ID, A
vOutput := ""
Loop, 4
{
	ControlGet, hCtl, Hwnd,, % "Edit" A_Index, % "ahk_id " hWnd
	hWnd2 := DllCall("user32\GetParent", Ptr,hCtl, Ptr)
	WinGetTitle, vWinTitle, % "ahk_id " hWnd2
	vOutput .= vWinTitle "`r`n"
}
Clipboard := vOutput
MsgBox, % vOutput
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Wigi
Posts: 93
Joined: 05 Jun 2017, 10:52
Contact:

Re: Selecting a tab in another program

07 Jun 2017, 05:33

This gives me 4 times "Advanced" (see the name of the tab in the upper row).
Capture.JPG
Capture.JPG (31.39 KiB) Viewed 1764 times
User avatar
jeeswg
Posts: 6722
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Selecting a tab in another program

07 Jun 2017, 11:16

Thanks. I haven't too much more in mind to try.

Btw what does the window spy say is the control or controls (the ClassNN) for: Parameters/Prolog/Metadata/Data/Epilog?

Also can AccViewer provide information that tells you which of those tab headers is focused?

There is this, to list all controls in a window, and each control's children:

Code: Select all

q:: ;list ClassNNs (where NN is relative to active window)
;and children of each ClassNN (where NN is relative to active window)
DetectHiddenWindows, On
WinGet, hWnd, ID, A
WinGet, vCtlList, ControlList, % "ahk_id " hWnd
oArray := {}
Loop, Parse, vCtlList, `n
{
	vCtlClassNN := A_LoopField
	ControlGet, hCtl, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
	oArray[hCtl] := vCtlClassNN
	vOutput .= vCtlClassNN "`r`n"
}

vOutput := ""
VarSetCapacity(vOutput, 1000000*2)
Loop, Parse, vCtlList, `n
{
	vCtlClassNN := A_LoopField
	ControlGet, hCtl, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
	WinGet, vCtlList2, ControlList, % "ahk_id " hCtl
	vOutput2 := ""
	vCount := 0
	Loop, Parse, vCtlList2, `n
	{
		vCtlClassNN2 := A_LoopField
		ControlGet, hCtl2, Hwnd,, % vCtlClassNN2, % "ahk_id " hCtl
		if !(A_Index = 1)
			vOutput2 .= ","
		vOutput2 .= oArray[hCtl2]
		vCount++
	}
	vOutput .= vCount "`t" RTrim(vCtlClassNN ": " vOutput2) "`r`n"
}

Clipboard := vOutput
MsgBox, % "done"
return
Btw if you do these:
WinGet, vCtlList, ControlList, % "ahk_id " hWnd
WinGet, vCtlList, ControlList, % "ahk_id " hCtl
Where hCtl is a child of hWnd, and where hCtl has child controls, then you will likely get some of the same controls in both lists with the same class, but different NNs.

I've provided pretty much all of the techniques I would use for this. So hopefully with the information in this thread, you can achieve everything that you want, programmatically.
Last edited by jeeswg on 07 Jun 2017, 12:13, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Wigi
Posts: 93
Joined: 05 Jun 2017, 10:52
Contact:

Re: Selecting a tab in another program

07 Jun 2017, 11:58

Hi,

I am indeed able to get the active tab (both 'Advanced' and 'Prolog/Metadata/...)
Now I am in the process of reading the contents of the active tab.
Thanks a lot for everything, if I am stuck I will ask again but I guess that I have all the tools now at my disposal.

Thanks!
Wigi
Posts: 93
Joined: 05 Jun 2017, 10:52
Contact:

Re: Selecting a tab in another program

07 Jun 2017, 18:14

Hello,

I got it working, in the direction of TM1 to Notepad++.
The source can be either Turbo Integrator, either rules.

If anyone has the time and willingness to have a look at my code and suggest improvements, I would be grateful but I guess it's okay and most of all, it works :-)

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; 1. Alt-F1: COPY THE CONTENTS OF THE SELECTED TAB IN A TI PROCESS TO NOTEPAD++
; if rules are selected, these are copied
; Notepad++ is started if not already started
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

!F1::
{
WinGetTitle, TM1_Window_Title, A

if InStr( TM1_Window_Title, "Turbo Integrator:", false ) = 1
{
; select the contents

WinGet, hWnd, ID, A
SendMessage, 0x130B,,, SysTabControl327, % "ahk_id " hWnd ;TCM_GETCURSEL := 0x130B
vSelection := ErrorLevel+1

If vSelection <> 4
{
   msgbox Select the Advanced tab
   return
}

WinGet, hWnd, ID, A
SendMessage, 0x130B,,, SysTabControl321, % "ahk_id " hWnd ;TCM_GETCURSEL := 0x130B
vSelection := ErrorLevel+1

If vSelection < 2
{
   msgbox Select Prolog, Metadata, Data or Epilog
   return
}

; get the contents of the selected tab
WinGet, hWnd, ID, A
WinGet, vCtlList, ControlList, % "ahk_id " hWnd

vSelection = % vSelection-1
ControlGetText, vText, Edit%vSelection%, % "ahk_id " hWnd
vText := StrReplace(vText, "#****Begin: Generated Statements***", "")
vText := StrReplace(vText, "#****End: Generated Statements****", "")
vText := Trim(vText, "`r`n")

;add the Advanced tab name in front
if % vSelection = 1
   vText = Prolog`r`n`r`n%vText%
else if % vSelection = 2
   vText = Metadata`r`n`r`n%vText%
else if % vSelection = 3
   vText = Data`r`n`r`n%vText%
else if % vSelection = 4
   vText = Epilog`r`n`r`n%vText%

}

else if InStr( TM1_Window_Title, "Rules Editor:", false ) = 1

; select the contents
{
   WinGet, hWnd, ID, A
   ControlGetText, vText, RichEdit20W1, % "ahk_id " hWnd
   vText = `r`n%vText%
}

else
{
   msgbox Not a TM1 acceptable window for this script: go to TI or rules
   return
}

; add the window caption in front
vText = %TM1_Window_Title%`r`n%vText%

; get or create a Notepad++ session
IfWinExist ahk_class Notepad++
{
   WinActivate
   WinWaitActive
   WinMenuSelectItem, , , File, New ; open a new tab
}
Else
{
   ; NOTE: this might change
   Run C:\Program Files (x86)\Notepad++\notepad++.exe
   WinActivate ahk_class Notepad++
   WinWaitActive ahk_class Notepad++
   ; empty tab already opened, we don't need to do this
}

Clipboard := vText

Send, ^v

; tab to space
WinMenuSelectItem, , , Edit, Blank Operations, TAB to Space

; remove trailing spaces
WinMenuSelectItem, , , Edit, Blank Operations, Trim Trailing Space

; apply the TM1 language
WinMenuSelectItem, , , Language, TM1

Send ^{home} ; go to the top

if ErrorLevel   ; i.e. it's not blank or zero.
    MsgBox, ERROR

return 


Can the following If structure:

Code: Select all

;add the Advanced tab name in front
if % vSelection = 1
   vText = Prolog`r`n`r`n%vText%
else if % vSelection = 2
   vText = Metadata`r`n`r`n%vText%
else if % vSelection = 3
   vText = Data`r`n`r`n%vText%
else if % vSelection = 4
   vText = Epilog`r`n`r`n%vText%
be shortened ? Like the function Choose in Excel (and VBA).

Thanks a lot and most of all, jeeswg you were a fantastic resource.
Wigi
Posts: 93
Joined: 05 Jun 2017, 10:52
Contact:

Re: Selecting a tab in another program

07 Jun 2017, 18:20

I created an output on 1 image, Turbo Integrator and rules, side by side. The result in Notepad++ too :-)
00.JPG
00.JPG (416.04 KiB) Viewed 1715 times
I'm learning a lot, certainly the syntax. I cursed on those % and %...% and := and so on !
User avatar
jeeswg
Posts: 6722
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Selecting a tab in another program

07 Jun 2017, 19:23

I should read the OP probably, but from the image, is your intention to show multiple windows on the screen, tiled, navigated to the right tabs.

Re. the tab control/tab headers.
- I believe that the control I asked about is probably a SysTabControl32, when you do ControlGetText they show nothing I believe (based on a test I did).
- When I go to 'Tools, Internet options', AccViewer does not show information that identifies what the active tab is (although this can be retrieved via a message as shown earlier, TCM_GETCURSEL), although it can retrieve the text from the tab headers.

Your code looks pretty good. Personally I would do:

Code: Select all

;one of:
if (vSelection <> 4)
if (vSelection != 4)
if !(vSelection = 4)

if (vSelection = 4)
if (vSelection = "string")
if (vSelection = var)

;one of:
vSelection := vSelection-1
vSelection -= 1
vSelection--
--vSelection
Btw the use of 'v' for variables, is very much a 'me' thing, I didn't invent the notation, although I rarely see it on the forums, but you're welcome to use it, or not use it.

In all my time with AHK, I didn't know this was possible, although it does make sense cf. what you can do with parameters:

Code: Select all

vSelection = % vSelection-1
Did you see that somewhere?

Haha yeah syntax can be tricky ...
I might release some AHK tutorials this week/next week.

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

Re. choose. There are too many ways to do this, and I may have made a mistake somewhere below, anyhow, I think AHK should decide what it recommends. Although I don't personally require or want a new choose syntax, it's not an unreasonable wish list item.

Code: Select all

q:: ;choose
vSelection := 3

vLabel := ""
oArray := ["Prolog","Metadata","Data","Epilog"]
if vSelection in 1,2,3,4
	vLabel := oArray[vSelection]
MsgBox, % vLabel

if (vSelection = 1)
	vLabel := "Prolog"
else if (vSelection = 2)
	vLabel := "Metadata"
else if (vSelection = 3)
	vLabel := "Data"
else if (vSelection = 4)
	vLabel := "Epilog"
else
	vLabel := ""

;split across multiple lines:
;multiple ternary operators:
vLabel := ""
(vSelection = 1) ? (vLabel := "Prolog")
: (vSelection = 2) ? (vLabel := "Metadata")
: (vSelection = 3) ? (vLabel := "Data")
: (vSelection = 4) ? (vLabel := "Epilog") : ""
MsgBox, % vLabel

;split across multiple lines:
;multiple ternary operators:
vLabel := (vSelection = 1) ? "Prolog"
: (vSelection = 2) ? "Metadata"
: (vSelection = 3) ? "Data"
: (vSelection = 4) ? "Epilog"
: ""
MsgBox, % vLabel

;in AHK v2 for ternary operator you have to specify both branches
;so the 2nd branch does nothing
vLabel := ""
(vSelection = 1) ? (vLabel := "Prolog") : ""
(vSelection = 2) ? (vLabel := "Metadata") : ""
(vSelection = 3) ? (vLabel := "Data") : ""
(vSelection = 4) ? (vLabel := "Epilog") : ""
MsgBox, % vLabel

;hacky unofficial way
vLabel := ""
(vSelection = 1) && (vLabel := "Prolog")
(vSelection = 2) && (vLabel := "Metadata")
(vSelection = 3) && (vLabel := "Data")
(vSelection = 4) && (vLabel := "Epilog")
MsgBox, % vLabel
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Wigi
Posts: 93
Joined: 05 Jun 2017, 10:52
Contact:

Re: Selecting a tab in another program

08 Jun 2017, 07:13

Thanks !

I like the idea of the array for Choose.

In TM1 I use:
cName for constants
vName for variables
pName for parameters
Wigi
Posts: 93
Joined: 05 Jun 2017, 10:52
Contact:

Re: Selecting a tab in another program

08 Jun 2017, 18:03

Hi,

To add to this, my intention is to copy/paste the codes from TM1 to Notepad++. No tiles etc. That was just my presentation of the work of the previous evenings. Coming weekend I will work on the reverse, changed coding in Notepad++ should be copied back to TM1, in the correct tab. If the wrong tab is selected I guess I will show a msgbox. Either stop the copy, either have AHK send left mouse clicks to activate he correct tab.

Return to “Ask For Help”

Who is online

Users browsing this forum: BeatboxHero, Bing [Bot], Chunjee, Flipeador, KilliK, pn4265, Qtic, teadrinker, TheUnknown138, x-tremespeed and 66 guests