Acc库以及一些使用方法

 

; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=40615
; 2021.12.11 - 适配当天微信PC版的最新版本:3.4.5.27版本
; 2022.8.3 - 适配当天微信PC版的最新版本:3.7.5.23版本【将微信窗口最小化可以后台接收】
#SingleInstance Force
SetBatchLines -1

; 当前列表的第一个用户的最后一条信息
F1::
oAcc := Acc_Get("Object", "4.1.2.2.2.1.1.1.1.1.1.2.2", 0, "微信")
MsgBox % oAcc.accName(1)
return


F2:: ; 遍历微信当前对话内容
oAcc := Acc_Get("Object", "4.1.2.3.1.1.1.1.2.1.1.1", 0, "微信")
当前对话内容:=""
Loop {
	当前对话内容 .= oAcc.accName(A_Index) "`n"
	if (oAcc.accName(A_Index)="")
		Break
}
MsgBox % "遍历微信当前对话内容:`n`n" 当前对话内容
MsgBox % "可指定顺序编号:`n`n" oAcc.accName(1) "`n" oAcc.accName(2) "`n" oAcc.accName(3) "`n" oAcc.accName(4)
return

; 绝对坐标取ACC文字【左上角坐标55,55没有遮挡的话,就会读取到桌面图标名称】
F3::
oAcc := Acc_ObjectFromPoint("", 55, 55)    
MsgBox % oAcc.accName(1) "|" oAcc.accName(2) "|" oAcc.accName(3) "|" oAcc.accName(4)
return

F4:: ; 遍历当前窗口的所有项和取指定控件【示例测试请鼠标对准,自带记事本】
WinGet, hWnd, ID, A
MsgBox % Clipboard := JEE_AccGetTextAll(hWnd, "`r`n")

; ============== 以下是针对自带记事本生效 ==============
;编辑控制信息是: 4.1.4
;读取路径将是 4.1.4
;而我们将用0与 accValue()
oAcc := Acc_Get("Object", "4.1.4", 0, "ahk_id " hWnd)
MsgBox % oAcc.accValue(0)

;状态栏信息是: 4.2.4 c2
;读取路径将是 4.2.4
;而我们将用2与 accName()
oAcc := Acc_Get("Object", "4.2.4", 0, "ahk_id " hWnd)
MsgBox % oAcc.accName(2)
return

F6:: ; 点击记事本的编辑按钮【accDoDefaultAction()应该只适用于标准控件,不是一定有效】[自测微信QQ都不行]
; WinActivate, ahk_class Notepad
oAcc := Acc_Get("Object", "3.2", 0, "ahk_class Notepad")
Try oAcc.accDoDefaultAction() ; 单击目标控件
return

F7:: ; 系统自带记事本 - 获取ACC信息(控件)
ControlGet, hCtl1, hWnd,, Edit1, ahk_class Notepad
ControlGet, hCtl2, hWnd,, msctls_statusbar321, ahk_class Notepad

MsgBox % Clipboard := JEE_AccGetTextAll(hCtl1, "`r`n")
MsgBox % Clipboard := JEE_AccGetTextAll(hCtl2, "`r`n")

;编辑控制信息是: 4
;读取路径将是 4
;而我们将用0与 accValue()
oAcc := Acc_Get("Object", "4", 0, "ahk_id " hCtl1)
MsgBox % oAcc.accValue(0)

;状态栏信息是: 4 c2
;读取路径将是 4
;而我们将用2与 accName()
oAcc := Acc_Get("Object", "4", 0, "ahk_id " hCtl2)
MsgBox % oAcc.accName(2)
return

;==================================================
; ;e.g.
; 1::
; WinGet, hWnd, ID, A
; MsgBox % Clipboard := JEE_AccGetTextAll(hWnd, "`r`n")
; return

; ;e.g.
; 2::
; ControlGet, hCtl, Hwnd,, Edit1, A
; MsgBox % Clipboard := JEE_AccGetTextAll(hCtl, "`r`n")
; return

; ;e.g.
; 3::
; ControlGetFocus, vCtlClassNN, A
; ControlGet, hCtl, Hwnd,, % vCtlClassNN, A
; MsgBox % Clipboard := JEE_AccGetTextAll(hCtl, "`r`n")
; return

;vOpt: 以空格分隔的列表
;vOpt: n#: e.g. n20 ; 将检索名称限制在前20个字符
;vOpt: v#: e.g. v20 ; 限制检索值为前20个字符

JEE_StrRept(vText, vNum) {
	if (vNum <= 0)
		return
	return StrReplace(Format("{:" vNum "}", ""), " ", vText)
	;return StrReplace(Format("{:0" vNum "}", 0), 0, vText)
}

