;  利用ACC和UIA后台获取文本  By FeiYue
;
;  后台获取文本时每个坐标第一次会激活窗口


F1::
; arr:=ACC获取文本()
arr:=后台ACC获取文本("记事本", 100, 100)
MsgBox 4096,, % "Name --> " arr.Name "`n`nText --> " arr.Value
return


F2::
; arr:=UIA获取文本()
ControlGetPos, x, y,,, Edit1, ahk_class Notepad
arr:=后台UIA获取文本("ahk_class Notepad", x, y)
MsgBox 4096,, % "Name --> " arr.Name "`n`nText --> " arr.Value
return

;===========

;使用窗口标题和相对窗口的坐标
后台ACC获取文本(WinTitle, x, y)
{
  static tab:=[]
  if !(r:=tab[WinTitle "|" x "|" y])
  {
    SetTitleMatchMode, 2
    ifWinNotExist, %WinTitle%,, return
    WinActivate, %WinTitle%
    WinWaitActive, %WinTitle%
    WinGetPos, winx, winy
    arr:=ACC获取文本(winx+x, winy+y, Acc, child)
    tab[WinTitle "|" x "|" y]:=[Acc, child]
    return arr
  }
  Acc:=r[1], child:=r[2], arr:=[]
  Try arr["Name"]:=Acc.accName(child)
  Try arr["Value"]:=Acc.accValue(child)
  return arr
}

;使用窗口标题和相对窗口的坐标
后台UIA获取文本(WinTitle, x, y)
{
  static tab:=[]
  if !(Element:=tab[WinTitle "|" x "|" y])
  {
    SetTitleMatchMode, 2
    ifWinNotExist, %WinTitle%,, return
    WinActivate, %WinTitle%
    WinWaitActive, %WinTitle%
    WinGetPos, winx, winy
    arr:=UIA获取文本(winx+x, winy+y, Element)
    tab[WinTitle "|" x "|" y]:=Element
    return arr
  }
  arr:=[], VarSetCapacity(var, 8+2*A_PtrSize), NumPut(8, var, "Short")
  For k, v in { "Name":30005, "Value":30045 }
  {
    ;-- Element.GetCurrentPropertyValue == 10
    DllCall(NumGet(NumGet(Element+0)+10*A_PtrSize),"Ptr",Element,"Int",v,"Ptr",&var)
    arr[k]:=StrGet(pstr:=NumGet(var, 8, "Ptr"), "utf-16")
    DllCall("oleaut32\SysFreeString", "Ptr",pstr)
  }
  return arr
}

UIA获取文本(x="", y="", ByRef Element="")
{
  static UIA:=ComObjCreate("{ff48dba4-60ef-4201-aa87-54103eef594e}"
    , "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")
    , h:=DllCall("LoadLibrary", "Str","oleaut32.dll")
  ;--------
  pos:=(x=""||y="" ? 0*DllCall("GetCursorPos","Int64*",pt)+pt : x&0xFFFFFFFF|y<<32)
  id:=DllCall("WindowFromPoint", "Int64",pos)
  SendMessage, WM_GETOBJECT:=0x3D, 0, 1,, ahk_id %id%
  ;-- UIA.ElementFromPoint == 7
  DllCall(NumGet(NumGet(UIA+0)+7*A_PtrSize), "Ptr",UIA, "Int64",pos, "Ptr*",Element)
  ;--------
  arr:=[], VarSetCapacity(var, 8+2*A_PtrSize), NumPut(8, var, "Short")
  For k, v in { "Name":30005, "Value":30045 }
  {
    ;-- Element.GetCurrentPropertyValue == 10
    DllCall(NumGet(NumGet(Element+0)+10*A_PtrSize),"Ptr",Element,"Int",v,"Ptr",&var)
    arr[k]:=StrGet(pstr:=NumGet(var, 8, "Ptr"), "utf-16")
    DllCall("oleaut32\SysFreeString", "Ptr",pstr)
  }
  return arr
}

ACC获取文本(x="", y="", ByRef Acc="", ByRef child="")
{
  static h:=DllCall("LoadLibrary", "Str","oleacc.dll")
  ;--------
  pos:=(x=""||y="" ? 0*DllCall("GetCursorPos","Int64*",pt)+pt : x&0xFFFFFFFF|y<<32)
  id:=DllCall("WindowFromPoint", "Int64",pos)
  SendMessage, WM_GETOBJECT:=0x3D, 0, 1,, ahk_id %id%
  Acc:=child:="", VarSetCapacity(var,8+2*A_PtrSize,0)
  if DllCall("oleacc\AccessibleObjectFromPoint","Int64",pos,"Ptr*",pacc,"Ptr",&var)=0
    Acc:=ComObjEnwrap(9,pacc,1), child:=NumGet(var,8,"UInt")
  ;--------
  arr:=[]
  Try arr["Name"]:=Acc.accName(child)
  Try arr["Value"]:=Acc.accValue(child)
  return arr
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。