Window Activate/Browser Tab Activate

Post your working scripts, libraries and tools
Tre4shunter
Posts: 36
Joined: 26 Jan 2016, 16:05

Window Activate/Browser Tab Activate

19 Nov 2016, 11:53

Hi all,

Something i started working on - Inspiration came from Run1e's Columbus - perhaps he could implement this functionality into it?!

It will display all active windows - and activate whichever you click on. Also shows Chrome tabs(will be adding other browsers soon hopefully)

Alt+Z to activate
Esc to close

Screenshots:
http://imgur.com/a/CAPKI

http://imgur.com/a/h2qJM

Program code: Includes Just Me's LV_EX functions for groups

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance,Force
setbatchlines, -1

gui,margin,0
gui,-Border
gui,font,s10
gui, +alwaysontop

;Gui,Add,ListBox,x0 y0 h340 w400 vmylistbox gMyListBox CGray,
Gui,Add,Tab3,x0 y0 w400 h340,Active Windows|Browser Tabs
gui,tab,1
Gui, Add, Listview, x0 y0 w400 h340 Grid hwndHLV vVLV gVLV, Windows
Gui,Tab,2
Gui, Add, Listview, x0 y0 w400 h340 Grid hwndHLV2 vVLV2 gVLV2, Tabs
gui,listview,syslistview321

return 

!z::  
;WinGetPos xP, yP, wP, hP, ahk_class Shell_TrayWnd

IDs := []
browserids := []
WinGet, ws_IDList, List
groups=1
LV_Delete()
gui,listview,syslistview322
LV_Delete()
gui,listview,syslistview321
Newlist :={}
bCounter = 1


Loop % ws_IDList
{
	winget,processlist,processname, % "ahk_id" ws_IdList%a_Index%
	if(newlist[processlist] = "")
		newlist[processlist,0] := ws_IdList%a_Index%
	else
		newlist[processlist,newlist[processlist].maxindex()+1] :=  ws_IdList%a_Index%
}


for k,v in newlist
{
	LV_EX_GroupInsert(HLV, groups, k)
	LV_EX_GroupSetState(HLV, groups, "Collapsible")
	for window,hwnd in v
	{
		if(k="Chrome.exe"){
			BrowserCounter+=100
			BrowserCounter:=ListBrowser(hwnd)
		}
		winget,pName,processname, ahk_id %hwnd%
		WinGetTitle,wTitle, ahk_id %hwnd%
		if(((wTitle="Start") OR (wTitle = "Program Manager") AND k = "Explorer.exe")){
			continue
		}
		
		if(wTitle <> "")
		{
			if(pName="Explorer.exe")
				wTitle := "File Explorer - " wTitle
			LV_Add("",wTitle)
			IDs[wTitle] := hwnd
			LV_EX_SetGroup(HLV,LV_GetCount(), Groups)
		}
	}
	groups++
}

LV_EX_EnableGroupView(HLV)
LV_EX_EnableGroupView(HLV2)
LV_ModifyCol(A_Index, "AutoHdr")
gui,show, NA  ;x1515 y735 h300 w400
return

VLV:
gui,listview,syslistview321
LV_GetText(Text,A_EventInfo)
winid := ids[text]
WinActivate, ahk_id %winid%
return

VLV2:
gui,listview,syslistview322
LV_GetText(bText,A_EventInfo)
chromeW := LV_EX_GetGroup(HLV2,A_EventInfo)
gui,listview,syslistview321
gHeader := StrSplit(LV_EX_GroupGetHeader(HLV2,ChromeW),"-").1
WinActivate,  % "ahk_id" browserids[gheader]
list := Acc_Get("Object", "4.1.2.2.2", 0, "ahk_id" browserids[gHeader])
for each, tab in Acc_Children(list) 
{
	if (tab.accName(0) = bText)
	{
		tab.accDoDefaultAction(0)
		return
	}
}
return

ESC::
gui,Hide
return

ListBrowser(hwnd)
{
	global
	gui,listview,syslistview322
	WinGet,wTitle,processname, ahk_id %hwnd%
	LV_EX_GroupInsert(HLV2, hwnd, bcounter++ "-" wTitle)
	browserids.push(hwnd)
	LV_EX_GroupSetState(HLV2, hwnd, "Collapsible")
	tabs:=""
	list := Acc_Get("Object", "4.1.2.2.2", 0, "ahk_id" hwnd)
	for each, tab in Acc_Children(list) 
	{
		LV_Add("",tab.accName(0))
		LV_EX_SetGroup(HLV2,LV_GetCount(), hwnd)
	}
	;tabs .= tab.accName(0) "`n"
	gui,listview,syslistview321
	return browserids
}

;Courtesy of Lexikos
WinGetNormalPos(hwnd, ByRef x, ByRef y, ByRef w="", ByRef h="")
{
	VarSetCapacity(wp, 44), NumPut(44, wp)
	DllCall("GetWindowPlacement", "uint", hwnd, "uint", &wp)
	x := NumGet(wp, 28, "int")
	y := NumGet(wp, 32, "int")
	w := NumGet(wp, 36, "int") - x
	h := NumGet(wp, 40, "int") - y
}