JEE_AccGetTextAll(hWnd:=0, vSep:="`n", vIndent:="`t", vOpt:="")
{
	vLimN := 20, vLimV := 20
	Loop, Parse, vOpt, % " "
	{
		vTemp := A_LoopField
		if (SubStr(vTemp, 1, 1) = "n")
			vLimN := SubStr(vTemp, 2)
		else if (SubStr(vTemp, 1, 1) = "v")
			vLimV := SubStr(vTemp, 2)
	}

	oMem := {}, oPos := {}
	;OBJID_WINDOW := 0x0
	oMem[1, 1] := Acc_ObjectFromWindow(hWnd, 0x0)
	oPos[1] := 1, vLevel := 1
	VarSetCapacity(vOutput, 1000000*2)

	Loop
	{
		if !vLevel
			break
		if !oMem[vLevel].HasKey(oPos[vLevel])
		{
			oMem.Delete(vLevel)
			oPos.Delete(vLevel)
			vLevelLast := vLevel, vLevel -= 1
			oPos[vLevel]++
			continue
		}
		oKey := oMem[vLevel, oPos[vLevel]]

		vName := "", vValue := ""
		if IsObject(oKey)
		{
			vRoleText := Acc_GetRoleText(oKey.accRole(0))
			try vName := oKey.accName(0)
			try vValue := oKey.accValue(0)
		}
		else
		{
			oParent := oMem[vLevel-1,oPos[vLevel-1]]
			vChildId := IsObject(oKey) ? 0 : oPos[vLevel]
			vRoleText := Acc_GetRoleText(oParent.accRole(vChildID))
			try vName := oParent.accName(vChildID)
			try vValue := oParent.accValue(vChildID)
		}
		if (StrLen(vName) > vLimN)
			vName := SubStr(vName, 1, vLimN) "..."
		if (StrLen(vValue) > vLimV)
			vValue := SubStr(vValue, 1, vLimV) "..."
		vName := RegExReplace(vName, "[`r`n]", " ")
		vValue := RegExReplace(vValue, "[`r`n]", " ")

		vAccPath := ""
		if IsObject(oKey)
		{
			Loop, % oPos.Length() - 1
				vAccPath .= (A_Index=1?"":".") oPos[A_Index+1]
		}
		else
		{
			Loop, % oPos.Length() - 2
				vAccPath .= (A_Index=1?"":".") oPos[A_Index+1]
			vAccPath .= " c" oPos[oPos.Length()]
		}
		vOutput .= vAccPath "`t" JEE_StrRept(vIndent, vLevel-1) vRoleText " [" vName "][" vValue "]" vSep

		oChildren := Acc_Children(oKey)
		if !oChildren.Length()
			oPos[vLevel]++
		else
		{
			vLevelLast := vLevel, vLevel += 1
			oMem[vLevel] := oChildren
			oPos[vLevel] := 1
		}
	}
	return SubStr(vOutput, 1, -StrLen(vSep))
}

