Page 1 of 1

`WinGet...ControlList` but ONLY get visible controls

Posted: 20 Oct 2021, 17:48
by wad11656
I'm using an application called CORE, which uses tabs just like an Internet browser does. I only want to get the ClassNN's of the active tab.

Even with DetectHiddenText, Off, WinGet, OutputVar, ControlList, A (example in docs) still parses through all the "hidden" text/controls in all of the inactive tabs too. :?

I...think the poster in the link below had the same issue and found a solution with DllCall(), but before I spend time digging into how DllCall() works and what that code is doing on my own, I'd first like someone to confirm that this indeed will solve my issue, and perhaps help me break down what is happening in that solution's code:

www.autohotkey.com/board/topic/74890-wingettext-troubles/?p=476971

Thank you in advance

P.S. I've been lurking these forums for months at my job without ever feeling a need to post anything 'cause of all the great solutions already here for all sorts of specific scenarios, so thank you.

Re: `WinGet...ControlList` but ONLY get visible controls  Topic is solved

Posted: 21 Oct 2021, 11:57
by Capn Odin
You can retrieve the hwnds of the controls of the window and then check whether the controls are visible. Here is an example it uses GridGUI to show the properties of the controls in a GUI.

Code: Select all

#Include <GridGUI>

SetBatchLines, -1
SetWinDelay, 0

; Creating and styling a GUI
myGui := new GridGUI("CSV Viewer", "resize")
myGui.GuiClose := GridGUI.ExitApp
myGui.Color("CED2DD")
myGui.Font("s9 c4D2609", "Helvetica")

LV := new GridGUI.ListviewControl(myGui.hwnd, "AltSubmit -Multi", "Class|Visible|Text")
myGui.AddControl(1, 1, LV, {exW: 1, exH: 1, fillW: true, fillH: true})

myGui.Show("w200 h700")

DllCall("RegisterShellHookWindow", "UInt", myGui.hwnd)
MsgNum := DllCall("RegisterWindowMessage", "Str", "SHELLHOOK")
OnMessage(MsgNum, Func("ShellMessage").Bind(myGui, LV))
return

UpdateCtrlList(LV, hwnd) {
	LV.Redraw(0)
	LV.Delete()
	rows := []
	for i, ctrl in GetControlsOfWin(hwnd) {
		rows.Push([GetClassOfControl(ctrl), GetVisibilityOfControl(ctrl), GetTextOfControl(ctrl)])
	}
	LV.AddArray(rows)
	LV.Redraw(1)
	LV.ModifyCol()
}

ShellMessage(gui, LV, nCode, wParam, lParam) {
	static	HSHELL_WINDOWCREATED := 1, 
			HSHELL_WINDOWACTIVATED := 32772 ; 4
	;ToolTip, % nCode "`n" wParam "`n" lParam
	if(nCode = HSHELL_WINDOWACTIVATED) {
		if(gui.hwnd != wParam) {
			UpdateCtrlList(LV, wParam)
		}
	}
}

GetVisibilityOfControl(hwnd) {
	ControlGet, visibility, Visible, , , % "ahk_id " hwnd
	return visibility
}

GetClassOfControl(hwnd) {
	VarSetCapacity(name, 100)
	size := DllCall("GetClassName", "Ptr", hwnd, "Str", name, "UInt", 100)
	return name
}

GetTextOfControl(hwnd) {
	
	ControlGetText, text, , % "ahk_id " hwnd
	return text
}

GetControlsOfWin(hwnd) {
	WinGet, ctrls, ControlListHwnd, % "ahk_id " hwnd
	return StrSplit(ctrls, "`n")
}

Re: `WinGet...ControlList` but ONLY get visible controls

Posted: 21 Oct 2021, 13:33
by wad11656
Capn Odin wrote:
21 Oct 2021, 11:57
You can retrieve the hwnds of the controls of the window and then check whether the controls are visible. Here is an example it uses GridGUI to show the properties of the controls in a GUI.
Thanks for the reply. I hope it didn't take too much time. Before I saw your reply, I just came back here to say I finally just found the "Visible" parameter in the docs for ControlGet ( :facepalm: ) which seems to work great: only controls in the active tab return a 1, exactly as I hoped...So, I'll just loop through the controls and see if Visibility is 1 or not to confirm whether it's in the active tab. :thumbup: