; 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)
}
}
留个脚印,晚些再回来好好看看,研究研究
天书级别啊
mark一下 难得的Acc库相关资料