;----------------------------------------------------------------------------------------------------------------------
; Acc.ahk
;----------------------------------------------------------------------------------------------------------------------
; Authors   (dd/mm/yyyy):
;   Sean    ()
;   jethrow (19/02/2012)
;   Sancarn (26/11/2017,18/01/2019,10/05/2019)
;----------------------------------------------------------------------------------------------------------------------
; CHANGE LOG:
;----------------------------------------------------------------------------------------------------------------------
;19/02/2012:
;     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
;26/11/2017:
;     Added Enumerations as Objects
;     Added IAccessible walking functionality e.g.
;         acc_childrenFilter(oAcc, ACC_FILTERS.byDescription, "Amazing button")
;         
;         acc_childrenFilter(oAcc, Func("myAwesomeFunction"), true)
;         myAwesomeFunction(oAcc,val){
;             return val
;         }
;     Added Acc_ChildProxy to Acc_Children
;18/01/2019:
;     Documentation Update
;10/05/2019:
;     Error Checking to ACC_ChildProxy
;----------------------------------------------------------------------------------------------------------------------
;ACC INTELLISENSE PACK:
;----------------------------------------------------------------------------------------------------------------------
;IACC成员属性:[ACCCHILD,ACCHECHEDCOUNT,ACCDEFAULTIACT,ACCDESICRING,ACCOCUS,ACCHELP,ACCHELPTOPIC,ACCKEYBOARDSHORTCUT,ACCNAME,ACCPLENT,ACCROLE,ACCSELECTION,ACTATE,ACCVALUE]
;成员方法:[AccDodefaultAction,Acchittest,Acclimation,AccNavate,AccSelect]
;全局常量:[acc_navdir,acc_selectionflag,acc_event,vt_constants,acc_filters,acc_objid,Acc_State,Acc_Role]
;全局方法:[Acc_ObjectFroomEvent,Acc_ObjectFromoPopt,Acc_ObjectFromWindow,Acc_WindowFromObject,Acc_SetWineventhook,Acc_LockWinevent,Acc_Location,Acc_Parent,Acc_Child,Acc_Children,Acc_Get,Acc_ChildrenFilter,Acc_GetRootElement
;
;----------------------------------------------------------------------------------------------------------------------
; DOCUMENTATION:
;----------------------------------------------------------------------------------------------------------------------
; IACC成员属性:
;如果存在,则为指定子项速写读取idispatch界面,如果存在。所有对象都必须支持此属性。请参阅get_accchild。
; acchildcount只读属于此对象的子项数。所有对象都必须支持此属性。请参阅get_accchildcount。
; AccDefaultAction只读一个描述对象默认操作的字符串。并非所有对象都有默认操作。请参阅get_accdefaultaction。
; AccDescription Read-one Lotup To In Automation的转换中不支持ACCDescription属性。 Microsoft Active Accessibility服务器和应用程序不应使用它。一个字符串,用于描述指定对象的可视化外观。并非所有对象都有描述。
; ACCFOCUS只读具有键盘焦点的对象。接收键盘焦点的所有对象都必须支持此属性。请参阅get_accfocus。
; Acchelp只读一个帮助字符串。并非所有对象都支持此属性。请参阅get_acchelp。
; acchelptopic只读注意弃用了acchelptopic属性,不应使用。与指定对象相关联的帮助文件和该文件中相应主题的标识符的完整路径。并非所有对象都支持此属性。
; Acckeyboardshortcut只读对象的快捷键或访问密钥,也称为助记符。所有具有快捷键或访问密钥的对象都支持此属性。请参阅get_acckeyboardshortcut。
; accName只读对象的名称。所有对象都支持此属性。请参阅get_accname。
; ACCALTENT只读对象父级的IDISPATCH接口。所有对象都支持此属性。见get_accparent。
; accrole可读信息,用于描述指定对象的角色。所有对象都支持此属性。见get_accrole。
; Accselection只读此对象的所选子项。支持选择的所有对象必须支持此属性。请参阅get_accselection。
; acctate只读对象的当前状态。所有对象都支持此属性。请参阅get_accstate。
; accvalue读/写对象的值。并非所有对象都有一个值。请参阅get_accvalue,put_accvalue。
;会员方法:
; AccDodeFaultAction执行指定的对象的默认操作。并非所有对象都有默认操作。
; Acchittest在屏幕上的给定点处检索子元素或子对象。所有可视对象都支持此方法。
; acclocation检索指定的对象的当前屏幕位置。所有可视对象都支持此方法。 
;ACCNAVAVAVAGE注意弃用了ACCNAVAVAIGE方法,不应使用。客户端应该使用其他方法和属性,如accessiblechildren,get_accchild,get_accparent和ienumvariant。遍历容器中的另一个用户界面元素并检索对象。所有可视对象都支持此方法。
; AccSelect修改了选择或移动指定对象的键盘焦点。支持选择或接收键盘焦点的所有对象都必须支持此方法。
;全球常量:
; ACC_NAVDIR对象包含不同的导航方向标志。
; ACC_SELETIONFLAG对象包含不同的ACCSELECT()标志。
; ACC_Event对象包含可以与Acc_ObjectFroomEvent一起使用的不同Windows事件。
; VT_Constants对象包含不同的COM VTABLE常量。
; ACC_FILERNS包含要与ACC_CHILDRENFILT一起使用的过滤器函数的对象。
; ACC_OBID对象包含不同的对象名称和ID。
; ACC_STATE对象包含不同的状态名称和ID。
; ACC_ROLE对象包含不同的角色名称和ID。
;全球方法:
; Acc_ObjectFroomEvent(ByRef _idChild_,HWND,IDObject,IDChild) - 用于从事件中获取ACC对象
; ACC_OBJECTFOLPOINT(BYREF _IDCHILD_ =“”,x =“”,y =“”) - 用于从x,y点获取ACC对象
; Acc_ObjectFromWindow(HWND,IDObject = -4) - 用于从HWND获取ACC对象
; Acc_WindowFromObject(PACC) - 用于从ACC对象获取HWND
; Acc_SetWineventhook(Eventmin,EventMax,PCallback) - 侦听Windows事件。使用ACC对象Param致电回调​​。
; ACC_UNHOOKWINEVENT(HHOK) - 停止收听现有事件钩。
; ACC_LOCATION(ACC,ChildID = 0) - 获取IACIBESSIBLEVENT的位置
; ACC_Parent(ACC) - 获取元素的父对象
; ACC_CHILD(ACC,CHILDID = 0) - 使用指定的ID获取对象的子项。
; ACC_CHILDREN(ACC) - 获取IACICESTIBLEVENT的子项(作为阵列)
; ACC_GET(CMD,CHILDPATH =“”,CHILDID = 0,WINTITLE =“”“,WINTEXT =”“,”excludeTITLE =“”,“excludeText =”“) - 获取可访问的对象
; ACC_CHILDRENFILTER(OACC,FCondition,Value = 0,RetrateOne = False,OBJ = 0) - 过滤子子通过某些定义的条件
; Acc_GetRootElement() - 返回桌面的ACC对象(所有ACC树元素的根目录)
;弃用和内部方法:
; ACC_INIT() - 不要打电话!
; Acc_Query(ACC) - 不要打电话!从对象查询iAccessible接口
; Acc_Error(p =“”) - 不要打电话!错误信息
; ACC_GETROLETEXT(NROLE) -  [已弃用。使用ACC_ROLE对象] GET'S ACC角色作为文本。
; Acc_GetStateText(nstate) -  [已弃用。使用ACC_STATE对象] GET'S ACC状态为文本。
; ACC_ROLE(ACC,ChildID = 0) -  [已弃用。使用Acc_Role对象]
; ACC_STATE(ACC,CHILDID = 0) -  [已弃用。使用ACC_STATE对象]
; Acc_ChildrenByrole(ACC,角色) -  [已弃用。使用ACC_CHILDRENFILTER]获取指定角色的所有孩子。
; ACC_CHILDRENBYNAME(OCACESSIBLE,NAME,RETURNONE = FALSE) -  [已弃用。使用Acc_ChildrenFilter]按名称过滤子名称,如果returnone那么只返回1个孩子
;
;----------------------------------------------------------------------------------------------------------------------
;进一步描述:
;----------------------------------------------------------------------------------------------------------------------
; Acc_ChildrenFilter.
;过滤在ACC对象中的子项,并调用2nd参数与ACC对象和第3参数定义的函数。
;如果函数返回true,则将孩子包含在过滤器中。
;例子:
;以下函数将包括基于第3个参数的子项:
; ACC_CHILDRENFILTER(OACC,FUNC(“MYAWESOMEFUNCT”),真实);返回所有孩子
; ACC_CHILDRENFILTER(OACC,FUNC(“MYAWESOMEFUNCT”),真实);没有孩子
; myawesomefunction(oacc,val){
;返回val.
; }
;
; Acc_Filters.
;这些通常与`Acc_Childrenfilter`结合使用:
;例子:
; ACC_CHILDRENFILTER(OACC,ACC_FILTERS.BYDESCRIPTION,“Amazing Button”)
;辅助方法列表:
; Acc_Filters.ByDefaultAction(OACC,Action) - 通过特定的默认操作过滤子项
; Acc_Filters.ByDescription(OACC,DESC) - 通过特定描述过滤子项
; ACC_FILTERS.BYVALUE(OACC,VALUE) - 通过特定值过滤子项
; ACC_FILTERS.BYHELP(OACC,HLPTXT) - 通过特定的帮助文本过滤子项
; Acc_Filters.ByState(OACC,状态) - 通过特定状态过滤子项
; ACC_FILTERS.BYROLE(OACC,角色) - 通过特定角色过滤子项
; ACC_FILTERS.BYNAME(OACC,NAME) - 通过特定名称过滤子项
; ACC_FILTERS.BYGEX(OACC,REGEX) - 通过REGEX匹配对阵字符串的筛选子项:%accName%;%accHelp%;%accValue%;%accDescription%;%accDefaultAction%
;----------------------------------------------------------------------------------------------------------------------

;https://msdn.microsoft.com/en-us/library/windows/desktop/dd373606(v=vs.85).aspx
class ACC_OBJID{
    static    WINDOW                :=    0x00000000
    static    SYSMENU               :=    0xFFFFFFFF
    static    TITLEBAR              :=    0xFFFFFFFE
    static    MENU                  :=    0xFFFFFFFD
    static    CLIENT                :=    0xFFFFFFFC
    static    VSCROLL               :=    0xFFFFFFFB
    static    HSCROLL               :=    0xFFFFFFFA
    static    SIZEGRIP              :=    0xFFFFFFF9
    static    CARET                 :=    0xFFFFFFF8
    static    CURSOR                :=    0xFFFFFFF7
    static    ALERT                 :=    0xFFFFFFF6
    static    SOUND                 :=    0xFFFFFFF5
    static    QUERYCLASSNAMEIDX     :=    0xFFFFFFF4
    static    NATIVEOM            :=    0xFFFFFFF0
}

;https://msdn.microsoft.com/en-us/library/windows/desktop/dd373609(v=vs.85).aspx
class ACC_STATE {
    static    NORMAL                  :=        0                    
    static    UNAVAILABLE             :=        0x1                    
    static    SELECTED                :=        0x2                    
    static    FOCUSED                 :=        0x4                    
    static    PRESSED                 :=        0x8                    
    static    CHECKED                 :=        0x10                   
    static    MIXED                   :=        0x20                   
    static    INDETERMINATE           :=        this.MIXED            
    static    READONLY                :=        0x40                   
    static    HOTTRACKED              :=        0x80                   
    static    DEFAULT                 :=        0x100                  
    static    EXPANDED                :=        0x200                  
    static    COLLAPSED               :=        0x400                  
    static    BUSY                    :=        0x800                  
    static    FLOATING                :=        0x1000                 
    static    MARQUEED                :=        0x2000                 
    static    ANIMATED                :=        0x4000                 
    static    INVISIBLE               :=        0x8000                 
    static    OFFSCREEN               :=        0x10000                
    static    SIZEABLE                :=        0x20000                
    static    MOVEABLE                :=        0x40000                
    static    SELFVOICING             :=        0x80000                
    static    FOCUSABLE               :=        0x100000               
    static    SELECTABLE              :=        0x200000               
    static    LINKED                  :=        0x400000               
    static    TRAVERSED               :=        0x800000               
    static    MULTISELECTABLE         :=        0x1000000              
    static    EXTSELECTABLE           :=        0x2000000              
    static    ALERT_LOW               :=        0x4000000              
    static    ALERT_MEDIUM            :=        0x8000000              
    static    ALERT_HIGH              :=        0x10000000             
    static    PROTECTED               :=        0x20000000             
    static    VALID                   :=        0x7fffffff            
}

;https://msdn.microsoft.com/en-us/library/windows/desktop/dd373608(v=vs.85).aspx
class ACC_ROLE {
    static    TITLEBAR                :=        0x1    
    static    MENUBAR                 :=        0x2 
    static    SCROLLBAR               :=        0x3 
    static    GRIP                    :=        0x4 
    static    SOUND                   :=        0x5 
    static    CURSOR                  :=        0x6 
    static    CARET                   :=        0x7 
    static    ALERT                   :=        0x8 
    static    WINDOW                  :=        0x9 
    static    CLIENT                  :=        0xa 
    static    MENUPOPUP               :=        0xb 
    static    MENUITEM                :=        0xc 
    static    TOOLTIP                 :=        0xd 
    static    APPLICATION             :=        0xe 
    static    DOCUMENT                :=        0xf 
    static    PANE                    :=        0x10
    static    CHART                   :=        0x11
    static    DIALOG                  :=        0x12
    static    BORDER                  :=        0x13
    static    GROUPING                :=        0x14
    static    SEPARATOR               :=        0x15
    static    TOOLBAR                 :=        0x16
    static    STATUSBAR               :=        0x17
    static    TABLE                   :=        0x18
    static    COLUMNHEADER            :=        0x19
    static    ROWHEADER               :=        0x1a
    static    COLUMN                  :=        0x1b
    static    ROW                     :=        0x1c
    static    CELL                    :=        0x1d
    static    LINK                    :=        0x1e
    static    HELPBALLOON             :=        0x1f
    static    CHARACTER               :=        0x20
    static    LIST                    :=        0x21
    static    LISTITEM                :=        0x22
    static    OUTLINE                 :=        0x23
    static    OUTLINEITEM             :=        0x24
    static    PAGETAB                 :=        0x25
    static    PROPERTYPAGE            :=        0x26
    static    INDICATOR               :=        0x27
    static    GRAPHIC                 :=        0x28
    static    STATICTEXT              :=        0x29
    static    TEXT                    :=        0x2a
    static    PUSHBUTTON              :=        0x2b
    static    CHECKBUTTON             :=        0x2c
    static    RADIOBUTTON             :=        0x2d
    static    COMBOBOX                :=        0x2e
    static    DROPLIST                :=        0x2f
    static    PROGRESSBAR             :=        0x30
    static    DIAL                    :=        0x31
    static    HOTKEYFIELD             :=        0x32
    static    SLIDER                  :=        0x33
    static    SPINBUTTON              :=        0x34
    static    DIAGRAM                 :=        0x35
    static    ANIMATION               :=        0x36
    static    EQUATION                :=        0x37
    static    BUTTONDROPDOWN          :=        0x38
    static    BUTTONMENU              :=        0x39
    static    BUTTONDROPDOWNGRID      :=        0x3a
    static    WHITESPACE              :=        0x3b
    static    PAGETABLIST             :=        0x3c
    static    CLOCK                   :=        0x3d
    static    SPLITBUTTON             :=        0x3e
    static    IPADDRESS               :=        0x3f
    static    OUTLINEBUTTON           :=        0x40
}

;https://msdn.microsoft.com/en-us/library/windows/desktop/dd373600(v=vs.85).aspx
class ACC_NAVDIR {
    static    MIN                     :=    0x0
    static    UP                      :=    0x1
    static    DOWN                    :=    0x2
    static    LEFT                    :=    0x3
    static    RIGHT                   :=    0x4
    static    NEXT                    :=    0x5
    static    PREVIOUS                :=    0x6
    static    FIRSTCHILD              :=    0x7
    static    LASTCHILD               :=    0x8
    static    MAX                     :=    0x9
}

;https://msdn.microsoft.com/en-us/library/windows/desktop/dd373634(v=vs.85).aspx
class ACC_SELECTIONFLAG {
    static    NONE                    := 0x0    
    static    TAKEFOCUS               := 0x1 
    static    TAKESELECTION           := 0x2 
    static    EXTENDSELECTION         := 0x4 
    static    ADDSELECTION            := 0x8 
    static    REMOVESELECTION         := 0x10
    static    VALID                   := 0x1f
}

;MSAA Events list:
;    https://msdn.microsoft.com/en-us/library/windows/desktop/dd318066(v=vs.85).aspx
;What are win events:
;    https://msdn.microsoft.com/en-us/library/windows/desktop/dd373868(v=vs.85).aspx
;System-Level and Object-level events:
;    https://msdn.microsoft.com/en-us/library/windows/desktop/dd373657(v=vs.85).aspx
;Console accessibility:
;    https://msdn.microsoft.com/en-us/library/ms971319.aspx
class ACC_EVENT {
    static MIN                        := 0x00000001
    static MAX                        := 0x7FFFFFFF
    static SYSTEM_SOUND               := 0x0001
    static SYSTEM_ALERT               := 0x0002
    static SYSTEM_FOREGROUND          := 0x0003
    static SYSTEM_MENUSTART           := 0x0004
    static SYSTEM_MENUEND             := 0x0005
    static SYSTEM_MENUPOPUPSTART      := 0x0006
    static SYSTEM_MENUPOPUPEND        := 0x0007
    static SYSTEM_CAPTURESTART        := 0x0008
    static SYSTEM_CAPTUREEND          := 0x0009
    static SYSTEM_MOVESIZESTART       := 0x000A
    static SYSTEM_MOVESIZEEND         := 0x000B
    static SYSTEM_CONTEXTHELPSTART    := 0x000C
    static SYSTEM_CONTEXTHELPEND      := 0x000D
    static SYSTEM_DRAGDROPSTART       := 0x000E
    static SYSTEM_DRAGDROPEND         := 0x000F
    static SYSTEM_DIALOGSTART         := 0x0010
    static SYSTEM_DIALOGEND           := 0x0011
    static SYSTEM_SCROLLINGSTART      := 0x0012
    static SYSTEM_SCROLLINGEND        := 0x0013
    static SYSTEM_SWITCHSTART         := 0x0014
    static SYSTEM_SWITCHEND           := 0x0015
    static SYSTEM_MINIMIZESTART       := 0x0016
    static SYSTEM_MINIMIZEEND         := 0x0017
    static CONSOLE_CARET              := 0x4001
    static CONSOLE_UPDATE_REGION      := 0x4002
    static CONSOLE_UPDATE_SIMPLE      := 0x4003
    static CONSOLE_UPDATE_SCROLL      := 0x4004
    static CONSOLE_LAYOUT             := 0x4005
    static CONSOLE_START_APPLICATION  := 0x4006
    static CONSOLE_END_APPLICATION    := 0x4007
    static OBJECT_CREATE              := 0x8000
    static OBJECT_DESTROY             := 0x8001
    static OBJECT_SHOW                := 0x8002
    static OBJECT_HIDE                := 0x8003
    static OBJECT_REORDER             := 0x8004
    static OBJECT_FOCUS               := 0x8005
    static OBJECT_SELECTION           := 0x8006
    static OBJECT_SELECTIONADD        := 0x8007
    static OBJECT_SELECTIONREMOVE     := 0x8008
    static OBJECT_SELECTIONWITHIN     := 0x8009
    static OBJECT_STATECHANGE         := 0x800A
    static OBJECT_LOCATIONCHANGE      := 0x800B
    static OBJECT_NAMECHANGE          := 0x800C
    static OBJECT_DESCRIPTIONCHANGE   := 0x800D
    static OBJECT_VALUECHANGE         := 0x800E
    static OBJECT_PARENTCHANGE        := 0x800F
    static OBJECT_HELPCHANGE          := 0x8010
    static OBJECT_DEFACTIONCHANGE     := 0x8011
    static OBJECT_ACCELERATORCHANGE   := 0x8012
}

class VT_CONSTANTS {
    static EMPTY     :=    0x0  ; No value
    static NULL      :=    0x1  ; SQL-style Null
    static I2        :=    0x2  ; 16-bit signed int
    static I4        :=    0x3  ; 32-bit signed int
    static R4        :=    0x4  ; 32-bit floating-point number
    static R8        :=    0x5  ; 64-bit floating-point number
    static CY        :=    0x6  ; Currency
    static DATE      :=    0x7  ; Date
    static BSTR      :=    0x8  ; COM string (Unicode string with length prefix)
    static DISPATCH  :=    0x9  ; COM object
    static ERROR     :=    0xA  ; Error code (32-bit integer)
    static BOOL      :=    0xB  ; Boolean True (-1) or False (0)
    static VARIANT   :=    0xC  ; VARIANT (must be combined with VT_ARRAY or VT_BYREF)
    static UNKNOWN   :=    0xD  ; IUnknown interface pointer
    static DECIMAL   :=    0xE  ; (not supported)
    static I1        :=   0x10  ; 8-bit signed int
    static UI1       :=   0x11  ; 8-bit unsigned int
    static UI2       :=   0x12  ; 16-bit unsigned int
    static UI4       :=   0x13  ; 32-bit unsigned int
    static I8        :=   0x14  ; 64-bit signed int
    static UI8       :=   0x15  ; 64-bit unsigned int
    static INT       :=   0x16  ; Signed machine int
    static UINT      :=   0x17  ; Unsigned machine int
    static RECORD    :=   0x24  ; User-defined type -- NOT SUPPORTED
    static ARRAY     := 0x2000  ; SAFEARRAY
    static BYREF     := 0x4000  ; Pointer to another type of value
}

class ACC_FILTERS {
    byDefaultAction(oAcc,action){
        b := oAcc.accDefaultAction = action
        return b
    }

    byDescription(oAcc,desc){
        b := oAcc.accDescription = desc
        return b
    }

    byValue(oAcc,value){
        b := oAcc.accValue = value
        return b
    }

    byHelp(oAcc,help){
        b := oAcc.accHelp = help
    }

    byState(oAcc,state){
        return oAcc.accState & state
    }

    byRole(oAcc,role){
        b := oAcc.accRole = role
        return b
    }

    byName(oAcc,name){
        b := oAcc.accName = name
        return b
    }

    byRegex(oAcc,rx){
        info := oAcc.accName . ";" 
              . oAcc.accHelp . ";" 
              . oAcc.accValue ";" 
              . oAcc.accDescription . ";" 
              . oAcc.accDefaultAction
        return RegexMatch(Haystack, rx) > 0
    }
}


Acc_Init()
{
    Static    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) {
        _idChild_:=NumGet(varChild,8,"UInt")
        return ComObjEnwrap(9,pacc,1)
    }
}

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) {
        _idChild_:=NumGet(varChild,8,"UInt")
        return ComObjEnwrap(9,pacc,1)
    }
}