; ======================================================================================================================
; Namespace:      LV_EX
; Function:       Some additional functions to use with AHK ListView controls.
; Tested with:    AHK 1.1.20.03 (A32/U32/U64)
; Tested on:      Win 8.1 (x64)
; Changelog:
;     1.1.01.00/2016-04-28(just me     -  added LV_EX_GroupGetState contributed by Pulover.
;     1.1.00.00/2015-03-13/just me     -  added basic tile view support (suggested by toralf),
;                                         added basic (XP compatible) group view support,
;                                         revised code and made some minor changes.
;     1.0.00.00/2013-12-30/just me     -  initial release.
; Notes:
;     In terms of Microsoft
;        Item     stands for the whole row or the first column of the row
;        SubItem  stands for the second to last column of a row
;     All functions require the handle of the ListView (HWND). You get this handle using the 'Hwnd' option when
;     creating the control per 'Gui, Add, HwndHwndOfLV ...' or using 'GuiControlGet, HwndOfLV, Hwnd, MyListViewVar'
;     after control creation.
; Credits:
;     LV_EX tile view functions:
;        Initial idea by segalion (old forum: /board/topic/80754-listview-with-multiline-in-report-mode-help/)
;        based on code from Fabio Lucarelli (http://users.skynet.be/oleole/ListView_Tiles.htm).
; ======================================================================================================================
; This software is provided 'as-is', without any express or implied warranty.
; In no event will the authors be held liable for any damages arising from the use of this software.
; ======================================================================================================================
; ======================================================================================================================
; LV_EX_EnableGroupView - Enables or disables whether the items in a list-view control display as a group.
; ======================================================================================================================
LV_EX_EnableGroupView(HLV, Enable := True) {
   ; LVM_ENABLEGROUPVIEW = 0x109D -> msdn.microsoft.com/en-us/library/bb774900(v=vs.85).aspx
	SendMessage, 0x109D, % (!!Enable), 0, , % "ahk_id " . HLV
	Return (ErrorLevel >> 31) ? 0 : 1
}

; ======================================================================================================================
; LV_EX_GetGroup - Gets the ID of the group the list-view item belongs to.
; ======================================================================================================================
LV_EX_GetGroup(HLV, Row) {
   ; LVM_GETITEMA = 0x1005 -> http://msdn.microsoft.com/en-us/library/bb774953(v=vs.85).aspx
	Static OffGroupID := 28 + (A_PtrSize * 3)
	LV_EX_LVITEM(LVITEM, 0x00000100, Row) ; LVIF_GROUPID
	SendMessage, 0x1005, 0, % &LVITEM, , % "ahk_id " . HLV
	Return NumGet(LVITEM, OffGroupID, "UPtr")
}
; ======================================================================================================================
; LV_EX_GetHeader - Retrieves the handle of the header control used by the list-view control.
; ======================================================================================================================
LV_EX_GetHeader(HLV) {
   ; LVM_GETHEADER = 0x101F -> http://msdn.microsoft.com/en-us/library/bb774937(v=vs.85).aspx
	SendMessage, 0x101F, 0, 0, , % "ahk_id " . HLV
	Return ErrorLevel
}

; ======================================================================================================================
; LV_EX_GroupGetHeader - Gets the header text of a group by group ID
; ======================================================================================================================
LV_EX_GroupGetHeader(HLV, GroupID, MaxChars := 1024) {
   ; LVM_GETGROUPINFO = 0x1095
	Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
	Static LVGF_HEADER := 0x00000001
	Static OffHeader := 8
	Static OffHeaderMax := 8 + A_PtrSize
	VarSetCapacity(HeaderText, MaxChars * 2, 0)
	VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
	NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
	NumPut(LVGF_HEADER, LVGROUP, 4, "UInt")
	NumPut(&HeaderText, LVGROUP, OffHeader, "Ptr")
	NumPut(MaxChars, LVGROUP, OffHeaderMax, "Int")
	SendMessage, 0x1095, %GroupID%, % &LVGROUP, , % "ahk_id " . HLV
	Return StrGet(&HeaderText, MaxChars, "UTF-16")
}
; ======================================================================================================================
; LV_EX_GroupGetState - Get group states (requires Win Vista+ for most states).
; ======================================================================================================================
LV_EX_GroupGetState(HLV, GroupID, ByRef Collapsed := "", ByRef Collapsible := "", ByRef Focused := "", ByRef Hidden := ""
                  , ByRef NoHeader := "", ByRef Normal := "", ByRef Selected := "") {
   ; LVM_GETGROUPINFO = 0x1095 -> msdn.microsoft.com/en-us/library/bb774932(v=vs.85).aspx
Static OS := DllCall("GetVersion", "UChar")
Static LVGS5 := {Collapsed: 0x01, Hidden: 0x02, Normal: 0x00}
Static LVGS6 := {Collapsed: 0x01, Collapsible: 0x08, Focused: 0x10, Hidden: 0x02, NoHeader: 0x04, Normal: 0x00, Selected: 0x20}
Static LVGF := 0x04 ; LVGF_STATE
Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
Static OffStateMask := 8 + (A_PtrSize * 3) + 8
Static OffState := OffStateMask + 4
SetStates := 0
LVGS := OS > 5 ? LVGS6 : LVGS5
For Each, State In LVGS
	SetStates |= State
VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
NumPut(LVGF, LVGROUP, 4, "UInt")
NumPut(SetStates, LVGROUP, OffStateMask, "UInt")
SendMessage, 0x1095, %GroupID%, &LVGROUP, , % "ahk_id " . HLV
States := NumGet(&LVGROUP, OffState, "UInt")
For Each, State in LVGS
	%Each% := States & State ? True : False
Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_GroupInsert - Inserts a group into a list-view control.
; ======================================================================================================================
LV_EX_GroupInsert(HLV, GroupID, Header, Align := "", Index := -1) {
   ; LVM_INSERTGROUP = 0x1091 -> msdn.microsoft.com/en-us/library/bb761103(v=vs.85).aspx
	Static Alignment := {1: 1, 2: 2, 4: 4, C: 2, L: 1, R: 4}
	Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
	Static OffHeader := 8
	Static OffGroupID := OffHeader + (A_PtrSize * 3) + 4
	Static OffAlign := OffGroupID + 12
	Static LVGF := 0x11 ; LVGF_GROUPID | LVGF_HEADER | LVGF_STATE
	Static LVGF_ALIGN := 0x00000008
	Align := (A := Alignment[SubStr(Align, 1, 1)]) ? A : 0
	Mask := LVGF | (Align ? LVGF_ALIGN : 0)
	PHeader := A_IsUnicode ? &Header : LV_EX_PWSTR(Header, WHeader)
	VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
	NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
	NumPut(Mask, LVGROUP, 4, "UInt")
	NumPut(PHeader, LVGROUP, OffHeader, "Ptr")
	NumPut(GroupID, LVGROUP, OffGroupID, "Int")
	NumPut(Align, LVGROUP, OffAlign, "UInt")
	SendMessage, 0x1091, %Index%, % &LVGROUP, , % "ahk_id " . HLV
	Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_GroupRemove - Removes a group from a list-view control.
; ======================================================================================================================
LV_EX_GroupRemove(HLV, GroupID) {
   ; LVM_REMOVEGROUP = 0x1096 -> msdn.microsoft.com/en-us/library/bb761149(v=vs.85).aspx
	SendMessage, 0x10A0, %GroupID%, 0, , % "ahk_id " . HLV
	Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_GroupRemoveAll - Removes all groups from a list-view control.
; ======================================================================================================================
LV_EX_GroupRemoveAll(HLV) {
   ; LVM_REMOVEALLGROUPS = 0x10A0 -> msdn.microsoft.com/en-us/library/bb761147(v=vs.85).aspx
	SendMessage, 0x10A0, 0, 0, , % "ahk_id " . HLV
	Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_GroupSetState - Set group state (requires Win Vista+ for most states).
; ======================================================================================================================
LV_EX_GroupSetState(HLV, GroupID, States*) {
   ; LVM_SETGROUPINFO = 0x1093 -> msdn.microsoft.com/en-us/library/bb761167(v=vs.85).aspx
	Static OS := DllCall("GetVersion", "UChar")
	Static LVGS5 := {Collapsed: 0x01, Hidden: 0x02, Normal: 0x00, 0: 0, 1: 1, 2: 2}
	Static LVGS6 := {Collapsed: 0x01, Collapsible: 0x08, Focused: 0x10, Hidden: 0x02, NoHeader: 0x04, Normal: 0x00
                 , Selected: 0x20, 0: 0, 1: 1, 2: 2, 4: 4, 8: 8, 16: 16, 32: 32}
	Static LVGF := 0x04 ; LVGF_STATE
	Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
	Static OffStateMask := 8 + (A_PtrSize * 3) + 8
	Static OffState := OffStateMask + 4
	SetStates := 0
	LVGS := OS > 5 ? LVGS6 : LVGS5
	For Each, State In States {
		If !LVGS.HasKey(State)
			Return False
		SetStates |= LVGS[State]
	}
	VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
	NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
	NumPut(LVGF, LVGROUP, 4, "UInt")
	NumPut(SetStates, LVGROUP, OffStateMask, "UInt")
	NumPut(SetStates, LVGROUP, OffState, "UInt")
	SendMessage, 0x1093, %GroupID%, % &LVGROUP, , % "ahk_id " . HLV
	Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_HasGroup - Determines whether the list-view control has a specified group.
; ======================================================================================================================
LV_EX_HasGroup(HLV, GroupID) {
   ; LVM_HASGROUP = 0x10A1 -> msdn.microsoft.com/en-us/library/bb761097(v=vs.85).aspx
	SendMessage, 0x10A1, %GroupID%, 0, , % "ahk_id " . HLV
	Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_IsGroupViewEnabled - Checks whether the list-view control has group view enabled.
; ======================================================================================================================
LV_EX_IsGroupViewEnabled(HLV) {
   ; LVM_ISGROUPVIEWENABLED = 0x10AF -> msdn.microsoft.com/en-us/library/bb761133(v=vs.85).aspx
	SendMessage, 0x10AF, 0, 0, , % "ahk_id " . HLV
	Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_RedrawRows - Forces a list-view control to redraw a range of items.
; ======================================================================================================================
LV_EX_RedrawRows(HLV, First := 0, Last := "") {
   ; LVM_REDRAWITEMS = 0x1015 -> http://msdn.microsoft.com/en-us/library/bb761145(v=vs.85).aspx
	If (First > 0) {
		If (Last = "")
			Last := First
	}
	Else {
		First := LV_EX_GetTopIndex(HLV)
		Last := First + LV_EX_GetRowsPerPage(HLV) - 1
	}
	SendMessage, 0x1015, % (First - 1), % (Last - 1), , % "ahk_id " . HLV
	If (ErrorLevel)
		Return DllCall("User32.dll\UpdateWindow", "Ptr", HLV, "UInt")
	Return False
}

; ======================================================================================================================
; LV_EX_GetRowsPerPage - Calculates the number of items that can fit vertically in the visible area of a list-view
;                        control when in list or report view. Only fully visible items are counted.
; ======================================================================================================================
LV_EX_GetRowsPerPage(HLV) {
   ; LVM_GETCOUNTPERPAGE = 0x1028 -> http://msdn.microsoft.com/en-us/library/bb774917(v=vs.85).aspx
	SendMessage, 0x1028, 0, 0, , % "ahk_id " . HLV
	Return ErrorLevel
}

; ======================================================================================================================
; LV_EX_GetTopIndex - Retrieves the index of the topmost visible item when in list or report view.
; ======================================================================================================================
LV_EX_GetTopIndex(HLV) {
   ; LVM_GETTOPINDEX = 0x1027 -> http://msdn.microsoft.com/en-us/library/bb761087(v=vs.85).aspx
	SendMessage, 0x1027, 0, 0, , % "ahk_id " . HLV
	Return (ErrorLevel + 1)
}

; ======================================================================================================================
; LV_EX_SetGroup - Assigns a list-view item to an existing group.
; ======================================================================================================================
LV_EX_SetGroup(HLV, Row, GroupID) {
   ; LVM_SETITEMA = 0x1006 -> http://msdn.microsoft.com/en-us/library/bb761186(v=vs.85).aspx
	Static OffGroupID := 28 + (A_PtrSize * 3)
	LV_EX_LVITEM(LVITEM, 0x00000100, Row) ; LVIF_GROUPID
	NumPut(GroupID, LVITEM, OffGroupID, "UPtr")
	SendMessage, 0x1006, 0, % &LVITEM, , % "ahk_id " . HLV
	Return ErrorLevel
}

; ======================================================================================================================
; ======================================================================================================================
; Function for internal use ============================================================================================
; ======================================================================================================================
; ======================================================================================================================
LV_EX_LVITEM(ByRef LVITEM, Mask := 0, Row := 1, Col := 1) {
	Static LVITEMSize := 48 + (A_PtrSize * 3)
	VarSetCapacity(LVITEM, LVITEMSize, 0)
	NumPut(Mask, LVITEM, 0, "UInt"), NumPut(Row - 1, LVITEM, 4, "Int"), NumPut(Col - 1, LVITEM, 8, "Int")
}
; ----------------------------------------------------------------------------------------------------------------------
LV_EX_PWSTR(Str, ByRef WSTR) { ; ANSI to Unicode
	VarSetCapacity(WSTR, StrPut(Str, "UTF-16") * 2, 0)
	StrPut(Str, &WSTR, "UTF-16")
	Return &WSTR
}

ACC Lib by jethrew required

Code: Select all

;------------------------------------------------------------------------------
; Acc.ahk Standard Library
; by Sean
; Updated by jethrow:
; 	Modified ComObjEnwrap params from (9,pacc) --> (9,pacc,1)
; 	Changed ComObjUnwrap to ComObjValue in order to avoid AddRef (thanks fincs)
; 	Added Acc_GetRoleText & Acc_GetStateText
; 	Added additional functions - commented below
; 	Removed original Acc_Children function
;	Added Acc_Error, Acc_ChildrenByRole, & Acc_Get functions
; last updated 10/25/2012
;------------------------------------------------------------------------------

Acc_Init()
{
	Static	h
	If Not	h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromEvent(ByRef _idChild_, hWnd, idObject, idChild)
{
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromEvent", "Ptr", hWnd, "UInt", idObject, "UInt", idChild, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return	ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "")
{
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return	ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

Acc_ObjectFromWindow(hWnd, idObject = 0)
{
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
	Return	ComObjEnwrap(9,pacc,1)
}

Acc_WindowFromObject(pacc)
{
	If	DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc)?ComObjValue(pacc):pacc, "Ptr*", hWnd)=0
	Return	hWnd
}

Acc_GetRoleText(nRole)
{
	nSize := DllCall("oleacc\GetRoleText", "Uint", nRole, "Ptr", 0, "Uint", 0)
	VarSetCapacity(sRole, (A_IsUnicode?2:1)*nSize)
	DllCall("oleacc\GetRoleText", "Uint", nRole, "str", sRole, "Uint", nSize+1)
	Return	sRole
}

Acc_GetStateText(nState)
{
	nSize := DllCall("oleacc\GetStateText", "Uint", nState, "Ptr", 0, "Uint", 0)
	VarSetCapacity(sState, (A_IsUnicode?2:1)*nSize)
	DllCall("oleacc\GetStateText", "Uint", nState, "str", sState, "Uint", nSize+1)
	Return	sState
}

Acc_SetWinEventHook(eventMin, eventMax, pCallback)
{
	Return	DllCall("SetWinEventHook", "Uint", eventMin, "Uint", eventMax, "Uint", 0, "Ptr", pCallback, "Uint", 0, "Uint", 0, "Uint", 0)
}

Acc_UnhookWinEvent(hHook)
{
	Return	DllCall("UnhookWinEvent", "Ptr", hHook)
}
/*	Win Events:

	pCallback := RegisterCallback("WinEventProc")
	WinEventProc(hHook, event, hWnd, idObject, idChild, eventThread, eventTime)
	{
		Critical
		Acc := Acc_ObjectFromEvent(_idChild_, hWnd, idObject, idChild)
		; Code Here:

	}
*/

; Written by jethrow
Acc_Role(Acc, ChildId=0) {
	try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetRoleText(Acc.accRole(ChildId)):"invalid object"
}
Acc_State(Acc, ChildId=0) {
	try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetStateText(Acc.accState(ChildId)):"invalid object"
}
Acc_Location(Acc, ChildId=0, byref Position="") { ; adapted from Sean's code
	try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
	catch
		return
	Position := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
	return	{x:NumGet(x,0,"int"), y:NumGet(y,0,"int"), w:NumGet(w,0,"int"), h:NumGet(h,0,"int")}
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Child(Acc, ChildId=0) {
	try child:=Acc.accChild(ChildId)
	return child?Acc_Query(child):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Acc_Error(p="") {
	static setting:=0
	return p=""?setting:setting:=p
}
Acc_Children(Acc) {
	if ComObjType(Acc,"Name") != "IAccessible"
		ErrorLevel := "Invalid IAccessible Object"
	else {
		Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
		if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
			Loop %cChildren%
				i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
			return Children.MaxIndex()?Children:
		} else
			ErrorLevel := "AccessibleChildren DllCall Failed"
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}
Acc_ChildrenByRole(Acc, Role) {
	if ComObjType(Acc,"Name")!="IAccessible"
		ErrorLevel := "Invalid IAccessible Object"
	else {
		Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
		if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
			Loop %cChildren% {
				i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i)
				if NumGet(varChildren,i-8)=9
					AccChild:=Acc_Query(child), ObjRelease(child), Acc_Role(AccChild)=Role?Children.Insert(AccChild):
				else
					Acc_Role(Acc, child)=Role?Children.Insert(child):
			}
			return Children.MaxIndex()?Children:, ErrorLevel:=0
		} else
			ErrorLevel := "AccessibleChildren DllCall Failed"
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}
Acc_Get(Cmd, ChildPath="", ChildID=0, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="") {
	static properties := {Action:"DefaultAction", DoAction:"DoDefaultAction", Keyboard:"KeyboardShortcut"}
	AccObj :=   IsObject(WinTitle)? WinTitle
			:   Acc_ObjectFromWindow( WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText), 0 )
	if ComObjType(AccObj, "Name") != "IAccessible"
		ErrorLevel := "Could not access an IAccessible Object"
	else {
		StringReplace, ChildPath, ChildPath, _, %A_Space%, All
		AccError:=Acc_Error(), Acc_Error(true)
		Loop Parse, ChildPath, ., %A_Space%
			try {
				if A_LoopField is digit
					Children:=Acc_Children(AccObj), m2:=A_LoopField ; mimic "m2" output in else-statement
				else
					RegExMatch(A_LoopField, "(\D*)(\d*)", m), Children:=Acc_ChildrenByRole(AccObj, m1), m2:=(m2?m2:1)
				if Not Children.HasKey(m2)
					throw
				AccObj := Children[m2]
			} catch {
				ErrorLevel:="Cannot access ChildPath Item #" A_Index " -> " A_LoopField, Acc_Error(AccError)
				if Acc_Error()
					throw Exception("Cannot access ChildPath Item", -1, "Item #" A_Index " -> " A_LoopField)
				return
			}
		Acc_Error(AccError)
		StringReplace, Cmd, Cmd, %A_Space%, , All
		properties.HasKey(Cmd)? Cmd:=properties[Cmd]:
		try {
			if (Cmd = "Location")
				AccObj.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
			  , ret_val := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
			else if (Cmd = "Object")
				ret_val := AccObj
			else if Cmd in Role,State
				ret_val := Acc_%Cmd%(AccObj, ChildID+0)
			else if Cmd in ChildCount,Selection,Focus
				ret_val := AccObj["acc" Cmd]
			else
				ret_val := AccObj["acc" Cmd](ChildID+0)
		} catch {
			ErrorLevel := """" Cmd """ Cmd Not Implemented"
			if Acc_Error()
				throw Exception("Cmd Not Implemented", -1, Cmd)
			return
		}
		return ret_val, ErrorLevel:=0
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}
So - not 100% where to take it from here, what functionality to add and so on...maybe you guys will have some suggestiosn or improvements! so let me know what you think!

Thanks!

-Treas
HrGwe
Posts: 4
Joined: 01 Dec 2016, 04:55

Re: Window Activate/Browser Tab Activate

03 Dec 2016, 10:35

Can you get more than just the tab titles? For example the tab's icon and URL?
Treashunter

Re: Window Activate/Browser Tab Activate

04 Dec 2016, 18:11

Getting URL is doable. Icons are a bit more complicated - I looked into it, but this was just something i decided to do on a whim, havent worked too much more on it at this point. You just need to access that urls favicon.ico file i believe, then download it locally and use an imagelist with the listviews.
drdutw
Posts: 5
Joined: 23 Oct 2013, 12:20

Re: Window Activate/Browser Tab Activate

06 Dec 2016, 00:24

Thank you so much! This is very useful!

BTW, how do you get the path to the interested properties, like the "4.1.2.2.2" below:
Acc_Get("Object", "4.1.2.2.2", 0, "ahk_id" chrome.get("hWnd"))
Tre4shunter
Posts: 36
Joined: 26 Jan 2016, 16:05

Re: Window Activate/Browser Tab Activate

06 Dec 2016, 08:12

Using ACCViewer by Jethrew. Ill post below because it took me forever and a day to find it. alot of the links on the forums for it are broke afaik.

Thanks! Glad you found it useful!

Code: Select all

; Accessible Info Viewer
; http://www.autohotkey.com/board/topic/77888-accessible-info-viewer-alpha-release-2012-09-20/
; https://dl.dropbox.com/u/47573473/Accessible%20Info%20Viewer/AccViewer%20Source.ahk
{
	WM_ACTIVATE := 0x06
	WM_KILLFOCUS := 0x08
	WM_LBUTTONDOWN := 0x201
	WM_LBUTTONUP := 0x202
	global	Border := new Outline, Stored:={}, Acc, ChildId, TVobj, Win:={}
}
{
	DetectHiddenWindows, On
	OnExit, OnExitCleanup
	OnMessage(0x200,"WM_MOUSEMOVE")
	ComObjError(false)
	Hotkey, ~LButton Up, Off
}
{
	Gui Main: New, HWNDhwnd LabelGui AlwaysOnTop, Accessible Info Viewer
	Gui Main: Default
	Win.Main := hwnd
	Gui, Add, Button, x160 y8 w105 h20 vShowStructure gShowStructure, Show Acc Structure
	{
		Gui, Add, Text, x10 y3 w25 h26 Border gCrossHair ReadOnly HWNDh8 Border
		CColor(h8, "White")
		Gui, Add, Text, x10 y3 w25 h4 HWNDh9 Border
		CColor(h9, "0046D5")
		Gui, Add, Text, x13 y17 w19 h1 Border vHBar
		Gui, Add, Text, x22 y8 w1 h19 Border vVBar
	}
	{
		Gui, Font, bold
		Gui, Add, GroupBox, x2 y32 w275 h130 vWinCtrl, Window/Control Info
		Gui, Font
		Gui, Add, Text, x7 y49 w42 h20 Right, WinTitle:
		Gui, Add, Edit, x51 y47 w221 h20 vWinTitle ,
		Gui, Add, Text, x7 y71 w42 h20 Right, Text:
		Gui, Add, Edit, x51 y69 w221 h20 vText ,
		Gui, Add, Text, x7 y93 w42 h20 Right, Hwnd:
		Gui, Add, Edit, x51 y91 w72 h20 vHwnd,
		Gui, Add, Text, x126 y93 w51 h20 vClassText Right, Class(NN):
		Gui, Add, Edit, x178 y91 w94 h20 vClass,
		Gui, Add, Text, x7 y115 w42 h20 Right, Position:
		Gui, Add, Edit, x51 y113 w72 h20 vPosition,
		Gui, Add, Text, x126 y115 w51 h20 Right, Process:
		Gui, Add, Edit, x178 y113 w94 h20 vProcess,
		Gui, Add, Text, x7 y137 w42 h20 Right, Size:
		Gui, Add, Edit, x51 y135 w72 h20 vSize,
		Gui, Add, Text, x126 y137 w51 h20 Right, Proc ID:
		Gui, Add, Edit, x178 y135 w94 h20 vProcID,
	}
	{
		Gui, Font, bold
		Gui, Add, GroupBox, x2 y165 w275 h240 vAcc, Accessible Info
		Gui, Font
		Gui, Add, Text, x7 y182 w42 h20 Right, Name:
		Gui, Add, Edit, x51 y180 w221 h20 vAccName ,
		Gui, Add, Text, x7 y204 w42 h20 Right, Value:
		Gui, Add, Edit, x51 y202 w221 h20 vAccValue ,
		Gui, Add, Text, x7 y226 w42 h20 Right, Role:
		Gui, Add, Edit, x51 y224 w72 h20 vAccRole,
		Gui, Add, Text, x126 y226 w55 h20 Right, ChildCount:
		Gui, Add, Edit, x182 y224 w90 h20 vAccChildCount,
		Gui, Add, Text, x7 y248 w42 h20 Right, State:
		Gui, Add, Edit, x51 y246 w72 h20 vAccState,
		Gui, Add, Text, x126 y248 w55 h20 Right, Selection:
		Gui, Add, Edit, x182 y246 w90 h20 vAccSelection,
		Gui, Add, Text, x7 y270 w42 h20 Right, Action:
		Gui, Add, Edit, x51 y268 w72 h20 vAccAction,
		Gui, Add, Text, x126 y270 w55 h20 Right, Focus:
		Gui, Add, Edit, x182 y268 w90 h20 vAccFocus,
		{
			Gui, Add, Text, x7 y292 w55 h20 Right vAccLocationText, Location:
			Gui, Add, Edit, x65 y290 w207 h20 vAccLocation ,
			Gui, Add, Text, x7 y314 w55 h20 Right, Description:
			Gui, Add, Edit, x65 y312 w207 h20 vAccDescription ,
			Gui, Add, Text, x7 y336 w55 h20 Right, Keyboard:
			Gui, Add, Edit, x65 y334 w207 h20 vAccKeyboard ,
			Gui, Add, Text, x7 y358 w55 h20 Right, Help:
			Gui, Add, Edit, x65 y356 w207 h20 vAccHelp ,
			Gui, Add, Text, x7 y380 w55 h20 Right, HelpTopic:
			Gui, Add, Edit, x65 y378 w207 h20 vAccHelpTopic ,
		}
	}
	{
		Gui, Add, StatusBar, gShowMainGui
		SB_SetParts(70,150)
		SB_SetText("`tshow more", 3)
	}
	{
		Gui Acc: New, ToolWindow AlwaysOnTop Resize LabelAcc HWNDhwnd, Acc Structure
		Win.Acc := hwnd
		Gui Acc: Add, TreeView, w200 h300 vTView gTreeView R17 AltSubmit
		Gui Acc: Show, Hide
	}
	GoSub, ShowMainGui
	WinSet, Redraw, , % "ahk_id" Win.Main
	return
}
ShowMainGui:
{
	if A_EventInfo in 1,2
	{
		WM_MOUSEMOVE()
		StatusBarGetText, SB_Text, %A_EventInfo%, % "ahk_id" Win.Main
		if SB_Text
			if (A_EventInfo=2 and SB_Text:=SubStr(SB_Text,7))
			or if RegExMatch(SB_Text, "Id: \K\d+", SB_Text)
			{
				ToolTip % "clipboard = " clipboard:=SB_Text
				SetTimer, RemoveToolTip, -2000
			}
	}
	else {
		Gui Main: Default
		if ShowingLess {
			SB_SetText("`tshow less", 3)
			GuiControl, Move, Acc, x2 y165 w275 h240
			GuiControl, Show, AccDescription
			GuiControl, Show, AccLocation
			GuiControl, Show, AccLocationText
			{
				height := 319
				while height<428 {
					height += 10
					Gui, Show, w280 h%height%
					Sleep, 20
				}
			}
			Gui, Show, w280 h428
			ShowingLess := false
		}
		else {
			if (ShowingLess != "") {
				height := 428
				while height>319 {
					height -= 10
					Gui, Show, w280 h%height%
					Sleep, 20
				}
			}
			Gui, Show, w280 h319
			GuiControl, Hide, AccDescription
			GuiControl, Hide, AccLocation
			GuiControl, Hide, AccLocationText
			GuiControl, Move, Acc, x2 y165 w275 h130
			SB_SetText("`tshow more", 3)
			ShowingLess := true
		}
		WinSet, Redraw, , % "ahk_id" Win.Main
	}
return
}

#if Not Lbutton_Pressed
^/::
{
	SetBatchLines, -1
	Lbutton_Pressed := true
	Stored.Chwnd := ""
	Gui Acc: Default
	GuiControl, Disable, TView
	while, Lbutton_Pressed
	GetAccInfo()
	SetBatchLines, 10ms
	return
}
#if Lbutton_Pressed
^/::
{
	Lbutton_Pressed := false
	Gui Main: Default
	Sleep, -1
	GuiControl, , WinCtrl, % (DllCall("GetParent", Uint,Acc_WindowFromObject(Acc))? "Control":"Window") " Info"
	if Not DllCall("IsWindowVisible", "Ptr",Win.Acc) {
		Border.Hide()
		SB_SetText("Path: " GetAccPath(Acc).path, 2)
	}
	else {
		Gui Acc: Default
		BuildTreeView()
		GuiControl, Enable, TView
		WinActivate, % "ahk_id" Win.Acc
		PostMessage, %WM_LBUTTONDOWN%, , , SysTreeView321, % "ahk_id" Win.Acc
	}
	return
}
#if
~Lbutton Up::
{
	Hotkey, ~LButton Up, Off
	Lbutton_Pressed := False
	Gui Main: Default
	if Not CH {
		GuiControl, Show, HBar
		GuiControl, Show, VBar
		CrossHair(CH:=true)
	}
	Sleep, -1
	GuiControl, , WinCtrl, % (DllCall("GetParent", Uint,Acc_WindowFromObject(Acc))? "Control":"Window") " Info"
	if Not DllCall("IsWindowVisible", "Ptr",Win.Acc) {
		Border.Hide()
		SB_SetText("Path: " GetAccPath(Acc).path, 2)
	}
	else {
		Gui Acc: Default
		BuildTreeView()
		GuiControl, Enable, TView
		WinActivate, % "ahk_id" Win.Acc
		PostMessage, %WM_LBUTTONDOWN%, , , SysTreeView321, % "ahk_id" Win.Acc
	}
	return
}
CrossHair:
{
	if (A_GuiEvent = "Normal") {
		SetBatchLines, -1
		Hotkey, ~LButton Up, On
		{
			GuiControl, Hide, HBar
			GuiControl, Hide, VBar
			CrossHair(CH:=false)
		}
		Lbutton_Pressed := True
		Stored.Chwnd := ""
		Gui Acc: Default
		GuiControl, Disable, TView
		while, Lbutton_Pressed
			GetAccInfo()
		SetBatchLines, 10ms
	}
	return
}
OnExitCleanup:
{
	CrossHair(true)
	GuiClose:
	ExitApp
}
ShowStructure:
{
	ControlFocus, Static1, % "ahk_id" Win.Main
	if DllCall("IsWindowVisible", "Ptr",Win.Acc) {
		PostMessage, %WM_LBUTTONDOWN%, , , SysTreeView321, % "ahk_id" Win.Acc
		return
	}
	WinGetPos, x, y, w, , % "ahk_id" Win.Main
	WinGetPos, , , AccW, AccH, % "ahk_id" Win.Acc
	WinMove, % "ahk_id" Win.Acc,
		, (x+w+AccW > A_ScreenWidth? x-AccW-10:x+w+10)
		, % y+5, %AccW%, %AccH%
	WinShow, % "ahk_id" Win.Acc
	if ComObjType(Acc, "Name") = "IAccessible"
		BuildTreeView()
	if Lbutton_Pressed
		GuiControl, Disable, TView
	else
		GuiControl, Enable, TView
	PostMessage, %WM_LBUTTONDOWN%, , , SysTreeView321, % "ahk_id" Win.Acc
	return
}
BuildTreeView()
{
	r := GetAccPath(Acc)
	AccObj:=r.AccObj, Child_Path:=r.Path, r:=""
	Gui Acc: Default
	TV_Delete()
	GuiControl, -Redraw, TView
	parent := TV_Add(Acc_Role(AccObj), "", "Bold Expand")
	TVobj := {(parent): {is_obj:true, obj:AccObj, need_children:false, childid:0, Children:[]}}
	Loop Parse, Child_Path, .
	{
		if A_LoopField is not Digit
			TVobj[parent].Obj_Path := Trim(TVobj[parent].Obj_Path "," A_LoopField, ",")
		else {
			StoreParent := parent
			parent := TV_BuildAccChildren(AccObj, parent, "", A_LoopField)
			TVobj[parent].need_children := false
			TV_Expanded(StoreParent)
			TV_Modify(parent,"Expand")
			AccObj := TVobj[parent].obj
		}
	}
	if Not ChildId {
		TV_BuildAccChildren(AccObj, parent)
		TV_Modify(parent, "Select")
	}
	else
		TV_BuildAccChildren(AccObj, parent, ChildId)
	TV_Expanded(parent)
	GuiControl, +Redraw, TView
}
AccClose:
{
	Border.Hide()
	Gui Acc: Hide
	TV_Delete()
	Gui Main: Default
	GuiControl, Enable, ShowStructure
	return
}
AccSize:
{
	Anchor(TView, "wh")
	return
}
TreeView:
{
	Gui, Submit, NoHide
	if (A_GuiEvent = "S")
		UpdateAccInfo(TVobj[A_EventInfo].obj, TVobj[A_EventInfo].childid, TVobj[A_EventInfo].obj_path)
	if (A_GuiEvent = "+") {
		GuiControl, -Redraw, TView
		TV_Expanded(A_EventInfo)
		GuiControl, +Redraw, TView
	}
	return
}
RemoveToolTip:
{
	ToolTip
	return
}
GetAccInfo() {
	global Whwnd
	static ShowButtonEnabled
	MouseGetPos, , , Whwnd
	if (Whwnd!=Win.Main and Whwnd!=Win.Acc) {
		{
			GuiControlGet, SectionLabel, , WinCtrl
			if (SectionLabel != "Window/Control Info")
				GuiControl, , WinCtrl, Window/Control Info
		}
		Acc := Acc_ObjectFromPoint(ChildId)
		Location := GetAccLocation(Acc, ChildId)
		if Stored.Location != Location {
			Hwnd := Acc_WindowFromObject(Acc)
			if Stored.Hwnd != Hwnd {
				if DllCall("GetParent", Uint,hwnd) {
					WinGetTitle, title, ahk_id %parent%
					ControlGetText, text, , ahk_id %Hwnd%
					class := GetClassNN(Hwnd,Whwnd)
					ControlGetPos, posX, posY, posW, posH, , ahk_id %Hwnd%
					WinGet, proc, ProcessName, ahk_id %parent%
					WinGet, procid, PID, ahk_id %parent%
				}
				else {
					WinGetTitle, title, ahk_id %Hwnd%
					WinGetText, text, ahk_id %Hwnd%
					WinGetClass, class, ahk_id %Hwnd%
					WinGetPos, posX, posY, posW, posH, ahk_id %Hwnd%
					WinGet, proc, ProcessName, ahk_id %Hwnd%
					WinGet, procid, PID, ahk_id %Hwnd%
				}
				{
					GuiControl, , WinTitle, %title%
					GuiControl, , Text, %text%
					SetFormat, IntegerFast, H
					GuiControl, , Hwnd, % Hwnd+0
					SetFormat, IntegerFast, D
					GuiControl, , Class, %class%
					GuiControl, , Position, x%posX%  y%posY%
					GuiControl, , Size, w%posW%  h%posH%
					GuiControl, , Process, %proc%
					GuiControl, , ProcId, %procid%
				}
				Stored.Hwnd := Hwnd
			}
			UpdateAccInfo(Acc, ChildId)
		}
	}
}
UpdateAccInfo(Acc, ChildId, Obj_Path="") {
	global Whwnd
	Gui Main: Default
	Location := GetAccLocation(Acc, ChildId, x,y,w,h)
	{
		GuiControl, , AccName, % Acc.accName(ChildId)
		GuiControl, , AccValue, % Acc.accValue(ChildId)
		GuiControl, , AccRole, % Acc_GetRoleText(Acc.accRole(ChildId))
		GuiControl, , AccState, % Acc_GetStateText(Acc.accState(ChildId))
		GuiControl, , AccAction, % Acc.accDefaultAction(ChildId)
		GuiControl, , AccChildCount, % ChildId? "N/A":Acc.accChildCount
		GuiControl, , AccSelection, % ChildId? "N/A":Acc.accSelection
		GuiControl, , AccFocus, % ChildId? "N/A":Acc.accFocus
		GuiControl, , AccLocation, %Location%
		GuiControl, , AccDescription, % Acc.accDescription(ChildId)
		GuiControl, , AccKeyboard, % Acc.accKeyboardShortCut(ChildId)
		Guicontrol, , AccHelp, % Acc.accHelp(ChildId)
		GuiControl, , AccHelpTopic, % Acc.accHelpTopic(ChildId)
		SB_SetText(ChildId? "Child Id: " ChildId:"Object")
		SB_SetText(DllCall("IsWindowVisible", "Ptr",Win.Acc)? "Path: " Obj_Path:"", 2)
	}
	Border.Transparent(true)
	Border.show(x,y,x+w,y+h)
	Border.setabove(Whwnd)
	Border.Transparent(false)
	Stored.Location := Location
}
GetClassNN(Chwnd, Whwnd) {
	global _GetClassNN := {}
	_GetClassNN.Hwnd := Chwnd
	Detect := A_DetectHiddenWindows
	WinGetClass, Class, ahk_id %Chwnd%
	_GetClassNN.Class := Class
	DetectHiddenWindows, On
	EnumAddress := RegisterCallback("GetClassNN_EnumChildProc")
	DllCall("EnumChildWindows", "uint",Whwnd, "uint",EnumAddress)
	DetectHiddenWindows, %Detect%
	return, _GetClassNN.ClassNN, _GetClassNN:=""
}
GetClassNN_EnumChildProc(hwnd, lparam) {
	static Occurrence
	global _GetClassNN
	WinGetClass, Class, ahk_id %hwnd%
	if _GetClassNN.Class == Class
		Occurrence++
	if Not _GetClassNN.Hwnd == hwnd
		return true
	else {
		_GetClassNN.ClassNN := _GetClassNN.Class Occurrence
		Occurrence := 0
		return false
	}
}
TV_Expanded(TVid) {
	For Each, TV_Child_ID in TVobj[TVid].Children
		if TVobj[TV_Child_ID].need_children
			TV_BuildAccChildren(TVobj[TV_Child_ID].obj, TV_Child_ID)
}
TV_BuildAccChildren(AccObj, Parent, Selected_Child="", Flag="") {
	TVobj[Parent].need_children := false
	Parent_Obj_Path := Trim(TVobj[Parent].Obj_Path, ",")
	for wach, child in Acc_Children(AccObj) {
		if Not IsObject(child) {
			added := TV_Add("[" A_Index "] " Acc_GetRoleText(AccObj.accRole(child)), Parent)
			TVobj[added] := {is_obj:false, obj:Acc, childid:child, Obj_Path:Parent_Obj_Path}
			if (child = Selected_Child)
				TV_Modify(added, "Select")
		}
		else {
			added := TV_Add("[" A_Index "] " Acc_Role(child), Parent, "bold")
			TVobj[added] := {is_obj:true, need_children:true, obj:child, childid:0, Children:[], Obj_Path:Trim(Parent_Obj_Path "," A_Index, ",")}
		}
		TVobj[Parent].Children.Insert(added)
		if (A_Index = Flag)
			Flagged_Child := added
	}
	return Flagged_Child
}
GetAccPath(Acc, byref hwnd="") {
	hwnd := Acc_WindowFromObject(Acc)
	WinObj := Acc_ObjectFromWindow(hwnd)
	WinObjPos := Acc_Location(WinObj).pos
	while Acc_WindowFromObject(Parent:=Acc_Parent(Acc)) = hwnd {
		t2 := GetEnumIndex(Acc) "." t2
		if Acc_Location(Parent).pos = WinObjPos
			return {AccObj:Parent, Path:SubStr(t2,1,-1)}
		Acc := Parent
	}
	while Acc_WindowFromObject(Parent:=Acc_Parent(WinObj)) = hwnd
		t1.="P.", WinObj:=Parent
	return {AccObj:Acc, Path:t1 SubStr(t2,1,-1)}
}
GetEnumIndex(Acc, ChildId=0) {
	if Not ChildId {
		ChildPos := Acc_Location(Acc).pos
		For Each, child in Acc_Children(Acc_Parent(Acc))
			if IsObject(child) and Acc_Location(child).pos=ChildPos
				return A_Index
	} 
	else {
		ChildPos := Acc_Location(Acc,ChildId).pos
		For Each, child in Acc_Children(Acc)
			if Not IsObject(child) and Acc_Location(Acc,child).pos=ChildPos
				return A_Index
	}
}
GetAccLocation(AccObj, Child=0, byref x="", byref y="", byref w="", byref h="") {
	AccObj.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), Child)
	return	"x" (x:=NumGet(x,0,"int")) "  "
	.	"y" (y:=NumGet(y,0,"int")) "  "
	.	"w" (w:=NumGet(w,0,"int")) "  "
	.	"h" (h:=NumGet(h,0,"int"))
}
WM_MOUSEMOVE() {
	static hCurs := new Cursor(32649)
	MouseGetPos,,,,ctrl
	if (ctrl = "msctls_statusbar321")
		DllCall("SetCursor","ptr",hCurs.ptr)
}
class Cursor {
	__New(id) {
	this.ptr := DllCall("LoadCursor","UInt",NULL,"Int",id,"UInt")
}
__delete() {
DllCall("DestroyCursor","Uint",this.ptr)
}
}
class Outline {
	__New(color="red") {
		Gui, +HWNDdefault
		Loop, 4 {
			Gui, New, -Caption +ToolWindow HWNDhwnd
			Gui, Color, %color%
			this[A_Index] := hwnd
		}
		this.visible := false
		this.color := color
		this.top := this[1]
		this.right := this[2]
		this.bottom := this[3]
		this.left := this[4]
		Gui, %default%: Default
	}
	Show(x1, y1, x2, y2, sides="TRBL") {
		Gui, +HWNDdefault
		if InStr( sides, "T" )
			Gui, % this[1] ":Show", % "NA X" x1-2 " Y" y1-2 " W" x2-x1+4 " H" 2
		Else, Gui, % this[1] ":Hide"
		if InStr( sides, "R" )
			Gui, % this[2] ":Show", % "NA X" x2 " Y" y1 " W" 2 " H" y2-y1
		Else, Gui, % this[2] ":Hide"
		if InStr( sides, "B" )
			Gui, % this[3] ":Show", % "NA X" x1-2 " Y" y2 " W" x2-x1+4 " H" 2
		Else, Gui, % this[3] ":Hide"
		if InStr( sides, "L" )
			Gui, % this[4] ":Show", % "NA X" x1-2 " Y" y1 " W" 2 " H" y2-y1
		Else, Gui, % this[3] ":Hide"
		self.visible := true
		Gui, %default%: Default
	}
	Hide() {
		Gui, +HWNDdefault
		Loop, 4
			Gui, % this[A_Index] ": Hide"
		self.visible := false
		Gui, %default%: Default
	}
	SetAbove(hwnd) {
		ABOVE := DllCall("GetWindow", "uint", hwnd, "uint", 3)
		Loop, 4
			DllCall(	"SetWindowPos", "uint", this[A_Index], "uint", ABOVE
					,	"int", 0, "int", 0, "int", 0, "int", 0
					,	"uint", 0x1|0x2|0x10	)
	}
	Transparent(param) {
		Loop, 4
			WinSet, Transparent, % param=1? 0:255, % "ahk_id" this[A_Index]
		self.visible := !param
	}
	Color(color) {
		Gui, +HWNDdefault
		Loop, 4
			Gui, % this[A_Index] ": Color" , %color%
		self.color := color
		Gui, %default%: Default
	}
	Destroy() {
		Loop, 4
			Gui, % this[A_Index] ": Destroy"
	}
}
CColor(Hwnd, Background="", Foreground="") {
	return CColor_(Background, Foreground, "", Hwnd+0)
}
CColor_(Wp, Lp, Msg, Hwnd) {
	static
	static WM_CTLCOLOREDIT=0x0133, WM_CTLCOLORLISTBOX=0x134, WM_CTLCOLORSTATIC=0x0138
	,LVM_SETBKCOLOR=0x1001, LVM_SETTEXTCOLOR=0x1024, LVM_SETTEXTBKCOLOR=0x1026, TVM_SETTEXTCOLOR=0x111E, TVM_SETBKCOLOR=0x111D
	,BS_CHECKBOX=2, BS_RADIOBUTTON=8, ES_READONLY=0x800
	,CLR_NONE=-1, CSILVER=0xC0C0C0, CGRAY=0x808080, CWHITE=0xFFFFFF, CMAROON=0x80, CRED=0x0FF, CPURPLE=0x800080, CFUCHSIA=0xFF00FF,CGREEN=0x8000, CLIME=0xFF00, COLIVE=0x8080, CYELLOW=0xFFFF, CNAVY=0x800000, CBLUE=0xFF0000, CTEAL=0x808000, CAQUA=0xFFFF00
	,CLASSES := "Button,ComboBox,Edit,ListBox,Static,RICHEDIT50W,SysListView32,SysTreeView32"
	If (Msg = "") {
		if !adrSetTextColor
		adrSetTextColor   := DllCall("GetProcAddress", "uint", DllCall("GetModuleHandle", "str", "Gdi32.dll"), "str", "SetTextColor")
		,adrSetBkColor   := DllCall("GetProcAddress", "uint", DllCall("GetModuleHandle", "str", "Gdi32.dll"), "str", "SetBkColor")
		,adrSetBkMode   := DllCall("GetProcAddress", "uint", DllCall("GetModuleHandle", "str", "Gdi32.dll"), "str", "SetBkMode")
		BG := !Wp ? "" : C%Wp% != "" ? C%Wp% : "0x" SubStr(WP,5,2) SubStr(WP,3,2) SubStr(WP,1,2)
		FG := !Lp ? "" : C%Lp% != "" ? C%Lp% : "0x" SubStr(LP,5,2) SubStr(LP,3,2) SubStr(LP,1,2)
		WinGetClass, class, ahk_id %Hwnd%
		If class not in %CLASSES%
			return A_ThisFunc "> Unsupported control class: " class
		ControlGet, style, Style, , , ahk_id %Hwnd%
		if (class = "Edit") && (Style & ES_READONLY)
			class := "Static"
		if (class = "Button")
			if (style & BS_RADIOBUTTON) || (style & BS_CHECKBOX)
				class := "Static"
			else 
				return A_ThisFunc "> Unsupported control class: " class
		if (class = "ComboBox") {
			VarSetCapacity(CBBINFO, 52, 0), NumPut(52, CBBINFO), DllCall("GetComboBoxInfo", "UInt", Hwnd, "UInt", &CBBINFO)
			hwnd := NumGet(CBBINFO, 48)
			%hwnd%BG := BG, %hwnd%FG := FG, %hwnd% := BG ? DllCall("CreateSolidBrush", "UInt", BG) : -1
			IfEqual, CTLCOLORLISTBOX,,SetEnv, CTLCOLORLISTBOX, % OnMessage(WM_CTLCOLORLISTBOX, A_ThisFunc)
			If NumGet(CBBINFO,44)
				Hwnd :=  Numget(CBBINFO,44), class := "Edit"
		}
		if class in SysListView32,SysTreeView32
		{
			m := class="SysListView32" ? "LVM" : "TVM"
			SendMessage, %m%_SETBKCOLOR, ,BG, ,ahk_id %Hwnd%
			SendMessage, %m%_SETTEXTCOLOR, ,FG, ,ahk_id %Hwnd%
			SendMessage, %m%_SETTEXTBKCOLOR, ,CLR_NONE, ,ahk_id %Hwnd%
			return
		}
		if (class = "RICHEDIT50W")
			return f := "RichEdit_SetBgColor", %f%(Hwnd, -BG)
		if (!CTLCOLOR%Class%)
			CTLCOLOR%Class% := OnMessage(WM_CTLCOLOR%Class%, A_ThisFunc)
		return %Hwnd% := BG ? DllCall("CreateSolidBrush", "UInt", BG) : CLR_NONE,  %Hwnd%BG := BG,  %Hwnd%FG := FG
	}
	critical
	Hwnd := Lp + 0, hDC := Wp + 0
	If (%Hwnd%) {
		DllCall(adrSetBkMode, "uint", hDC, "int", 1)
		if (%Hwnd%FG)
			DllCall(adrSetTextColor, "UInt", hDC, "UInt", %Hwnd%FG)
		if (%Hwnd%BG)
			DllCall(adrSetBkColor, "UInt", hDC, "UInt", %Hwnd%BG)
		return (%Hwnd%)
	}
}
CrossHair(OnOff=1) {
	static AndMask, XorMask, $, h_cursor, IDC_CROSS := 32515
	,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13
	, b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13
	, h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,h12,h13
	if (OnOff = "Init" or OnOff = "I" or $ = "") {
		$ := "h"
		, VarSetCapacity( h_cursor,4444, 1 )
		, VarSetCapacity( AndMask, 32*4, 0xFF )
		, VarSetCapacity( XorMask, 32*4, 0 )
		, system_cursors := "32512,32513,32514,32515,32516,32642,32643,32644,32645,32646,32648,32649,32650"
		StringSplit c, system_cursors, `,
		Loop, %c0%
			h_cursor   := DllCall( "LoadCursor", "uint",0, "uint",c%A_Index% )
			, h%A_Index% := DllCall( "CopyImage",  "uint",h_cursor, "uint",2, "int",0, "int",0, "uint",0 )
			, b%A_Index% := DllCall("LoadCursor", "Uint", "", "Int", IDC_CROSS, "Uint")
	}
	$ := (OnOff = 0 || OnOff = "Off" || $ = "h" && (OnOff < 0 || OnOff = "Toggle" || OnOff = "T")) ? "b" : "h"
	Loop, %c0%
		h_cursor := DllCall( "CopyImage", "uint",%$%%A_Index%, "uint",2, "int",0, "int",0, "uint",0 )
		, DllCall( "SetSystemCursor", "uint",h_cursor, "uint",c%A_Index% )
}

{ ; Acc Library
	Acc_Init()
	{
		Static	h
		If Not	h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
	}
	Acc_ObjectFromEvent(ByRef _idChild_, hWnd, idObject, idChild)
	{
	Acc_Init()
		If	DllCall("oleacc\AccessibleObjectFromEvent", "Ptr", hWnd, "UInt", idObject, "UInt", idChild, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
		Return	ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
	}
	Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "")
	{
		Acc_Init()
		If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
		Return	ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
	}
	Acc_ObjectFromWindow(hWnd, idObject = 0)
	{
		Acc_Init()
		If	DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
		Return	ComObjEnwrap(9,pacc,1)
	}
	Acc_WindowFromObject(pacc)
	{
		If	DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc)?ComObjValue(pacc):pacc, "Ptr*", hWnd)=0
		Return	hWnd
	}
	Acc_GetRoleText(nRole)
	{
		nSize := DllCall("oleacc\GetRoleText", "Uint", nRole, "Ptr", 0, "Uint", 0)
		VarSetCapacity(sRole, (A_IsUnicode?2:1)*nSize)
		DllCall("oleacc\GetRoleText", "Uint", nRole, "str", sRole, "Uint", nSize+1)
		Return	sRole
	}
	Acc_GetStateText(nState)
	{
		nSize := DllCall("oleacc\GetStateText", "Uint", nState, "Ptr", 0, "Uint", 0)
		VarSetCapacity(sState, (A_IsUnicode?2:1)*nSize)
		DllCall("oleacc\GetStateText", "Uint", nState, "str", sState, "Uint", nSize+1)
		Return	sState
	}
	Acc_Role(Acc, ChildId=0)
	{
		try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetRoleText(Acc.accRole(ChildId)):"invalid object"
	}
	Acc_State(Acc, ChildId=0)
	{
		try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetStateText(Acc.accState(ChildId)):"invalid object"
	}
	Acc_Children(Acc)
	{
		if ComObjType(Acc,"Name")!="IAccessible"
			error_message := "Cause:`tInvalid IAccessible Object`n`n"
		else
		{
			Acc_Init()
			cChildren:=Acc.accChildCount, Children:=[]
			if DllCall("oleacc\AccessibleChildren", "Ptr", ComObjValue(Acc), "Int", 0, "Int", cChildren, "Ptr", VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*", cChildren)=0
			{
				Loop %cChildren%
					i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=3?child:Acc_Query(child)), ObjRelease(child)
			return Children
			}
		}
		error:=Exception("",-1)
		MsgBox, 262148, Acc_Children Failed, % (error_message?error_message:"") "File:`t" (error.file==A_ScriptFullPath?A_ScriptName:error.file) "`nLine:`t" error.line "`n`nContinue Script?"
		IfMsgBox, No
			ExitApp
	}
	Acc_Location(Acc, ChildId=0)
	{
		try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
		catch
		return
		return	{x:NumGet(x,0,"int"), y:NumGet(y,0,"int"), w:NumGet(w,0,"int"), h:NumGet(h,0,"int")
		,	pos:"x" NumGet(x,0,"int")" y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")}
	}
	Acc_Parent(Acc)
	{
		try parent:=Acc.accParent
		return parent?Acc_Query(parent):
	}
	Acc_Child(Acc, ChildId=0)
	{
		try child:=Acc.accChild(ChildId)
		return child?Acc_Query(child):
	}
	Acc_Query(Acc)
	{
		try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
	}
}

Anchor(i, a = "", r = false)
{
	static c, cs = 12, cx = 255, cl = 0, g, gs = 8, gl = 0, gpi, gw, gh, z = 0, k = 0xffff, ptr
	If z = 0
		VarSetCapacity(g, gs * 99, 0), VarSetCapacity(c, cs * cx, 0), ptr := A_PtrSize ? "Ptr" : "UInt", z := true
	If (!WinExist("ahk_id" . i))
	{
		GuiControlGet, t, Hwnd, %i%
		If ErrorLevel = 0
			i := t
		Else ControlGet, i, Hwnd, , %i%
	}
	VarSetCapacity(gi, 68, 0), DllCall("GetWindowInfo", "UInt", gp := DllCall("GetParent", "UInt", i), ptr, &gi)
	, giw := NumGet(gi, 28, "Int") - NumGet(gi, 20, "Int"), gih := NumGet(gi, 32, "Int") - NumGet(gi, 24, "Int")
	If (gp != gpi)
	{
		gpi := gp
		Loop, %gl%
			If (NumGet(g, cb := gs * (A_Index - 1)) == gp, "UInt")
			{
				gw := NumGet(g, cb + 4, "Short"), gh := NumGet(g, cb + 6, "Short"), gf := 1
				Break
			}
		If (!gf)
			NumPut(gp, g, gl, "UInt"), NumPut(gw := giw, g, gl + 4, "Short"), NumPut(gh := gih, g, gl + 6, "Short"), gl += gs
	}
	ControlGetPos, dx, dy, dw, dh, , ahk_id %i%
	Loop, %cl%
		If (NumGet(c, cb := cs * (A_Index - 1), "UInt") == i)
		{
			If a =
			{
				cf = 1
				Break
			}
			giw -= gw, gih -= gh, as := 1, dx := NumGet(c, cb + 4, "Short"), dy := NumGet(c, cb + 6, "Short")
		, cw := dw, dw := NumGet(c, cb + 8, "Short"), ch := dh, dh := NumGet(c, cb + 10, "Short")
			Loop, Parse, a, xywh
				If A_Index > 1
					av := SubStr(a, as, 1), as += 1 + StrLen(A_LoopField)
				, d%av% += (InStr("yh", av) ? gih : giw) * (A_LoopField + 0 ? A_LoopField : 1)
			DllCall("SetWindowPos", "UInt", i, "UInt", 0, "Int", dx, "Int", dy
		, "Int", InStr(a, "w") ? dw : cw, "Int", InStr(a, "h") ? dh : ch, "Int", 4)
			If r != 0
				DllCall("RedrawWindow", "UInt", i, "UInt", 0, "UInt", 0, "UInt", 0x0101)
			Return
		}
	If cf != 1
		cb := cl, cl += cs
	bx := NumGet(gi, 48, "UInt"), by := NumGet(gi, 16, "Int") - NumGet(gi, 8, "Int") - gih - NumGet(gi, 52, "UInt")
	If cf = 1
		dw -= giw - gw, dh -= gih - gh
	NumPut(i, c, cb, "UInt"), NumPut(dx - bx, c, cb + 4, "Short"), NumPut(dy - by, c, cb + 6, "Short")
	, NumPut(dw, c, cb + 8, "Short"), NumPut(dh, c, cb + 10, "Short")
	Return, true
}
drdutw
Posts: 5
Joined: 23 Oct 2013, 12:20

Re: Window Activate/Browser Tab Activate

06 Dec 2016, 12:57

This looks very cool. Thanks!
rommmcek
Posts: 489
Joined: 15 Aug 2014, 15:18

Re: Window Activate/Browser Tab Activate

28 Mar 2017, 00:36

Very good idea! Very instructive code! Made some additions:
- metro windows activation enabled (tested on Calculator & Settings [OS: Win10])
- Full screen windows (tested on Oracle VM VirtualBox) & Magnifier [OS: Win10] activation enabled
- Enter enabled as a alternative to DoubleClick
- bigger fonts & Gui, but a quarter transparent

P.s.: There is still enormous potential!
Attachments
Win-Tab Activate.ahk
(4.52 KiB) Downloaded 81 times
Tre4shunter
Posts: 36
Joined: 26 Jan 2016, 16:05

Re: Window Activate/Browser Tab Activate

28 Mar 2017, 07:53

Thanks so much for taking a look!

I wasnt really sure where to go with the code from here - as it was mostly just a proof of concept for me at the time. I might make some sort of a keyboard control scheme for it - for faster switching between windows/tabs and items etc etc.

Thanks!
rommmcek
Posts: 489
Joined: 15 Aug 2014, 15:18

Re: Window Activate/Browser Tab Activate

13 Apr 2017, 12:42

I added IE Tab Focus and some design changes.
I guess a few more tabs would be useful:
-one for z-order sorted windows (for quick switching between couple of windows)
-two or three for user defined group windows (e.g.: Editors, Dictionaries, Explorers...)
What do you think?

P.s.: I started to use it regularly
Attachments
Win-Tab Activate_2.4.ahk
(6.68 KiB) Downloaded 74 times
asad41163
Posts: 218
Joined: 29 Jul 2014, 14:31

Re: Window Activate/Browser Tab Activate

16 Apr 2017, 14:49

Hello guys,
it gave me this Msg:
D:\Lip\Win-Tab Activate_2.4.ahk (133) : ==> Duplicate label.
please help me
rommmcek
Posts: 489
Joined: 15 Aug 2014, 15:18

Re: Window Activate/Browser Tab Activate

17 Apr 2017, 03:35

@asad41163, There are only tree labels in v2.4 (VLV, VLV2 and VLV3). I suspect corrupt file data.
- If so a fresh download would help.
- If not:
* Does original code by Tre4shunter works?
* Does my previous version work?
asad41163
Posts: 218
Joined: 29 Jul 2014, 14:31

Re: Window Activate/Browser Tab Activate

17 Apr 2017, 07:29

Hi rommmcek,
I have not tried the code by Ter4shunter.
I have not tried your previous version.

that is the MSG:
>"C:\Program Files\AutoHotkey\AutoHotkey.exe" /ErrorStdOut "D:\Lip\Win-Tab Activate_2.4.ahk"
D:\Lip\Win-Tab Activate_2.4.ahk (133) : ==> Duplicate label.
Specifically: VLV
>Exit code: 2 Time: 0.03646
rommmcek
Posts: 489
Joined: 15 Aug 2014, 15:18

Re: Window Activate/Browser Tab Activate

17 Apr 2017, 10:12

I recommend you to try first the code by Ter4shunter! Just for testing purpose!
You must have some reference to find out, what is wrong!
Then we will see what is to be done!

P.s.: Did you try to make a fresh download? Again it looks like your file data is corrupted!
Tre4shunter
Posts: 36
Joined: 26 Jan 2016, 16:05

Re: Window Activate/Browser Tab Activate

17 Apr 2017, 10:50

Try this:

I removed includes, and just added everything to main script for you. It should work fine. What is your AHK version?

Code: Select all

;~ https://autohotkey.com/boards/viewtopic.php?f=6&t=24716&sid=15508c1eb2e61c2e2cb26cd3503a6450

click, 1078, 574, 0
if not A_IsAdmin
{
	Run *RunAs "%A_ScriptFullPath%"  ; Requires v1.0.92.01+
	ExitApp
}

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#SingleInstance,Force
;#Include Acc.ahk
;#Include LV_EX.ahk

setbatchlines, -1

gui,margin, 0, 0
;~ gui,-Border
gui,font,s12
gui, +alwaysontop +hwndGhwnd -MinimizeBox
Gui Color,, D9D0C3
;Gui,Add,ListBox,x0 y0 h340 w400 vmylistbox gMyListBox CGray,
Gui,Add,Tab3,x0 y0 w950 h550,Act_Win|IE_Tabs|G_Tabs 
gui,font,s14
gui,tab,1
Gui, Add, Listview, x0 y0 w950 h550 Grid -Multi hwndHLV vVLV gVLV, Act_Win
Gui,Tab,2
Gui, Add, Listview, x0 y0 w950 h550 Grid -Multi hwndHLV2 vVLV2 gVLV2, ieTabs|ieHwnd|cHwnd
Gui,Tab,3
Gui, Add, Listview, x0 y0 w950 h550 Grid -Multi hwndHLV3 vVLV3 gVLV3, gTabs|chHwnd
gui,listview,SysListView321
return 

!3::
;~ if (A_ThisHotkey = A_PriorHotkey) and (A_TimeSincePriorHotkey < 360)
	Reload
!Tab::
MButton::

IDs := []
g_browserids := []
ie_browserids := []
WinGet, ws_IDList, List
groups=1
LV_Delete()
gui,listview,SysListView323
LV_Delete()
gui,listview,SysListView322
LV_Delete()
gui,listview,SysListView321
Newlist:={}, ieCounter:=1, gCounter:=1, hwnd:=chwnd:=""


Loop % ws_IDList
{
	winget,processlist,processname, % "ahk_id" ws_IdList%a_Index%
	if(newlist[processlist] = "")
		newlist[processlist,0] := ws_IdList%a_Index%
	else
		newlist[processlist,newlist[processlist].maxindex()+1] :=  ws_IdList%a_Index%
}


for k,v in newlist
{
	LV_EX_GroupInsert(HLV, groups, k)
	LV_EX_GroupSetState(HLV, groups, "Collapsible")
	for window,hwnd in v
	{
		if(k="iexplore.exe"){
			BrowserCounter+=100
			BrowserCounter:=ie_ListBrowser(hwnd)
		} BrowserCounter:=""
		if(k="Chrome.exe"){
			browserCounter+=200
			browserCounter:=g_ListBrowser(hwnd)
		}
		winget,pName,processname, ahk_id %hwnd%
		WinGetTitle,wTitle, ahk_id %hwnd%
		if(((wTitle="Start") OR (wTitle = "Program Manager") AND k = "Explorer.exe")){
			continue
		}
		
		if(wTitle <> "")
		{
			if(pName="Explorer.exe")
				wTitle := "File Explorer - " wTitle
			LV_Add("",wTitle)
			IDs[wTitle] := hwnd
			LV_EX_SetGroup(HLV,LV_GetCount(), Groups)
		}
	}
	groups++
	ieDone:=""
}

LV_EX_EnableGroupView(HLV)
LV_EX_EnableGroupView(HLV2)
LV_EX_EnableGroupView(HLV3)
LV_ModifyCol(1,930)
gui,show ;, NA  ;x1515 y735 h300 w400
;~ WinSet, Transparent, 191, ahk_id %gHWND%
return

#IfWinExist, Win-Tab Activate ahk_class AutoHotkeyGUI
!F4::ExitApp
!Tab::Send, {Down}
!CapsLock::Send, {Up}
Tab::Send, ^{PgDn}
CapsLock::Send, ^{PgUp}
q::Send, {PgUp}
a::Send, {PgDn}
Alt::
Enter::
	ControlGetFocus, fCtrl, Win-Tab ahk_class AutoHotkeyGUI
	if (fCtrl == "SysListView321")
		ControlGet, Text, List, Selected, SysListView321, Win-Tab ahk_class AutoHotkeyGUI
	else if (fCtrl == "SysListView322") {
		ControlGet, Text, List, Selected, SysListView322, Win-Tab ahk_class AutoHotkeyGUI
		StringSplit, LvRow, Text, % A_Tab
		Text:=LvRow1, hwnd:=LvRow2, chwnd:=LvRow3
		goto, VLV2
		}
	else if (fCtrl == "SysListView323") {
		ControlGet, Text, List, Selected, SysListView323, Win-Tab ahk_class AutoHotkeyGUI
		StringSplit, LvRow, Text, % A_Tab
		Text:=LvRow1, hwnd:=LvRow2
		goto, VLV3
		}
VLV:
gui,listview,SysListView321
if !Text
	LV_GetText(Text,A_EventInfo)
winid := ids[text]
WinGet name, ProcessName, % Text " ahk_exe ApplicationFrameHost.exe"
if (name = "ApplicationFrameHost.exe") {                   ; detect metro window
	WinActivate, % Text " ahk_exe ApplicationFrameHost.exe"
	WinWaitActive, % Text " ahk_exe ApplicationFrameHost.exe",, 1
	}
else {										; depricated by MS, but the best I dealt with
	DllCall("SwitchToThisWindow", "UInt", winid, "UInt", 1)
	WinWaitActive, ahk_id %winid%,, 1
	} Text:=""
	;~ if (A_ThisHotkey = "Enter")||(A_ThisHotkey = "Alt")
		;~ WinActivate, Win-Tab ahk_class AutoHotkeyGUI
gui, hide
return
	
VLV2:
gui,listview,SysListView322
if !Text {
	LV_GetText(Text,A_EventInfo)
	LV_GetText(hwnd,A_EventInfo, 2)
	LV_GetText(chwnd,A_EventInfo, 3)
	}
gui,listview,SysListView321
list := Acc_Get("Object", "4.1", 0, "ahk_id " chwnd)
for each, tab in Acc_Children(list) 
{
	if (tab.accName(0) = Text)
	{
		tab.accDoDefaultAction(0)
		WinActivate,  % "ahk_id " hwnd
		break
	}
} Text:=""
;~ if (A_ThisHotkey = "Enter")||(A_ThisHotkey = "Alt")
	;~ WinActivate, Win-Tab ahk_class AutoHotkeyGUI
gui, hide
return

VLV3:
gui,listview,SysListView323
if !Text {
	LV_GetText(Text,A_EventInfo)
	LV_GetText(hwnd,A_EventInfo, 2)
	}
gui,listview,SysListView321
list := Acc_Get("Object", "4.1.2.2.2", 0, "ahk_id " hwnd)
for each, tab in Acc_Children(list) 
{
	if (tab.accName(0) = Text)
	{
		tab.accDoDefaultAction(0)
		WinActivate,  % "ahk_id " hwnd
		break
	}
} Text:=""
;~ if (A_ThisHotkey = "Enter")||(A_ThisHotkey = "Alt")
	;~ WinActivate, Win-Tab ahk_class AutoHotkeyGUI
gui, hide
return

;~ Tab::Send, {Down}
;~ CapsLock::Send, {Up}
^CapsLock::Send, ^{PgUp}
Del::
Esc::
!Esc::
;~ WinSet, Transparent, off, ahk_id %gHWND%
gui, hide
return
Right::ControlSend, SysHeader321, ^{PgDn}, Win-Tab Activate ahk_class AutoHotkeyGUI
Left:: ControlSend, SysHeader321, ^{PgUp}, Win-Tab Activate ahk_class AutoHotkeyGUI
#IfWinExist

ie_ListBrowser(hwnd)
{
	global
	gui,listview,SysListView322
	loop {  
		ControlGet, pHwnd, Hwnd,, % "DirectUIHWND" A_Index, ahk_id %Hwnd%
		phwnd?cHwnd:=pHwnd
		 }	until !phwnd
	if InStr(ieDone, chwnd) {
		gui,listview,SysListView321
		return
		} ieDone.= chwnd "`n"	
	WinGet,wTitle,processname, ahk_id %hwnd%
	LV_EX_GroupInsert(HLV2, hwnd, ieCounter++ "-" wTitle)
	LV_EX_GroupSetState(HLV2, hwnd, "Collapsible")
	list := Acc_Get("Object", "4.1", 0, "ahk_id" chwnd)
	for each, tab in Acc_Children(list)
	if (tab.accName(0) != "New tab (Ctrl+T)")
	{
		LV_Add("",tab.accName(0), hwnd, chwnd)
		LV_EX_SetGroup(HLV2,LV_GetCount(), hwnd)
	}  bcounter:=1
	LV_ModifyCol(1,930)
	LV_ModifyCol(2,0)
	LV_ModifyCol(3,0)
	gui,listview,SysListView321
}

g_ListBrowser(hwnd)
{
	global
	gui,listview,SysListView323
	WinGet,wTitle,processname, ahk_id %hwnd%
	LV_EX_GroupInsert(HLV3, hwnd, gCounter++ "-" wTitle)
	LV_EX_GroupSetState(HLV3, hwnd, "Collapsible")
	list := Acc_Get("Object", "4.1.2.2.2", 0, "ahk_id" hwnd)
	for each, tab in Acc_Children(list)
	if (tab.accName(0) != "New Tab")
	{
		LV_Add("",tab.accName(0), hwnd)
		LV_EX_SetGroup(HLV3,LV_GetCount(), hwnd)
	}
	LV_ModifyCol(1,930)
	LV_ModifyCol(2,0)
	gui,listview,SysListView321
}

 
 
 ; ======================================================================================================================
; Namespace:      LV_EX
; Function:       Some additional functions to use with AHK ListView controls.
; Tested with:    AHK 1.1.20.03 (A32/U32/U64)
; Tested on:      Win 8.1 (x64)
; Changelog:
;     1.1.01.00/2016-04-28(just me     -  added LV_EX_GroupGetState contributed by Pulover.
;     1.1.00.00/2015-03-13/just me     -  added basic tile view support (suggested by toralf),
;                                         added basic (XP compatible) group view support,
;                                         revised code and made some minor changes.
;     1.0.00.00/2013-12-30/just me     -  initial release.
; Notes:
;     In terms of Microsoft
;        Item     stands for the whole row or the first column of the row
;        SubItem  stands for the second to last column of a row
;     All functions require the handle of the ListView (HWND). You get this handle using the 'Hwnd' option when
;     creating the control per 'Gui, Add, HwndHwndOfLV ...' or using 'GuiControlGet, HwndOfLV, Hwnd, MyListViewVar'
;     after control creation.
; Credits:
;     LV_EX tile view functions:
;        Initial idea by segalion (old forum: /board/topic/80754-listview-with-multiline-in-report-mode-help/)
;        based on code from Fabio Lucarelli (http://users.skynet.be/oleole/ListView_Tiles.htm).
; ======================================================================================================================
; This software is provided 'as-is', without any express or implied warranty.
; In no event will the authors be held liable for any damages arising from the use of this software.
; ======================================================================================================================
; ======================================================================================================================
; LV_EX_EnableGroupView - Enables or disables whether the items in a list-view control display as a group.
; ======================================================================================================================
LV_EX_EnableGroupView(HLV, Enable := True) {
   ; LVM_ENABLEGROUPVIEW = 0x109D -> msdn.microsoft.com/en-us/library/bb774900(v=vs.85).aspx
	SendMessage, 0x109D, % (!!Enable), 0, , % "ahk_id " . HLV
	Return (ErrorLevel >> 31) ? 0 : 1
}

; ======================================================================================================================
; LV_EX_GetGroup - Gets the ID of the group the list-view item belongs to.
; ======================================================================================================================
LV_EX_GetGroup(HLV, Row) {
   ; LVM_GETITEMA = 0x1005 -> http://msdn.microsoft.com/en-us/library/bb774953(v=vs.85).aspx
	Static OffGroupID := 28 + (A_PtrSize * 3)
	LV_EX_LVITEM(LVITEM, 0x00000100, Row) ; LVIF_GROUPID
	SendMessage, 0x1005, 0, % &LVITEM, , % "ahk_id " . HLV
	Return NumGet(LVITEM, OffGroupID, "UPtr")
}
; ======================================================================================================================
; LV_EX_GetHeader - Retrieves the handle of the header control used by the list-view control.
; ======================================================================================================================
LV_EX_GetHeader(HLV) {
   ; LVM_GETHEADER = 0x101F -> http://msdn.microsoft.com/en-us/library/bb774937(v=vs.85).aspx
	SendMessage, 0x101F, 0, 0, , % "ahk_id " . HLV
	Return ErrorLevel
}

; ======================================================================================================================
; LV_EX_GroupGetHeader - Gets the header text of a group by group ID
; ======================================================================================================================
LV_EX_GroupGetHeader(HLV, GroupID, MaxChars := 1024) {
   ; LVM_GETGROUPINFO = 0x1095
	Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
	Static LVGF_HEADER := 0x00000001
	Static OffHeader := 8
	Static OffHeaderMax := 8 + A_PtrSize
	VarSetCapacity(HeaderText, MaxChars * 2, 0)
	VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
	NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
	NumPut(LVGF_HEADER, LVGROUP, 4, "UInt")
	NumPut(&HeaderText, LVGROUP, OffHeader, "Ptr")
	NumPut(MaxChars, LVGROUP, OffHeaderMax, "Int")
	SendMessage, 0x1095, %GroupID%, % &LVGROUP, , % "ahk_id " . HLV
	Return StrGet(&HeaderText, MaxChars, "UTF-16")
}
; ======================================================================================================================
; LV_EX_GroupGetState - Get group states (requires Win Vista+ for most states).
; ======================================================================================================================
LV_EX_GroupGetState(HLV, GroupID, ByRef Collapsed := "", ByRef Collapsible := "", ByRef Focused := "", ByRef Hidden := ""
                  , ByRef NoHeader := "", ByRef Normal := "", ByRef Selected := "") {
   ; LVM_GETGROUPINFO = 0x1095 -> msdn.microsoft.com/en-us/library/bb774932(v=vs.85).aspx
Static OS := DllCall("GetVersion", "UChar")
Static LVGS5 := {Collapsed: 0x01, Hidden: 0x02, Normal: 0x00}
Static LVGS6 := {Collapsed: 0x01, Collapsible: 0x08, Focused: 0x10, Hidden: 0x02, NoHeader: 0x04, Normal: 0x00, Selected: 0x20}
Static LVGF := 0x04 ; LVGF_STATE
Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
Static OffStateMask := 8 + (A_PtrSize * 3) + 8
Static OffState := OffStateMask + 4
SetStates := 0
LVGS := OS > 5 ? LVGS6 : LVGS5
For Each, State In LVGS
	SetStates |= State
VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
NumPut(LVGF, LVGROUP, 4, "UInt")
NumPut(SetStates, LVGROUP, OffStateMask, "UInt")
SendMessage, 0x1095, %GroupID%, &LVGROUP, , % "ahk_id " . HLV
States := NumGet(&LVGROUP, OffState, "UInt")
For Each, State in LVGS
	%Each% := States & State ? True : False
Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_GroupInsert - Inserts a group into a list-view control.
; ======================================================================================================================
LV_EX_GroupInsert(HLV, GroupID, Header, Align := "", Index := -1) {
   ; LVM_INSERTGROUP = 0x1091 -> msdn.microsoft.com/en-us/library/bb761103(v=vs.85).aspx
	Static Alignment := {1: 1, 2: 2, 4: 4, C: 2, L: 1, R: 4}
	Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
	Static OffHeader := 8
	Static OffGroupID := OffHeader + (A_PtrSize * 3) + 4
	Static OffAlign := OffGroupID + 12
	Static LVGF := 0x11 ; LVGF_GROUPID | LVGF_HEADER | LVGF_STATE
	Static LVGF_ALIGN := 0x00000008
	Align := (A := Alignment[SubStr(Align, 1, 1)]) ? A : 0
	Mask := LVGF | (Align ? LVGF_ALIGN : 0)
	PHeader := A_IsUnicode ? &Header : LV_EX_PWSTR(Header, WHeader)
	VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
	NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
	NumPut(Mask, LVGROUP, 4, "UInt")
	NumPut(PHeader, LVGROUP, OffHeader, "Ptr")
	NumPut(GroupID, LVGROUP, OffGroupID, "Int")
	NumPut(Align, LVGROUP, OffAlign, "UInt")
	SendMessage, 0x1091, %Index%, % &LVGROUP, , % "ahk_id " . HLV
	Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_GroupRemove - Removes a group from a list-view control.
; ======================================================================================================================
LV_EX_GroupRemove(HLV, GroupID) {
   ; LVM_REMOVEGROUP = 0x1096 -> msdn.microsoft.com/en-us/library/bb761149(v=vs.85).aspx
	SendMessage, 0x10A0, %GroupID%, 0, , % "ahk_id " . HLV
	Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_GroupRemoveAll - Removes all groups from a list-view control.
; ======================================================================================================================
LV_EX_GroupRemoveAll(HLV) {
   ; LVM_REMOVEALLGROUPS = 0x10A0 -> msdn.microsoft.com/en-us/library/bb761147(v=vs.85).aspx
	SendMessage, 0x10A0, 0, 0, , % "ahk_id " . HLV
	Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_GroupSetState - Set group state (requires Win Vista+ for most states).
; ======================================================================================================================
LV_EX_GroupSetState(HLV, GroupID, States*) {
   ; LVM_SETGROUPINFO = 0x1093 -> msdn.microsoft.com/en-us/library/bb761167(v=vs.85).aspx
	Static OS := DllCall("GetVersion", "UChar")
	Static LVGS5 := {Collapsed: 0x01, Hidden: 0x02, Normal: 0x00, 0: 0, 1: 1, 2: 2}
	Static LVGS6 := {Collapsed: 0x01, Collapsible: 0x08, Focused: 0x10, Hidden: 0x02, NoHeader: 0x04, Normal: 0x00
                 , Selected: 0x20, 0: 0, 1: 1, 2: 2, 4: 4, 8: 8, 16: 16, 32: 32}
	Static LVGF := 0x04 ; LVGF_STATE
	Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
	Static OffStateMask := 8 + (A_PtrSize * 3) + 8
	Static OffState := OffStateMask + 4
	SetStates := 0
	LVGS := OS > 5 ? LVGS6 : LVGS5
	For Each, State In States {
		If !LVGS.HasKey(State)
			Return False
		SetStates |= LVGS[State]
	}
	VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
	NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
	NumPut(LVGF, LVGROUP, 4, "UInt")
	NumPut(SetStates, LVGROUP, OffStateMask, "UInt")
	NumPut(SetStates, LVGROUP, OffState, "UInt")
	SendMessage, 0x1093, %GroupID%, % &LVGROUP, , % "ahk_id " . HLV
	Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_HasGroup - Determines whether the list-view control has a specified group.
; ======================================================================================================================
LV_EX_HasGroup(HLV, GroupID) {
   ; LVM_HASGROUP = 0x10A1 -> msdn.microsoft.com/en-us/library/bb761097(v=vs.85).aspx
	SendMessage, 0x10A1, %GroupID%, 0, , % "ahk_id " . HLV
	Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_IsGroupViewEnabled - Checks whether the list-view control has group view enabled.
; ======================================================================================================================
LV_EX_IsGroupViewEnabled(HLV) {
   ; LVM_ISGROUPVIEWENABLED = 0x10AF -> msdn.microsoft.com/en-us/library/bb761133(v=vs.85).aspx
	SendMessage, 0x10AF, 0, 0, , % "ahk_id " . HLV
	Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_RedrawRows - Forces a list-view control to redraw a range of items.
; ======================================================================================================================
LV_EX_RedrawRows(HLV, First := 0, Last := "") {
   ; LVM_REDRAWITEMS = 0x1015 -> http://msdn.microsoft.com/en-us/library/bb761145(v=vs.85).aspx
	If (First > 0) {
		If (Last = "")
			Last := First
	}
	Else {
		First := LV_EX_GetTopIndex(HLV)
		Last := First + LV_EX_GetRowsPerPage(HLV) - 1
	}
	SendMessage, 0x1015, % (First - 1), % (Last - 1), , % "ahk_id " . HLV
	If (ErrorLevel)
		Return DllCall("User32.dll\UpdateWindow", "Ptr", HLV, "UInt")
	Return False
}

; ======================================================================================================================
; LV_EX_GetRowsPerPage - Calculates the number of items that can fit vertically in the visible area of a list-view
;                        control when in list or report view. Only fully visible items are counted.
; ======================================================================================================================
LV_EX_GetRowsPerPage(HLV) {
   ; LVM_GETCOUNTPERPAGE = 0x1028 -> http://msdn.microsoft.com/en-us/library/bb774917(v=vs.85).aspx
	SendMessage, 0x1028, 0, 0, , % "ahk_id " . HLV
	Return ErrorLevel
}

; ======================================================================================================================
; LV_EX_GetTopIndex - Retrieves the index of the topmost visible item when in list or report view.
; ======================================================================================================================
LV_EX_GetTopIndex(HLV) {
   ; LVM_GETTOPINDEX = 0x1027 -> http://msdn.microsoft.com/en-us/library/bb761087(v=vs.85).aspx
	SendMessage, 0x1027, 0, 0, , % "ahk_id " . HLV
	Return (ErrorLevel + 1)
}

; ======================================================================================================================
; LV_EX_SetGroup - Assigns a list-view item to an existing group.
; ======================================================================================================================
LV_EX_SetGroup(HLV, Row, GroupID) {
   ; LVM_SETITEMA = 0x1006 -> http://msdn.microsoft.com/en-us/library/bb761186(v=vs.85).aspx
	Static OffGroupID := 28 + (A_PtrSize * 3)
	LV_EX_LVITEM(LVITEM, 0x00000100, Row) ; LVIF_GROUPID
	NumPut(GroupID, LVITEM, OffGroupID, "UPtr")
	SendMessage, 0x1006, 0, % &LVITEM, , % "ahk_id " . HLV
	Return ErrorLevel
}

; ======================================================================================================================
; ======================================================================================================================
; Function for internal use ============================================================================================
; ======================================================================================================================
; ======================================================================================================================
LV_EX_LVITEM(ByRef LVITEM, Mask := 0, Row := 1, Col := 1) {
	Static LVITEMSize := 48 + (A_PtrSize * 3)
	VarSetCapacity(LVITEM, LVITEMSize, 0)
	NumPut(Mask, LVITEM, 0, "UInt"), NumPut(Row - 1, LVITEM, 4, "Int"), NumPut(Col - 1, LVITEM, 8, "Int")
}
; ----------------------------------------------------------------------------------------------------------------------
LV_EX_PWSTR(Str, ByRef WSTR) { ; ANSI to Unicode
	VarSetCapacity(WSTR, StrPut(Str, "UTF-16") * 2, 0)
	StrPut(Str, &WSTR, "UTF-16")
	Return &WSTR
}



;------------------------------------------------------------------------------
; Acc.ahk Standard Library
; by Sean
; Updated by jethrow:
; 	Modified ComObjEnwrap params from (9,pacc) --> (9,pacc,1)
; 	Changed ComObjUnwrap to ComObjValue in order to avoid AddRef (thanks fincs)
; 	Added Acc_GetRoleText & Acc_GetStateText
; 	Added additional functions - commented below
; 	Removed original Acc_Children function
;	Added Acc_Error, Acc_ChildrenByRole, & Acc_Get functions
; last updated 10/25/2012
;------------------------------------------------------------------------------

Acc_Init()
{
	Static	h
	If Not	h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromEvent(ByRef _idChild_, hWnd, idObject, idChild)
{
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromEvent", "Ptr", hWnd, "UInt", idObject, "UInt", idChild, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return	ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "")
{
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return	ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

Acc_ObjectFromWindow(hWnd, idObject = 0)
{
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
	Return	ComObjEnwrap(9,pacc,1)
}

Acc_WindowFromObject(pacc)
{
	If	DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc)?ComObjValue(pacc):pacc, "Ptr*", hWnd)=0
	Return	hWnd
}

Acc_GetRoleText(nRole)
{
	nSize := DllCall("oleacc\GetRoleText", "Uint", nRole, "Ptr", 0, "Uint", 0)
	VarSetCapacity(sRole, (A_IsUnicode?2:1)*nSize)
	DllCall("oleacc\GetRoleText", "Uint", nRole, "str", sRole, "Uint", nSize+1)
	Return	sRole
}

Acc_GetStateText(nState)
{
	nSize := DllCall("oleacc\GetStateText", "Uint", nState, "Ptr", 0, "Uint", 0)
	VarSetCapacity(sState, (A_IsUnicode?2:1)*nSize)
	DllCall("oleacc\GetStateText", "Uint", nState, "str", sState, "Uint", nSize+1)
	Return	sState
}

Acc_SetWinEventHook(eventMin, eventMax, pCallback)
{
	Return	DllCall("SetWinEventHook", "Uint", eventMin, "Uint", eventMax, "Uint", 0, "Ptr", pCallback, "Uint", 0, "Uint", 0, "Uint", 0)
}

Acc_UnhookWinEvent(hHook)
{
	Return	DllCall("UnhookWinEvent", "Ptr", hHook)
}
/*	Win Events:

	pCallback := RegisterCallback("WinEventProc")
	WinEventProc(hHook, event, hWnd, idObject, idChild, eventThread, eventTime)
	{
		Critical
		Acc := Acc_ObjectFromEvent(_idChild_, hWnd, idObject, idChild)
		; Code Here:

	}
*/

; Written by jethrow
Acc_Role(Acc, ChildId=0) {
	try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetRoleText(Acc.accRole(ChildId)):"invalid object"
}
Acc_State(Acc, ChildId=0) {
	try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetStateText(Acc.accState(ChildId)):"invalid object"
}
Acc_Location(Acc, ChildId=0, byref Position="") { ; adapted from Sean's code
	try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
	catch
		return
	Position := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
	return	{x:NumGet(x,0,"int"), y:NumGet(y,0,"int"), w:NumGet(w,0,"int"), h:NumGet(h,0,"int")}
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Child(Acc, ChildId=0) {
	try child:=Acc.accChild(ChildId)
	return child?Acc_Query(child):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Acc_Error(p="") {
	static setting:=0
	return p=""?setting:setting:=p
}
Acc_Children(Acc) {
	if ComObjType(Acc,"Name") != "IAccessible"
		ErrorLevel := "Invalid IAccessible Object"
	else {
		Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
		if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
			Loop %cChildren%
				i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
			return Children.MaxIndex()?Children:
		} else
			ErrorLevel := "AccessibleChildren DllCall Failed"
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}
Acc_ChildrenByRole(Acc, Role) {
	if ComObjType(Acc,"Name")!="IAccessible"
		ErrorLevel := "Invalid IAccessible Object"
	else {
		Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
		if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
			Loop %cChildren% {
				i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i)
				if NumGet(varChildren,i-8)=9
					AccChild:=Acc_Query(child), ObjRelease(child), Acc_Role(AccChild)=Role?Children.Insert(AccChild):
				else
					Acc_Role(Acc, child)=Role?Children.Insert(child):
			}
			return Children.MaxIndex()?Children:, ErrorLevel:=0
		} else
			ErrorLevel := "AccessibleChildren DllCall Failed"
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}
Acc_Get(Cmd, ChildPath="", ChildID=0, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="") {
	static properties := {Action:"DefaultAction", DoAction:"DoDefaultAction", Keyboard:"KeyboardShortcut"}
	AccObj :=   IsObject(WinTitle)? WinTitle
			:   Acc_ObjectFromWindow( WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText), 0 )
	if ComObjType(AccObj, "Name") != "IAccessible"
		ErrorLevel := "Could not access an IAccessible Object"
	else {
		StringReplace, ChildPath, ChildPath, _, %A_Space%, All
		AccError:=Acc_Error(), Acc_Error(true)
		Loop Parse, ChildPath, ., %A_Space%
			try {
				if A_LoopField is digit
					Children:=Acc_Children(AccObj), m2:=A_LoopField ; mimic "m2" output in else-statement
				else
					RegExMatch(A_LoopField, "(\D*)(\d*)", m), Children:=Acc_ChildrenByRole(AccObj, m1), m2:=(m2?m2:1)
				if Not Children.HasKey(m2)
					throw
				AccObj := Children[m2]
			} catch {
			ErrorLevel:="Cannot access ChildPath Item #" A_Index " -> " A_LoopField, Acc_Error(AccError)
			if Acc_Error()
				throw Exception("Cannot access ChildPath Item", -1, "Item #" A_Index " -> " A_LoopField)
			return
		}
		Acc_Error(AccError)
		StringReplace, Cmd, Cmd, %A_Space%, , All
		properties.HasKey(Cmd)? Cmd:=properties[Cmd]:
		try {
			if (Cmd = "Location")
				AccObj.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
			  , ret_val := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
			else if (Cmd = "Object")
				ret_val := AccObj
			else if Cmd in Role,State
				ret_val := Acc_%Cmd%(AccObj, ChildID+0)
			else if Cmd in ChildCount,Selection,Focus
				ret_val := AccObj["acc" Cmd]
			else
				ret_val := AccObj["acc" Cmd](ChildID+0)
		} catch {
			ErrorLevel := """" Cmd """ Cmd Not Implemented"
			if Acc_Error()
				throw Exception("Cmd Not Implemented", -1, Cmd)
			return
		}
		return ret_val, ErrorLevel:=0
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}

Return to “Scripts and Functions”

Who is online

Users browsing this forum: Bing [Bot] and 29 guests