利用ACC運行JS代碼

利用瀏覽器地址欄可以方便的運行JS代碼,下面就是實現的代碼。

;---------------------------------
;  利用ACC運行JS代碼 - By FeiYue
;
;  使用說明:在瀏覽器窗口中熱鍵運行
;---------------------------------

$^PgDn:: AccGetInfoUnderCursor()

$^Right::  ;//下一頁
$^Left::   ;//上一頁
js=
(LTrim Join`s
try {
  var Re=new RegExp("(下|後)(一|\s)*(頁|頁|章|篇|翻)","i");
  var a=document.getElementsByTagName("A");
  for (var i=0;i<a.length;i++) {
    if (Re.test(a[i].innerHTML)) {
      if (a[i].href.substr(0,11).toLowerCase()=="javascript:")
        a[i].click();
      else
        document.location.href=a[i].href;
      break;
    }
  }
} catch (e){}
)
js:=InStr(A_ThisLabel,"Right") ? js : StrReplace(js,"下|後","上|前")
AccRunJs(js)
; AccRunJs2(js)
return


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


AccRunJs(js)  ; 利用輸入光標找到目標ACC
{
  Send {Alt Down}d{Alt Up}
  Loop, 20
  {
    Sleep, 50
    Try if (Acc:=GetCaretAcc(child))
    {
      Acc.accValue(child):="javascript:" js
      Acc.accSelect(1,child)
      SendInput {Enter}
      Sleep, 500
      return
    }
  }
}

GetCaretAcc(ByRef _Childid_="", ByRef cx="", ByRef cy="")
{
  static init
  if (!init)
    init:=DllCall("LoadLibrary","Str","oleacc","Ptr")
  cmc:=A_CoordModeCaret
  CoordMode, Caret, Screen
  cx:=A_CaretX, cy:=A_CaretY
  CoordMode, Caret, %cmc%
  Try if (cx="" or cy="")
  {
    hWnd:=WinExist("A"), idObject:=OBJID_CARET:=0xFFFFFFF8
    if DllCall("oleacc\AccessibleObjectFromWindow"
    , "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", (VarSetCapacity(IID,16)
    +NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64")
    +NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,IID,8,"Int64"))*0
    +&IID, "Ptr*", pacc)=0
    {
      Acc:=ComObjEnwrap(9,pacc,1)
      , Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0)
      , ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId:=0)
      , cx:=NumGet(x,0,"int"), cy:=NumGet(y,0,"int")
    }
  }
  if  (cx+cy>0) and DllCall("oleacc\AccessibleObjectFromPoint"
  , "Int64", cx&0xFFFFFFFF|(cy+5)<<32, "Ptr*", pacc
  , "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
    return ComObjEnwrap(9,pacc,1), _Childid_:=NumGet(varChild,8,"UInt")
}


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


AccRunJs2(js, window:="A")  ; 利用控件屬性找到目標ACC
{
  static accPath
  SetTitleMatchMode, 2
  AccObj := AccObjectFromWindow( WinExist(window) )
  if (!accPath)  ; 第一次查找Acc路徑比較耗時
  {
    Acc := SearchElement(AccObj, {Role: ROLE_SYSTEM_TEXT:=0x2A
      , State: STATE_SYSTEM_FOCUSABLE:=0x100000, Name: "地址"}
      , arr:=[])
    For k,v in arr
      accPath.=(k=1) ? v : "." v
    ; MsgBox, 4096,, % accPath
  }
  else
  {
    Acc := AccObj
    Loop Parse, accPath, .
    try {
       idx:=A_LoopField, cChildren := Acc.accChildCount
       VarSetCapacity(varChildren, cChildren*(8+A_PtrSize*2), 0)
       DllCall("oleacc\AccessibleChildren", "Ptr", ComObjValue(Acc), "Int", 0
          , "Int", cChildren, "Ptr", &varChildren, "IntP", cChildren)
       Acc := AccQuery( NumGet(varChildren,(idx-1)*(8+A_PtrSize*2)+8) )
    }
    Catch
       return accPath:=""
  }
  Acc.accValue(0) := "javascript:" js
  Acc.accSelect(SELFLAG_TAKEFOCUS:=0x1, 0)
  ControlSend,, {Enter}, % window
}

SearchElement(parentElement, params, arr)
{
  found := true
  for k, v in params
  {
    try {
      if (k = "ChildCount")
        (parentElement.accChildCount != v && found := false)
      else if (k = "Role")
        (parentElement.accRole(0) != v && found := false)
      else if (k = "State")
        (!(parentElement.accState(0) & v) && found := false)
      else
        (!(parentElement["acc" . k](0) ~= v) && found := false)
    }
    catch 
      found := false
  } until (found = false)
  if found
    Return parentElement

  arr.Push(1)
  for k, v in AccChildren(parentElement)
  {
    arr[arr.length()]:=k
    if obj := SearchElement(v, params, arr)
      Return obj
  }
  arr.Pop()
}

AccObjectFromWindow(hWnd, idObject = 0)
{
  static IID_IDispatch   := "{00020400-0000-0000-C000-000000000046}"
       , IID_IAccessible := "{618736E0-3C3D-11CF-810C-00AA00389B71}"
       , OBJID_NATIVEOM  := 0xFFFFFFF0, VT_DISPATCH := 9, F_OWNVALUE := 1
       , h := DllCall("LoadLibrary", "Str", "oleacc", "Ptr")
  VarSetCapacity(IID, 16), idObject &= 0xFFFFFFFF
  DllCall("ole32\CLSIDFromString", "Str", idObject = OBJID_NATIVEOM ? IID_IDispatch : IID_IAccessible, "Ptr", &IID)
  if DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject, "Ptr", &IID, "PtrP", pAcc) = 0
    Return ComObject(VT_DISPATCH, pAcc, F_OWNVALUE)
}

AccChildren(Acc)
{
  static VT_DISPATCH := 9
  Loop 1  {
    if ComObjType(Acc, "Name") != "IAccessible"
    {
      error := "Invalid IAccessible Object"
      break
    }
    try cChildren := Acc.accChildCount
    catch
      Return ""
    Children := []
    VarSetCapacity(varChildren, cChildren*(8 + A_PtrSize*2), 0)
    res := DllCall("oleacc\AccessibleChildren", "Ptr", ComObjValue(Acc), "Int", 0
      , "Int", cChildren, "Ptr", &varChildren, "IntP", cChildren)
    if (res != 0)
    {
      error := "AccessibleChildren DllCall Failed"
      break
    }
    Loop % cChildren  {
      i := (A_Index - 1)*(A_PtrSize*2 + 8)
      child := NumGet(varChildren, i + 8)
      Children.Push( (b := NumGet(varChildren, i) = VT_DISPATCH) ? AccQuery(child) : child )
      ( b && ObjRelease(child) )
    }
  }
  if error
    ErrorLevel := error
  else
    Return Children.MaxIndex() ? Children : ""
}

AccQuery(Acc)
{
   static IAccessible := "{618736e0-3c3d-11cf-810c-00aa00389b71}", VT_DISPATCH := 9, F_OWNVALUE := 1
   try Return ComObject(VT_DISPATCH, ComObjQuery(Acc, IAccessible), F_OWNVALUE)
}

AccGetInfoUnderCursor()
{
  Acc := AccObjectFromPoint(child)
  Try ChildCount := Acc.accChildCount
  Try Role := Format("0x{:X}", Acc.accRole(child))
  Try State := Format("0x{:X}", Acc.accState(child))
  Try name := Acc.accName(child)
  Try value := Acc.accValue(child)
  MsgBox, 4096,, % "控件屬性爲:`n"
    . "ChildCount=" ChildCount "`n"
    . "Role=" Role "`n"
    . "State=" State "`n"
    . "name=" name "`n"
    . "value=" value "`n"
}

AccObjectFromPoint(ByRef _idChild_ = "", x = "", y = "")
{
  static init
  if (!init)
    init:=DllCall("LoadLibrary","Str","oleacc","Ptr")
  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")
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章