Acc_ObjectFromWindow(hWnd, idObject = -4)
{
    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
}

;Implement this?
;    IAccessibleHandler::AccessibleObjectFromID 

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) { ; 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
    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) :
}

; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
Acc_Query(Acc) { 
    try return ComObj(9, ComObjQuery(Acc, "{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

;Acc_GetChild(Acc_or_Hwnd, child_path) {
;   Acc := WinExist("ahk_id" Acc_or_Hwnd)? Acc_ObjectFromWindow(Acc_or_Hwnd):Acc_or_Hwnd
;   if ComObjType(Acc,"Name") = "IAccessible" {
;      Loop Parse, child_path, csv
;         Acc := A_LoopField="P"? Acc_Parent(Acc):Acc_Children(Acc)[A_LoopField]
;      return Acc
;   }
;}


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:=[], ErrorLevel=
        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)
                
                ;I assume NumGet(varChildren,i-8) is ComObjType ~Sancarn
                ComType := NumGet(varChildren,i-8)
                if (ComType = VT_CONSTANTS.DISPATCH) {
                    Children.push(Acc_Query(child))
                    ObjRelease(child)
                } else if (ComType = VT_CONSTANTS.I4) {
                    Children.push(new ACC_ChildProxy(Acc,child))
                } else {
                    ErrorLevel := "Unknown ComType: " ComType
                    Children.push(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)
}

acc_childrenByName(oAccessible, name,returnOne=false){
    items:=Acc_Children(oAccessible)
    results := []
    for k,item in items
    {
        if item.accName = name {
            if returnOne {
                return item
            }
            results.push(item)
        }
    }
    return results
}

acc_childrenFilter(oAcc, fCondition, value=0, returnOne=false, obj=0){
    
    items:=Acc_Children(oAcc)
    results := []
    if !IsFunc(fCondition)
        return 0        
    if obj =0
        obj:=ACC_FILTERS
    
    methodCallConvention = instr(fCondition.name, ".") > 0
    
    for k,item in items
    {
        ;fCondition(this ==> stores variables && other methods of object,item,value)
        if methodCallConvention {
            condition := fCondition.call(obj,item,value)
        } else {
            condition := fCondition.call(item,value)
        }
        if condition {
            if returnOne {
                return item
            }
            results.push(item)
        }
    }
    return results
}

acc_getRootElement(){
    return acc_ObjectFromWindow(0x10010)  ;Root object window handle always appears to be 0x10010
}

class ACC_ChildProxy {
    __New(oAccParent,id){
      global ACC_STATE
      this.__accParent         := oAccParent                        
      this.__accChildID        := id   
      this.accParent           := oAccParent                               
      
      try {
        this.accDefaultAction    := oAccParent.accDefaultAction(id)    
      } catch e {
        this.accDefaultAction:=""
      }
      try {
        this.accDescription      := oAccParent.accDescription(id)      
      } catch e {
        this.accDescription:=""
      }
      try {
        this.accHelp             := oAccParent.accHelp(id)             
      } catch e {
        this.accHelp:=""
      }
      try {
        this.accHelpTopic        := oAccParent.accHelpTopic(id)        
      } catch e {
        this.accHelpTopic:=""
      }
      try {
        this.accKeyboardShortcut := oAccParent.accKeyboardShortcut(id) 
      } catch e {
        this.accKeyboardShortcut:=""
      }
      try {
        this.accName             := oAccParent.accName(id)             
      } catch e {
        this.accName:=""
      }
      
      try {
        this.accRole             := oAccParent.accRole(id)             
      } catch e {
        this.accRole:=""
      }
      try {
        this.accState            := oAccParent.accState(id)            
      } catch e {
        this.accState:=""
      }
      try {
        this.accValue            := oAccParent.accValue(id)            
      } catch e {
        this.accValue:=""
      }
      try {
        this.accFocus            := this.accState && ACC_STATE.FOCUSED 
      } catch e {
        this.accFocus:=""
      }
    }
    
    accDoDefaultAction(){
        return this.__accParent.accDoDefaultAction(this.__accChildID)
    }
    
    accHitTest(){
        return false
    }
    accLocation(ByRef left, Byref top, ByRef width, ByRef height){
        return this.__accParent.accLocation(left, top, width, height, this.__accChildID)
    }
    accNavigate(){
        return this.__accParent.accNavigate(navDir,this.__accChildID)
    }
    accSelect(flagsSelect){
        return this.__accParent.accSelect(flagsSelect,this.__accChildID)
    }
}

给TA捐赠
共{{data.count}}人
人已捐赠
其他

Acc后台取微信来新消息更新提醒

2021-12-11 14:28:31

其他

修改注册表把cspslock换成Ralt

2021-12-12 21:00:49

5 条回复 A文章作者 M管理员
  1. 月下马

    留个脚印,晚些再回来好好看看,研究研究

  2. maxs

    天书级别啊

  3. AHK中文社区
    1河许人给您打赏了¥5
  4. 蜜獾哥
    HoneyBadger给您打赏了¥10
  5. gdzrh917

    mark一下 难得的Acc库相关资料

个人中心
购物车
优惠劵
有新私信 私信列表
搜索