Acc / AccViewer / iWB2 Learner / Anchor conversion attempts
Acc / AccViewer / iWB2 Learner / Anchor conversion attempts
I've attempted two-way compatible conversions. They're working on AHK v1 but AccViewer and iWB2 Learner are having problems saying 'No object to invoke' on AHK v2, although the GUI windows are displaying.
Since AccViewer and iWB2 Learner need the Gui command, I suggest to test them on AutoHotkey_2.0-a077-c2bb552.
Index of /download/2.0
https://autohotkey.com/download/2.0/
Intended filenames:
Acc (AHK1+2).ahk [a finished version might be renamed to Acc.ahk]
AccViewer (AHK1+2).ahk
Anchor (AHK1+2).ahk [a finished version might be renamed to Anchor.ahk]
iWB2 Learner (AHK1+2).ahk
==================================================
Original versions:
[installation instructions]
Acc library (MSAA) and AccViewer download links - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=26201
[Acc.ahk]
Autohotkey-scripts-.ahk/Acc.ahk at master · Drugoy/Autohotkey-scripts-.ahk · GitHub
https://github.com/Drugoy/Autohotkey-sc ... es/Acc.ahk
[AccViewer.ahk]
Autohotkey-scripts-.ahk/AccViewer.ahk at master · Drugoy/Autohotkey-scripts-.ahk · GitHub
https://github.com/Drugoy/Autohotkey-sc ... Viewer.ahk
[Anchor.ahk]
AutoHotkey-Scripts/Anchor.ahk at master · polyethene/AutoHotkey-Scripts · GitHub
https://github.com/polyethene/AutoHotke ... Anchor.ahk
[iWB2 Learner UPDATED.ahk]
iWB2.Learner.UPDATED.zip
https://github.com/ahkscript/awesome-Au ... PDATED.zip
==================================================
One query re. Acc.ahk, which is preferable:
Acc_ObjectFromWindow(hWnd, idObject = 0) ;OBJID_WINDOW := 0
Acc_ObjectFromWindow(hWnd, idObject = -4) ;OBJID_CLIENT := -4
As I have seen both versions in recent versions of Acc.ahk.
Does it affect the operation of the script?
I normally see in AccViewer's treeview hierarchies, 'window' then lower down, 'client'.
Please share any arguments for why it should be either 'window' or 'client'.
Since AccViewer and iWB2 Learner need the Gui command, I suggest to test them on AutoHotkey_2.0-a077-c2bb552.
Index of /download/2.0
https://autohotkey.com/download/2.0/
Intended filenames:
Acc (AHK1+2).ahk [a finished version might be renamed to Acc.ahk]
AccViewer (AHK1+2).ahk
Anchor (AHK1+2).ahk [a finished version might be renamed to Anchor.ahk]
iWB2 Learner (AHK1+2).ahk
==================================================
Original versions:
[installation instructions]
Acc library (MSAA) and AccViewer download links - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=26201
[Acc.ahk]
Autohotkey-scripts-.ahk/Acc.ahk at master · Drugoy/Autohotkey-scripts-.ahk · GitHub
https://github.com/Drugoy/Autohotkey-sc ... es/Acc.ahk
[AccViewer.ahk]
Autohotkey-scripts-.ahk/AccViewer.ahk at master · Drugoy/Autohotkey-scripts-.ahk · GitHub
https://github.com/Drugoy/Autohotkey-sc ... Viewer.ahk
[Anchor.ahk]
AutoHotkey-Scripts/Anchor.ahk at master · polyethene/AutoHotkey-Scripts · GitHub
https://github.com/polyethene/AutoHotke ... Anchor.ahk
[iWB2 Learner UPDATED.ahk]
iWB2.Learner.UPDATED.zip
https://github.com/ahkscript/awesome-Au ... PDATED.zip
==================================================
One query re. Acc.ahk, which is preferable:
Acc_ObjectFromWindow(hWnd, idObject = 0) ;OBJID_WINDOW := 0
Acc_ObjectFromWindow(hWnd, idObject = -4) ;OBJID_CLIENT := -4
As I have seen both versions in recent versions of Acc.ahk.
Does it affect the operation of the script?
I normally see in AccViewer's treeview hierarchies, 'window' then lower down, 'client'.
Please share any arguments for why it should be either 'window' or 'client'.
Last edited by jeeswg on 15 Apr 2017, 13:32, edited 13 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: Acc / AccViewer / iWB2 Learner / Anchor conversion attempts
Code: Select all
;[updated: 2017-04-15]
;updated by jeeswg to make it AHK v1/v2 two-way compatible
; http://www.autohotkey.com/board/topic/77303-acc-library-ahk-l-updated-09272012/
; https://dl.dropbox.com/u/47573473/Web%20Server/AHK_L/Acc.ahk
;------------------------------------------------------------------------------
; 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
; last updated 2/25/2010
;------------------------------------------------------------------------------
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
{
_idChild_:=NumGet(varChild,8,"UInt")
ObjAddRef(pacc)
Return ComObject(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")
ObjAddRef(pacc)
Return ComObject(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
{
ObjAddRef(pacc)
Return ComObject(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(ComObject(0x4003,&x:=0), ComObject(0x4003,&y:=0), ComObject(0x4003,&w:=0), ComObject(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 ComObject(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.Push(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.Push(AccChild):""
else
Acc_Role(Acc, child)=Role?Children.Push(child):""
}
ErrorLevel:=0
return Children.MaxIndex()?Children:""
} 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 {
ChildPath := StrReplace(ChildPath, "_", A_Space)
AccError:=Acc_Error(), Acc_Error(true)
Loop, Parse, ChildPath, ., % A_Space
try {
if RegExMatch(A_LoopField, "^\d*$")
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)
Cmd := StrReplace(Cmd, A_Space, "")
properties.HasKey(Cmd)? Cmd:=properties[Cmd]:""
try {
if (Cmd = "Location")
AccObj.accLocation(ComObject(0x4003,&x:=0), ComObject(0x4003,&y:=0), ComObject(0x4003,&w:=0), ComObject(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 RegExMatch(Cmd, "^(Role|State)$")
ret_val := Acc_%Cmd%(AccObj, ChildID+0)
else if RegExMatch(Cmd, "^(ChildCount|Selection|Focus)$")
ret_val := AccObj["acc" Cmd]
else
ret_val := AccObj["acc" Cmd](ChildID+0)
} catch {
ErrorLevel := Chr(34) Cmd Chr(34) " Cmd Not Implemented"
if Acc_Error()
throw Exception("Cmd Not Implemented", -1, Cmd)
return
}
ErrorLevel:=0
return ret_val
}
if Acc_Error()
throw Exception(ErrorLevel,-1)
}
Code: Select all
#Include Acc (AHK1+2).ahk
#Include Anchor (AHK1+2).ahk
;[updated: 2017-04-15]
;updated by jeeswg to make it AHK v1/v2 two-way compatible
{
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
AHKFC_WinRedraw("ahk_id" Win.Main)
return
}
ShowMainGui:
{
if RegExMatch(A_EventInfo, "^(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 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
}
AHKFC_WinRedraw("ahk_id" Win.Main)
}
return
}
#if Not Lbutton_Pressed
^/::
{
AHKBC_SetBatchLines(-1)
Lbutton_Pressed := true
Stored.Chwnd := ""
Gui Acc: Default
GuiControl, Disable, TView
while Lbutton_Pressed
GetAccInfo()
AHKBC_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") {
AHKBC_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()
AHKBC_SetBatchLines("10ms")
}
return
}
OnExitCleanup()
{
CrossHair(true)
ExitApp
}
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 !RegExMatch(A_LoopField, "^\d*$")
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
proc := AHKFC_WinGetProcessName("ahk_id" parent)
procid := AHKFC_WinGetPID("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
proc := AHKFC_WinGetProcessName("ahk_id" Hwnd)
procid := AHKFC_WinGetPID("ahk_id" Hwnd)
}
{
GuiControl, , WinTitle, % title
GuiControl, , Text, % text
GuiControl, , Hwnd, % "0x" Format("{:X}", Hwnd)
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
ClassNN := _GetClassNN.ClassNN, _GetClassNN:=""
return, ClassNN
}
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.Push(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(ComObject(0x4003,&x:=0), ComObject(0x4003,&y:=0), ComObject(0x4003,&w:=0), ComObject(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
AHKFC_WinSetTransparent(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", "ptr", DllCall("GetModuleHandle", "str", "Gdi32.dll"), "astr", "SetTextColor")
,adrSetBkColor := DllCall("GetProcAddress", "ptr", DllCall("GetModuleHandle", "str", "Gdi32.dll"), "astr", "SetBkColor")
,adrSetBkMode := DllCall("GetProcAddress", "ptr", DllCall("GetModuleHandle", "str", "Gdi32.dll"), "astr", "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 !RegExMatch(class, "^(" 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
(CTLCOLORLISTBOX = "") ? (CTLCOLORLISTBOX := OnMessage(WM_CTLCOLORLISTBOX, A_ThisFunc)) : ""
If NumGet(CBBINFO,44)
Hwnd := Numget(CBBINFO,44), class := "Edit"
}
if RegExMatch(class, "^(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")
{
f := "RichEdit_SetBgColor", %f%(Hwnd, -BG)
return f
}
if (!CTLCOLOR%Class%)
CTLCOLOR%Class% := OnMessage(WM_CTLCOLOR%Class%, A_ThisFunc)
_%Hwnd%BG := BG, _%Hwnd%FG := FG
return _%Hwnd% := BG ? DllCall("CreateSolidBrush", "UInt", BG) : CLR_NONE
}
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, _s, h_cursor, IDC_CROSS := 32515, _c, _b, _h
if (OnOff = "Init" or OnOff = "I" or _s = "") {
_s := "_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"
_c := StrSplit(system_cursors, ","), _b := [], _h := []
Loop, % _c.MaxIndex()
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")
}
_s := (OnOff = 0 || OnOff = "Off" || _s = "_h" && (OnOff < 0 || OnOff = "Toggle" || OnOff = "T")) ? "_b" : "_h"
Loop, % _c.MaxIndex()
h_cursor := DllCall( "CopyImage", "uint",%_s%[A_Index], "uint",2, "int",0, "int",0, "uint",0 )
, DllCall( "SetSystemCursor", "uint",h_cursor, "uint",_c[A_Index] )
}
;==================================================
;forwards-compatibility functions
AHKFC_WinGetPID(WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{
local OutputVar
static WinGetPID := Func("WinGetPID")
if WinGetPID
return %WinGetPID%(WinTitle, WinText, ExcludeTitle, ExcludeText)
WinGet, OutputVar, PID, % WinTitle, % WinText, % ExcludeTitle, % ExcludeText
return OutputVar
}
AHKFC_WinGetProcessName(WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{
local OutputVar
static WinGetProcessName := Func("WinGetProcessName")
if WinGetProcessName
return %WinGetProcessName%(WinTitle, WinText, ExcludeTitle, ExcludeText)
WinGet, OutputVar, ProcessName, % WinTitle, % WinText, % ExcludeTitle, % ExcludeText
return OutputVar
}
WinGet(Cmd:="", WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{
local OutputVar
return OutputVar
}
AHKFC_WinRedraw(WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{
static WinRedraw := Func("WinRedraw")
if WinRedraw
%WinRedraw%(WinTitle, WinText, ExcludeTitle, ExcludeText)
else
WinSet, Redraw,, % WinTitle, % WinText, % ExcludeTitle, % ExcludeText
}
AHKFC_WinSetTransparent(N, WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{
local Hwnd
static WinSetTransparent := Func("WinSetTransparent")
Hwnd := WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText)
if (!Hwnd)
return 0
if WinSetTransparent
%WinSetTransparent%(N, WinTitle, WinText, ExcludeTitle, ExcludeText)
else
WinSet, Transparent, % N, % "ahk_id" Hwnd
return 1
}
WinSet(Param1:="", Param2:="", WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{
}
;==================================================
;backwards compatibility functions
AHKBC_SetBatchLines(Param)
{
SetBatchLines, % Param
}
SetBatchLines(Param)
{
}
;==================================================
Code: Select all
;[updated: 2017-04-15]
;updated by jeeswg to make it AHK v1/v2 two-way compatible
/*
Function: Anchor
Defines how controls should be automatically positioned relative to the new dimensions of a window when resized.
Parameters:
cl - a control HWND, associated variable name or ClassNN to operate on
a - (optional) one or more of the anchors: 'x', 'y', 'w' (width) and 'h' (height),
optionally followed by a relative factor, e.g. "x h0.5"
r - (optional) true to redraw controls, recommended for GroupBox and Button types
Examples:
> "xy" ; bounds a control to the bottom-left edge of the window
> "w0.5" ; any change in the width of the window will resize the width of the control on a 2:1 ratio
> "h" ; similar to above but directrly proportional to height
Remarks:
To assume the current window size for the new bounds of a control (i.e. resetting) simply omit the second and third parameters.
However if the control had been created with DllCall() and has its own parent window,
the container AutoHotkey created GUI must be made default with the +LastFound option prior to the call.
For a complete example see anchor-example.ahk.
License:
- Version 4.60a <http://www.autohotkey.net/~polyethene/#anchor>
- Dedicated to the public domain (CC0 1.0) <http://creativecommons.org/publicdomain/zero/1.0/>
*/
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
If (z = 0)
VarSetCapacity(g, gs * 99, 0), VarSetCapacity(c, cs * cx, 0), 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), "UInt", &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) {
gw := NumGet(g, cb + 4, "Short"), gh := NumGet(g, cb + 6, "Short"), gf := 1
Break
}
If (!gf)
NumPut(gp, g, gl), 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)) == 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, "Int", 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) ; RDW_UPDATENOW | RDW_INVALIDATE
Return
}
If (cf != 1)
cb := cl, cl += cs
bx := NumGet(gi, 48), by := NumGet(gi, 16, "Int") - NumGet(gi, 8, "Int") - gih - NumGet(gi, 52)
If (cf = 1)
dw -= giw - gw, dh -= gih - gh
NumPut(i, c, cb), 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
}
Code: Select all
#Include Acc (AHK1+2).ahk
#Include Anchor (AHK1+2).ahk
;[updated: 2017-04-15]
;updated by jeeswg to make it AHK v1/v2 two-way compatible
; Dragable Cursor is now Drawn In, rather than using external images
; Text Insert Point will not stay on edit control when clicked (unless highlighted)
; Updated to use New Realease of Sean's ComUtils
; To Do: Allow Text/HTML Pop-out for Viewing
; To Do: Make ChildNodes a complete tree
; Considering: Change from Click-to-Copy to Right-Click>>Copy Data
{ ; CONSTANTS/PARAMETERS
WM_ACTIVATE := 0x06
WM_KILLFOCUS := 0x08
WM_LBUTTONDOWN := 0x201
WM_LBUTTONUP := 0x202
Stored := object( "AppName", "iWB2 Learner"
, "TextLabel", "InnerText" ) ; hold stored/global values throughout script
}
{ ; DIRECTIVES
;#NoEnv
#NoTrayIcon
DetectHiddenWindows,on
SetTitleMatchMode,slow
SetTitleMatchMode,2
}
{ ; AUTOEXEC
ComObjError(false)
OnMessage(WM_LBUTTONDOWN, "HandleMessage")
OnExit("OnExitCleanup")
; Main GUI
Menu, Main, Add, Show Parent Structure, ParentStructure
Gui, Menu, Main
Gui, Add, Edit, x61 y5 w255 h20 hwndTitleHwnd vTitle HWNDh1,
Gui, Add, Edit, x61 y30 w255 h20 vURLL HWNDh2,
Gui, Add, Edit, x36 y55 w50 h20 vEleIndex HWNDh3,
Gui, Add, Edit, x120 y55 w90 h20 vEleName HWNDh4,
Gui, Add, Edit, x226 y55 w90 h20 vEleIDs HWNDh5,
Gui, Add, ListView, x6 y82 w310 h60 -LV0x10 AltSubmit vVarListView gSubListView NoSortHdr, % "Frame.#|index|name|id|"
LV_ModifyCol(1, 65), LV_ModifyCol(2,49), LV_ModifyCol(3,87), LV_ModifyCol(4,87), LV_ModifyCol(2,"Center")
Gui, Add, Edit, x11 y160 w302 h40 vhtml_text HWNDh6,
Gui, Add, Edit, x10 y217 w302 h40 vhtml_value HWNDh7,
Gui, Add, Text, x35 y7 w25 h20 +Center, Title
Gui, Add, Text, x37 y33 w23 h20 +Center, Url
Gui, Add, Text, x1 y56 w34 h20 +Center, Index
Gui, Add, Text, x89 y57 w30 h21 +Center, Name
Gui, Add, Text, x212 y58 w13 h20 +Center, ID
Gui, Add, GroupBox, x6 y145 w310 h119 vText, InnerText
Gui, Add, GroupBox, x6 y201 w310 h63 , OuterHTML
; CrossHair Control
Gui, Add, Text, x5 y3 w25 h26 Border gCrossHair ReadOnly HWNDh8 Border
CColor(h8, "White")
Gui, Add, Text, x5 y3 w25 h4 HWNDh9 Border
CColor(h9, "0046D5")
Gui, Add, Text, x8 y17 w19 h1 Border vHBar
Gui, Add, Text, x17 y8 w1 h19 Border vVBar
Gui, Font, S6
Gui, Add, Text, x1 y32 w35 h26 +Center, DRAG CURSOR
Gui, +AlwaysOnTop +Delimiter`n
Gui, Show, Center h270 w322, % Stored.AppName
Gui, +LastFoundExist
AHKFC_WinRedraw("ahk_id" GuiWinHWND:=WinExist())
ControlFocus, Static7, % "ahk_id" GuiWinHWND
; Parental Structure GUI
Gui 2: +ToolWindow +AlwaysOnTop +Resize
Gui 2: Add, TreeView, vTView R17
Gui 2: Show, Hide, Parent Structure
WinGetPos, , , _2GuiW, _2GuiH, % "ahk_id"
. Stored.2GUIhwnd := WinExist("Parent Structure ahk_class AutoHotkeyGUI")
Menu, RClickMenu, Add ; Ensure RClickMenu Exists
outline := Outline() ; create "Outline" object
Hotkey, ~LButton Up, Off ; "~LButton Up" Hotkey only active when LButton is pressed
return
}
#s::
{ ; Speak the Text of the Element
ComObjCreate("SAPI.SpVoice").Speak(Stored.textOfObj)
return
}
~Lbutton Up::
{ ; Handle LButton Being Released
Hotkey, ~LButton Up, Off
Lbutton_Pressed := False
if IsObject(Stored.BColor) ; Restore Element Background Color
Stored.BColor := ""
else if Not CH { ; Reset CrossHair
GuiControl, Show, HBar
GuiControl, Show, VBar
CrossHair(CH:=true)
}
RemoveFocus()
return
}
HandleMessage( p_w, p_l, p_m, p_hw ) { ; Handle LButton Being Pressed (for "WM_LBUTTONDOWN")
Gui, Submit, NoHide
if (A_GuiControl = "VarListView") { ; Get Column Number - if clicked on ListView
global column_num ; http://www.autohotkey.com/forum/viewtopic.php?t=6414
VarSetCapacity( htinfo, 20 )
, DllCall( "RtlFillMemory", "uint", &htinfo, "uint", 1, "uchar", p_l & 0xFF )
, DllCall( "RtlFillMemory", "uint", &htinfo+1, "uint", 1, "uchar", ( p_l >> 8 ) & 0xFF )
, DllCall( "RtlFillMemory", "uint", &htinfo+4, "uint", 1, "uchar", ( p_l >> 16 ) & 0xFF )
, DllCall( "RtlFillMemory", "uint", &htinfo+5, "uint", 1, "uchar", ( p_l >> 24 ) & 0xFF )
SendMessage, % 0x1000+57, 0, % &htinfo,, % "ahk_id" p_hw
If ( ErrorLevel = -1 )
Return
column_num := ( *( &htinfo+8 ) & 1 ) ? False : 1+*( &htinfo+16 )
}
else if (%A_GuiControl% != "") {
temp := clipboard := %A_GuiControl%
ToolTip, % "clipboard= " (StrLen(temp) > 40 ? SubStr(temp,1,40) "..." : temp)
SetTimer, RemoveToolTip, 1000
}
else if (A_GuiControl = "TView") { ; if clicked on TreeView (parent structure)
Acc_ObjectFromPoint(child).accSelect(0x3, child)
Hotkey, ~LButton Up, On
global Stored
if TV_GetParent(TVsel:=TV_GetSelection()) {
TV_GetText(text, TVsel)
RegExMatch(text, "\d+", child)
clicked := Stored.pelt.childNodes[child]
}
else {
clicked := Stored.pelt
Loop, % TV_GetDiffCount(Stored.TVitem, TVsel)
clicked := clicked.parentNode
}
Stored.BColor := BCobj(clicked, "silver")
}
RemoveFocus()
}
IE_HtmlElement() { ; get the parent windows & coord from the element
static IID_IWebBrowserApp := "{0002DF05-0000-0000-C000-000000000046}", IID_IHTMLWindow2 := "{332C4427-26CB-11D0-B483-00C04FD90119}"
CoordMode, Mouse
MouseGetPos, xpos, ypos,, hCtl, 3
WinGetClass, sClass, % "ahk_id" hCtl
If Not (sClass == "Internet Explorer_Server")
|| Not pdoc := ComObject(9,ComObjQuery(Acc_ObjectFromWindow(hCtl), IID_IHTMLWindow2, IID_IHTMLWindow2),1).document ; document property will fail if no valie com object
Return
global outline, Stored, Frame := {} ; store frames & hold "Frame" Coords & stored values
pwin := ComObject(9,ComObjQuery(pdoc, IID_IHTMLWindow2, IID_IHTMLWindow2),1)
iWebBrowser2 := ComObject(9,ComObjQuery(pwin,IID_IWebBrowserApp,IID_IWebBrowserApp),1)
if pelt := pwin.document.elementFromPoint( xpos-xorg:=pwin.screenLeft, ypos-yorg:=pwin.screenTop ) {
Stored.LV := object() ; hold frame info for ListView
while (type:=pelt.tagName)="IFRAME" || type="FRAME" {
selt .= A_Index ") **[sourceIndex]=" pelt.sourceindex " **[Name]= " pelt.name " **[ID]= " pelt.id "`n"
, Stored.LV[A_Index, "C1"] := type "." A_Index
, Stored.LV[A_Index, "C2"] := pelt.sourceindex
, Stored.LV[A_Index, "C3"] := pelt.name
, Stored.LV[A_Index, "C4"] := pelt.id
, Frame[A_Index] := pelt ; store frames
, pwin := ComObject(9,ComObjQuery(pbrt:=pelt.contentWindow, IID_IHTMLWindow2, IID_IHTMLWindow2),1)
, pdoc := pwin.document
, Stored.LV[A_Index, "URL"] := pdoc.url
, pbrt := pdoc.elementFromPoint( xpos-xorg+=pelt.getBoundingClientRect().left
, ypos-yorg+=pelt.getBoundingClientRect().top )
, pelt := pbrt
}
pbrt := pelt.getBoundingClientRect()
, l := pbrt.left
, t := pbrt.top
, r := pbrt.right
, b := pbrt.bottom
if Not outline.visible ; if the element has changed
|| (Stored.pelt.sourceIndex != pelt.sourceIndex) {
; (Stored["x1"] <> l+xorg || Stored["y1"] <> t+yorg || Stored["x2"] <> r+xorg || Stored["y2"] <> b+yorg) {
if selt ; if the element is in a frame, get frame dimensions
Frect := Frame[Frame.maxIndex()].getBoundingClientRect() ; get the Frame Rectangle
, Frame.x1 := xorg ; set the frame Coordinates
, Frame.y1 := yorg
, Frame.x2 := FRect.right+xorg
, Frame.y2 := FRect.bottom+yorg
else,
Frame.x1:=Frame.y1:=Frame.x2:=Frame.y2:= "NA" ; if there isn't any frames, assign frame coords "NA"
; Change outline display
outline.transparent(true)
, outline.hide()
, coord := GetCoord( Stored.x1 := l+xorg
, Stored.y1 := t+yorg
, Stored.x2 := r+xorg
, Stored.y2 := b+yorg
, iWebBrowser2.HWND )
, outline.show(coord.x1, coord.y1, coord.x2, coord.y2, coord.sides)
, outline.setAbove( iWebBrowser2.HWND )
, outline.transparent( false )
}
Sleep, 1 ; make sure Controls Update
if (Stored.selt != selt) {
LV_Delete()
Loop, % Stored.LV.MaxIndex()
LV_Add( "" , Stored.LV[A_Index].C1
, Stored.LV[A_Index].C2
, Stored.LV[A_Index].C3
, Stored.LV[A_Index].C4 )
Stored.selt := selt
}
Stored.pelt := pelt
, Stored.LocationName := iWebBrowser2.LocationName
, Stored.LocationURL := iWebBrowser2.LocationURL
GoSub, UpdateGuiControls
Gui, Show, NA, % Stored.AppName " :: <" Stored.pelt.tagName ">"
}
}
CrossHair:
{ ; allow dragable Cross-Hair when clicked
if (A_GuiEvent = "Normal") {
AHKBC_SetBatchLines(-1)
Hotkey, ~LButton Up, On
{ ; Set CrossHair Cursor & Hide in GUI
GuiControl, Hide, HBar
GuiControl, Hide, VBar
CrossHair(CH:=false)
}
Lbutton_Pressed := True
while Lbutton_Pressed
IE_HtmlElement()
outline.hide()
if (Stored.pelt.tagName != "")
Gui, Show, NA, % Stored.AppName " :: <" Stored.pelt.tagName "> [" GetTagIndex(Stored.pelt) "]"
if WinVisible("ahk_id" Stored.2GUIhwnd)
GoSub, ParentStructure
AHKBC_SetBatchLines("10ms")
}
return
}
OnExitCleanup()
{ ; Cleanup when the Script Exits
CrossHair(true)
ExitApp
}
GuiClose:
ExitApp
UpdateGuiControls:
{ ; Update the Main GUI with the New Element Info
AHKBC_SetBatchLines(-1)
Gui, 1: Default
textOfObj := inpt(Stored.pelt)
GuiControl, , Title, % Stored.LocationName
GuiControl, , URLL, % Stored.LocationURL ; Edit2
GuiControl, , EleIndex, % Stored.pelt.sourceindex ; Edit3
GuiControl, , EleName, % Stored.pelt.name ; Edit4
GuiControl, , EleIDs, % Stored.pelt.id ; Edit5
if (Stored.textOfObj != textOfObj)
GuiControl, , html_text, % Stored.textOfObj:=textOfObj ; Edit6
if (Stored.outerHTML != (val:=Stored.pelt.outerHTML) )
GuiControl, , html_value, % Stored.outerHTML:=val ; Edit7
textOfObj:=val:=""
RemoveFocus()
}
SubListView:
{ ; When the Frames ListView is clicked
if (A_GuiEvent = "Normal") { ; if Right Clicked
if (column_num = 1)
LVselection := Stored.LV[A_EventInfo].url
else,
LV_GetText(LVselection, A_EventInfo, column_num)
if LVselection { ; if listview item contains data
clipboard := LVSelection
ToolTip, % "clipboard= " (StrLen(LVSelection) > 40 ? SubStr(LVSelection,1,40) "..." : LVSelection)
SetTimer, RemoveToolTip, 1000
}
}
Return
}
RemoveToolTip:
{
SetTimer, RemoveToolTip, off
ToolTip
return
}
ParentStructure:
{ ; "Parent Structure" Menu Item Labels
{
AHKBC_SetBatchLines(-1)
if Not Stored.pelt.tagName
return
nodes := object()
elem := Stored.pelt
Gui 2: Default
TV_Delete()
Loop {
if (A_Index != 1)
elem := elem.parentNode
nodes.InsertAt( 1, elem.tagName
. (elem.id!=""? " id= " Chr(34) elem.id Chr(34):"")
. (elem.name!=""? " name= " Chr(34) elem.name Chr(34):"") )
} Until, elem.tagName = "html"
GuiControl, -Redraw, TView
For, Each, item in nodes
Stored.TVitem := TV_Add(item)
nodes := Stored.pelt.childNodes
Loop, % nodes.length {
elem := nodes.item(A_Index-1)
TV_Add("[" A_Index-1 "] " elem.tagName
. (elem.id!=""? " id= " Chr(34) elem.id Chr(34):"")
. (elem.name!=""? " name= " Chr(34) elem.name Chr(34):"")
, Stored.TVitem )
}
nodes:=elem:=""
GuiControl, +Redraw, TView
TV_Modify(Stored.TVitem, "Select Bold")
if Not WinVisible("ahk_id" Stored.2GUIhwnd) {
WinGetPos, x, y, w, , % "ahk_id" GuiWinHWND
WinMove, % "ahk_id" Stored.2GUIhwnd,
, % (x+w+_2GuiW > A_ScreenWidth? x-_2GuiW-5:x+w+5)
, % y, % _2GuiW, % _2GuiH
WinShow, % "ahk_id" Stored.2GUIhwnd
temp:=""
}
return
}
2GuiClose:
{
Gui 2: Hide
Gui 1: Default
Stored.TVitem := ""
return
}
2GuiSize:
{
Anchor(TView, "wh")
return
}
2GuiContextMenu:
{
if (A_GuiControl = "TView") {
Acc_ObjectFromPoint(child).accSelect(0x3, child)
Menu, RClickMenu, DeleteAll
TV_GetText(text, TV_GetSelection())
if RegExMatch(text, "id= " Chr(34) "\K[^" Chr(34) "]+", ElemID)
Menu, RClickMenu, Add, Copy ID, RClick
if RegExMatch(text, "name= " Chr(34) "\K[^" Chr(34) "]+", ElemName)
Menu, RClickMenu, Add, Copy Name, RClick
Menu, RClickMenu, Add, Use Element, RClick
Menu, RClickMenu, Show
}
return
}
RClick:
{
Gui, 2: +OwnDialogs
if (A_ThisMenuItem = "Copy ID")
clipboard := ElemID
else if (A_ThisMenuItem = "Copy Name")
clipboard := ElemName
else if (A_ThisMenuItem = "Use Element") {
temp := Stored.pelt
Gui, 2: Default
if TV_GetParent(TVsel:=TV_GetSelection()) {
TV_GetText(text, TVsel)
RegExMatch(text, "\d+", child)
Stored.pelt := Stored.pelt.childNodes[child]
}
else,
Loop, % TV_GetDiffCount(Stored.TVitem, TVsel)
Stored.pelt := Stored.pelt.parentNode
if Not Stored.pelt.sourceIndex {
MsgBox, 262160, Selection Error, Cannot access this element.
Stored.pelt := temp
}
else {
Gui, 1: Default
Gui, Show, NA, % Stored.AppName " :: <" Stored.pelt.tagName ">"
. (Stored.pelt.tagName="HTML"? "":" [" GetTagIndex(Stored.pelt) "]")
GoSub, UpdateGuiControls
if WinVisible("ahk_id" Stored.2GUIhwnd)
GoSub, ParentStructure
}
}
ElemName:=ElemID:=TVsel:=child:=temp:=""
return
}
}
{ ; OUTLINE OBJECT DEFINITION
Outline(color:="red") { ; uses GUI 95-99
self := object( "base", object( "show", "Outline_Show"
, "hide", "Outline_Hide"
, "setAbove", "Outline_SetAbove"
, "transparent", "Outline_Transparent"
, "color", "Outline_Color"
, "destroy", "Outline_Destroy"
, "__delete", "Object_Delete" ) )
Loop, 4 {
Gui, % A_Index+95 ": -Caption +ToolWindow"
Gui, % A_Index+95 ": Color", % color
Gui, % A_Index+95 ": Show", NA h0 w0, % "outline" A_Index
self[A_Index] := WinExist("outline" A_Index " ahk_class AutoHotkeyGUI")
}
self.visible := false
, self.color := color
, self.top := self[1]
, self.right := self[2]
, self.bottom := self[3]
, self.left := self[4]
Return, self
}
Outline_Show(self, x1, y1, x2, y2, sides:="TRBL") { ; show outline at coords
if InStr( sides, "T" )
Gui, 96:Show, % "NA X" x1-2 " Y" y1-2 " W" x2-x1+4 " H" 2,outline1
Else, Gui, 96: Hide
if InStr( sides, "R" )
Gui, 97:Show, % "NA X" x2 " Y" y1 " W" 2 " H" y2-y1,outline2
Else, Gui, 97: Hide
if InStr( sides, "B" )
Gui, 98:Show, % "NA X" x1-2 " Y" y2 " W" x2-x1+4 " H" 2,outline3
Else, Gui, 98: Hide
if InStr( sides, "L" )
Gui, 99:Show, % "NA X" x1-2 " Y" y1 " W" 2 " H" y2-y1,outline4
Else, Gui, 99: Hide
self.visible := true
}
Outline_Hide(self) { ; hide outline
Loop, 4
Gui, % A_Index+95 ": Hide"
self.visible := false
}
Outline_SetAbove(self, hwnd) { ; set Z-Order one above "hwnd"
ABOVE := DllCall("GetWindow", "uint", hwnd, "uint", 0x3) ; get window directly above "hwnd"
Loop, 4 ; set 4 "outline" GUI's directly below "hwnd_above"
DllCall( "SetWindowPos", "uint", self[ A_Index ], "uint", ABOVE
, "int", 0, "int", 0, "int", 0, "int", 0
, "uint", 0x1|0x2|0x10 ) ; NOSIZE | NOMOVE | NOACTIVATE
}
Outline_Transparent(self, param) { ; set Transparent ( different from hiding )
Loop, 4
AHKFC_WinSetTransparent(param=1? 0:255, "ahk_id" self[A_Index])
self.visible := !param
}
Outline_Color(self, color) { ; set Color of Outline GUIs
Loop, 4
Gui, % A_Index+95 ": Color" , % color
self.color := color
}
Outline_Destroy(self) { ; Destroy Outline
VarSetCapacity(self, 0)
}
Object_Delete() { ; Destroy "outline GUIs" when object is deleted
Loop, 4
Gui, % A_Index+95 ": Destroy"
}
}
; OTHER FUNCTIONS
CrossHair(OnOff:=1) { ; Change Cursor to Cross-Hair
; INIT = "I","Init"; OFF = 0,"Off"; TOGGLE = -1,"T","Toggle"; ON = others
static AndMask, XorMask, _s, h_cursor, IDC_CROSS := 32515
,_c ; system cursors
,_b ; blank cursors
,_h ; handles of default cursors
if (OnOff = "Init" or OnOff = "I" or _s = "") { ; init when requested or at first call
_s := "_h" ; active default cursors
, 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"
_c := StrSplit(system_cursors, ",")
Loop, % _c.MaxIndex()
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")
}
_s := (OnOff = 0 || OnOff = "Off" || _s = "_h" && (OnOff < 0 || OnOff = "Toggle" || OnOff = "T")) ? "_b" : "_h"
Loop, % _c.MaxIndex()
h_cursor := DllCall( "CopyImage", "uint",%_s%[A_Index], "uint",2, "int",0, "int",0, "uint",0 )
, DllCall( "SetSystemCursor", "uint",h_cursor, "uint",_c[A_Index] )
; http://www.autohotkey.com/docs/commands/DllCall.htm
; http://www.autohotkey.com/forum/topic4570.html#75609
}
inpt(i) { ; return the Text of the Element
global Stored
tag := i.tagName
if RegExMatch(tag, "^(BUTTON|INPUT|OPTION|SELECT|TEXTAREA)$")
{
if (Stored.TextLabel = "InnerText")
GuiControl, , Text, % Stored.TextLabel:="Value"
return, i.value
}
if (Stored.TextLabel = "Value")
GuiControl, , Text, % Stored.TextLabel:="InnerText"
return, i.innerText
}
GetCoord( x1,y1,x2,y2, WinHWND ) { ; get the coordinates for the outline
global Frame, outline
WinGetPos, Wx, Wy, , , % "ahk_id" WinHWND
ControlGetPos, Cx1, Cy1, Cw, Ch, Internet Explorer_Server1, % "ahk_id" WinHWND
Cx1+=Wx ; set "Internet Explorer_Server1" dimensions
, Cy1+=Wy
, Cx2:=Cx1+Cw
, Cy2:=Cy1+Ch
; Example return: object( "x1", 150, "y1", 200, "x2", 250, "y2", 300, "sides", "TRBL" )
Return, object( "x1", Value( x1,Cx1,Frame["x1"], ">" )
, "y1", Value( y1,Cy1,Frame["y1"], ">" )
, "x2", Value( x2,Cx2,Frame["x2"], "<" )
, "y2", Value( y2,Cy2,Frame["y2"], "<" )
, "sides", ( ElemCoord( y1,Cy1,Frame["y1"], ">" ) ? "T" : "" )
. ( ElemCoord( x2,Cx2,Frame["x2"], "<" ) ? "R" : "" )
. ( ElemCoord( y2,Cy2,Frame["y2"], "<" ) ? "B" : "" )
. ( ElemCoord( x1,Cx1,Frame["x1"], ">" ) ? "L" : "" ) )
}
Value( E,C,F, option:=">" ) { ; returns the value of the Greatest (or smallest) value
return, F+0=""? (option=">"? (E>=C? E:C) : (E<=C? E:C))
: (option=">"? (E>=C? (E>=F? E:F) : (C>=F? C:F)) : (E<=C? (E<=F? E:F) : (C<=F? C:F)))
}
ElemCoord( E,C,F, option:=">" ) { ; returns true if the Element value is the Greatest (or smallest)
return, F+0=""? (option=">"? (E>=C? 1:0):(E<=C? 1:0))
: (option=">"? (E>=C && E>=F? 1:0):(E<=C && E<=F? 1:0))
}
GetTagIndex(element) { ; return the Index in the Tag Collection
if IsMemberOf(element, "sourceIndex")
and (index:=element.sourceIndex)
and (tags:=element.ownerDocument.all.tags(element.tagName))
and (top:=tags.length, bottom:=0)
Loop {
test := Floor( (top+bottom)/2 )
i := tags[test].sourceIndex
if (index < i)
top := test
else if (index > i)
bottom := test
else,
return, test
}
}
IsMemberOf(obj, name) { ; http://www.autohotkey.com/forum/topic63827.html
p := ComObjValue(obj), ObjAddRef(p)
return, DllCall(NumGet(NumGet(1*p)+A_PtrSize*5)
, "Ptr", p
, "Ptr", VarSetCapacity(iid,16,0)*0+&iid
, "Ptr*", &name
, "UInt", 1
, "UInt", 1024
, "Int*", dispID)=0
&& dispID+1, ObjRelease(p)
}
TV_GetDiffCount(p1, p2) {
count := 0
while (p1 != p2)
p1 := TV_GetPrev(p1)
, count++
return, count
}
WinVisible(WinTitle) {
temp := A_DetectHiddenWindows
DetectHiddenWindows, Off
out := WinExist(WinTitle)
DetectHiddenWindows, % temp
return, out
}
BCobj(elem, color) { ; highlight Element Background
static base := object("__delete","BCobj_Delete")
return, object("elem",elem, "color",elem.style.backgroundColor, "base",base)
, elem.style.backgroundColor := color
}
BCobj_Delete(self) {
self.elem.style.backgroundColor := self.color
}
RemoveFocus() { ; Handle LButton Being Release over Main GUI
global GuiWinHWND
ControlGetFocus, focus, % "ahk_id" GuiWinHWND
if (SubStr(focus,1,4) == "Edit") {
ControlGet, text, Selected, , % focus, % "ahk_id" GuiWinHWND
if Not text
ControlFocus, Static7, % "ahk_id" GuiWinHWND
}
}
CColor(Hwnd, Background:="", Foreground:="") {
; http://www.autohotkey.com/forum/viewtopic.php?t=39055
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", "ptr", DllCall("GetModuleHandle", "str", "Gdi32.dll"), "astr", "SetTextColor")
,adrSetBkColor := DllCall("GetProcAddress", "ptr", DllCall("GetModuleHandle", "str", "Gdi32.dll"), "astr", "SetBkColor")
,adrSetBkMode := DllCall("GetProcAddress", "ptr", DllCall("GetModuleHandle", "str", "Gdi32.dll"), "astr", "SetBkMode")
;Set the colors (RGB -> BGR)
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)
;Activate message handling with OnMessage() on the first call for a class
WinGetClass, class, % "ahk_id" Hwnd
If !RegExMatch(class, "^(" 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) ;hwndList
%hwnd%BG := BG, %hwnd%FG := FG, %hwnd% := BG ? DllCall("CreateSolidBrush", "UInt", BG) : -1
(CTLCOLORLISTBOX = "") ? (CTLCOLORLISTBOX := OnMessage(WM_CTLCOLORLISTBOX, A_ThisFunc)) : ""
If NumGet(CBBINFO,44) ;hwndEdit
Hwnd := Numget(CBBINFO,44), class := "Edit"
}
if RegExMatch(class, "^(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")
{
f := "RichEdit_SetBgColor", %f%(Hwnd, -BG)
return f
}
if (!CTLCOLOR%Class%)
CTLCOLOR%Class% := OnMessage(WM_CTLCOLOR%Class%, A_ThisFunc)
_%Hwnd%BG := BG, _%Hwnd%FG := FG
return _%Hwnd% := BG ? DllCall("CreateSolidBrush", "UInt", BG) : CLR_NONE
}
; Message handler
critical ;its OK, always in new thread.
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%)
}
}
;==================================================
;backwards compatibility functions
AHKBC_SetBatchLines(Param)
{
SetBatchLines, % Param
}
SetBatchLines(Param)
{
}
;==================================================
;forwards-compatibility functions
AHKFC_WinRedraw(WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{
static WinRedraw := Func("WinRedraw")
if WinRedraw
%WinRedraw%(WinTitle, WinText, ExcludeTitle, ExcludeText)
else
WinSet, Redraw,, % WinTitle, % WinText, % ExcludeTitle, % ExcludeText
}
AHKFC_WinSetTransparent(N, WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{
local Hwnd
static WinSetTransparent := Func("WinSetTransparent")
Hwnd := WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText)
if (!Hwnd)
return 0
if WinSetTransparent
%WinSetTransparent%(N, WinTitle, WinText, ExcludeTitle, ExcludeText)
else
WinSet, Transparent, % N, % "ahk_id" Hwnd
return 1
}
WinSet(Param1:="", Param2:="", WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{
}
;==================================================
Last edited by jeeswg on 16 May 2017, 09:34, edited 3 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: Acc / AccViewer / iWB2 Learner / Anchor conversion attempts
jeeswg wrote:One query re. Acc.ahk, which is preferable ...
Code: Select all
#define OBJID_WINDOW ((LONG)0x00000000)
#define OBJID_SYSMENU ((LONG)0xFFFFFFFF)
#define OBJID_TITLEBAR ((LONG)0xFFFFFFFE)
#define OBJID_MENU ((LONG)0xFFFFFFFD)
#define OBJID_CLIENT ((LONG)0xFFFFFFFC) // -4 (added)
#define OBJID_VSCROLL ((LONG)0xFFFFFFFB)
#define OBJID_HSCROLL ((LONG)0xFFFFFFFA)
#define OBJID_SIZEGRIP ((LONG)0xFFFFFFF9)
#define OBJID_CARET ((LONG)0xFFFFFFF8)
#define OBJID_CURSOR ((LONG)0xFFFFFFF7)
#define OBJID_ALERT ((LONG)0xFFFFFFF6)
#define OBJID_SOUND ((LONG)0xFFFFFFF5)
#define OBJID_QUERYCLASSNAMEIDX ((LONG)0xFFFFFFF4)
#define OBJID_NATIVEOM ((LONG)0xFFFFFFF0)
Re: Acc / AccViewer / iWB2 Learner / Anchor conversion attempts
Cheers just me.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: Acc / AccViewer / iWB2 Learner / Anchor conversion attempts
I corrected some variable/object names on the conversions for AccViewer and iWB2 Learner. AccViewer's crosshair now works, although iWB2 Learner's crosshair is not working (in AHK v1 or v2).
==================================================
I understand now about the 'No object to invoke.' error.
Error: No object to invoke - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=37&t=3818
==================================================
I see now that there has been a change to NumGet:
NumGet
https://autohotkey.com/docs/commands/NumGet.htm
NumGet
https://lexikos.github.io/v2/docs/commands/NumGet.htm
I would be grateful to anyone who would like to test AccViewer and iWB2 Learner, to give me some hints on debugging the problems. Including: what is causing 'Parameter list too small.', which based on the source code, I believe refers to passing parameters to a function, but it signals 'Return, 0' ('Return, false') as being the problem line.
When I add ampersands to NumGet in AccViewer, there still seems to be a problem.
Basically I keep discovering new and surprising error messages each time I fix or try to fix the 2 scripts to work in AHK v2, and I'm going round in circles trying to correct the script. (The 2 scripts both work in AHK v1.)
==================================================
I understand now about the 'No object to invoke.' error.
Error: No object to invoke - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=37&t=3818
Code: Select all
q:: ;'No object to invoke.' tests
;MsgBox % obj.1 ;No object to invoke.
obj := {}
obj[1,2] := "hello"
MsgBox % obj.1.2 ;hello
obj := {}
obj.1 := "hello"
MsgBox % obj.1.2 ;No object to invoke.
obj := {}
obj.1 := {}
MsgBox % obj.1.2 ;blank
;MsgBox % obj.1.2 ;No object to invoke.
return
I see now that there has been a change to NumGet:
NumGet
https://autohotkey.com/docs/commands/NumGet.htm
NumGet
https://lexikos.github.io/v2/docs/commands/NumGet.htm
==================================================If the variable contains a pure number, that number is assumed to be an address.
I would be grateful to anyone who would like to test AccViewer and iWB2 Learner, to give me some hints on debugging the problems. Including: what is causing 'Parameter list too small.', which based on the source code, I believe refers to passing parameters to a function, but it signals 'Return, 0' ('Return, false') as being the problem line.
When I add ampersands to NumGet in AccViewer, there still seems to be a problem.
Basically I keep discovering new and surprising error messages each time I fix or try to fix the 2 scripts to work in AHK v2, and I'm going round in circles trying to correct the script. (The 2 scripts both work in AHK v1.)
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: Acc / AccViewer / iWB2 Learner / Anchor conversion attempts
Might want to add just me's Acc_Selection function
Also see qwerty12345's OnAlertSound script
Also sinkfaze made some cool things on the previous forum (IMPORTANT: These will not work in all cases)
Finally, does anyone know how to get the desktop window? I assume Acc_ObjectFromWindow(WinExist(),0).accParent works, but haven't tested it and am not sure it is the 'correct' method...
Code: Select all
; ----------------------------------------------------------------------------------------------------------------------------------
; Retrieves the selected children of this object. All objects that support selection must support this property
; ----------------------------------------------------------------------------------------------------------------------------------
Acc_Selection(Acc) {
Selection := []
Try
Selected := Acc.accSelection
Catch E
Return Acc_Error(A_ThisFunc, E)
If IsObject(Selected) {
If (Name := ComObjType(Selected, "Name")) {
If (Name = "IAccessible")
Selection.Push(Selected)
Else If (IA := Acc_Query(Selected))
Selection.Push(IA)
}
Else {
While Selected.Next(Value, VarType)
Selection.Push(Value)
}
}
Else If (Selected <> "")
Selection.Push(Selected)
Return (Selection.Length() ? Selection : "")
}
Also sinkfaze made some cool things on the previous forum (IMPORTANT: These will not work in all cases)
Finally, does anyone know how to get the desktop window? I assume Acc_ObjectFromWindow(WinExist(),0).accParent works, but haven't tested it and am not sure it is the 'correct' method...
Last edited by sancarn on 15 Jul 2017, 20:15, edited 1 time in total.
Re: Acc / AccViewer / iWB2 Learner / Anchor conversion attempts
Might also want to add these enums:
Code: Select all
;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
}
Re: Acc / AccViewer / iWB2 Learner / Anchor conversion attempts
- Although qwerty12's OnAlertSound script looks interesting, it's not necessarily something I would incorporate into AccViewer or an AccViewer alternative, although if you can provide a good argument, I might consider it.
- sinkfaze's scripts re. menus are good, but invoking a menu item seems like a good use of the Acc library, rather than a good feature for AccViewer, also, the information retrieved via 'WinGet', is information that AccViewer can already retrieve I believe.
- From your comments you strike me as having good ambition and vision for either AccViewer or an alternative/mod, so I would encourage you to work on an alternative and submit it, written in AHK v2 or AHK v1, whichever you prefer.
- I'm not against including the Acc_Selection function or the constants per se, they strike me as being potentially worthwhile, but I think I would like to see how you would incorporate them, one of the reasons for my comment above.
- Overall I'm actually quite happy with AccViewer and iWB2 Learner, I want 2 features: hotkeys to retrieve the window/control/object under the cursor for AccViewer, and any % zoom support for iWB2 Learner, plus to simply have AHK v2 compatible versions. I've already done all of the hard work for this, however the scripts are so fiddly to alter, that I plan to recreate them instead. So my most honest answer would be further encouragement for you to pursue your own script.
This script could be a good base from which to develop an AccViewer upgrade/alternative:
AccViewer Basic - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=32039
The functionality I would like to incorporate into iWB2 Learner:
Internet Explorer get element under cursor (show borders, show text) (any zoom percentage) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=29458
I have been having a lot of trouble trying to make even simple updates to AccViewer and iWB2 Learner, so I plan to recreate them from scratch ... *when I can* ... which could be months away, even if I then went back and worked on the original scripts, from experience, it would still be faster to try and recreate the scripts first. Note: I haven't done any work with AHK v2 GUI functions, so if anyone has any good template code, that would expedite things.
In trying to convert the two scripts for AHK v2, I have kept running into unusual errors that I don't get in AHK v1, that I am unfamiliar with, thus if someone familiar enough with AHK v2 felt motivated to do it, it would be useful for those scripts to be fully debugged. This is a key reason for me to start again from scratch, I might then be able to to understand the scripts better and anticipate what was causing the errors, and resolve them all myself. Although I think the scripts would benefit from a rewrite anyway.
==================================================
Re. getting access to Desktop.
This may or may not be helpful:
get full paths of selected files on Desktop and Common File Dialogs - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 36#p154836
Also:
WinGet, hWnd, ID, ahk_class Progman
I'd be interested as to whether FindWindowSW be used for Explorer folder windows as well as Desktop, or whether a WBGet equivalent (WBGet is for Internet Explorer) can be made for Explorer folder windows, and Desktop. I.e. one method for both Desktop and folder windows.
WBGet:
Basic Webpage Controls with JavaScript / COM - Tutorial - Tutorials - AutoHotkey Community
https://autohotkey.com/board/topic/4705 ... -tutorial/
- sinkfaze's scripts re. menus are good, but invoking a menu item seems like a good use of the Acc library, rather than a good feature for AccViewer, also, the information retrieved via 'WinGet', is information that AccViewer can already retrieve I believe.
- From your comments you strike me as having good ambition and vision for either AccViewer or an alternative/mod, so I would encourage you to work on an alternative and submit it, written in AHK v2 or AHK v1, whichever you prefer.
- I'm not against including the Acc_Selection function or the constants per se, they strike me as being potentially worthwhile, but I think I would like to see how you would incorporate them, one of the reasons for my comment above.
- Overall I'm actually quite happy with AccViewer and iWB2 Learner, I want 2 features: hotkeys to retrieve the window/control/object under the cursor for AccViewer, and any % zoom support for iWB2 Learner, plus to simply have AHK v2 compatible versions. I've already done all of the hard work for this, however the scripts are so fiddly to alter, that I plan to recreate them instead. So my most honest answer would be further encouragement for you to pursue your own script.
This script could be a good base from which to develop an AccViewer upgrade/alternative:
AccViewer Basic - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=32039
The functionality I would like to incorporate into iWB2 Learner:
Internet Explorer get element under cursor (show borders, show text) (any zoom percentage) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=29458
I have been having a lot of trouble trying to make even simple updates to AccViewer and iWB2 Learner, so I plan to recreate them from scratch ... *when I can* ... which could be months away, even if I then went back and worked on the original scripts, from experience, it would still be faster to try and recreate the scripts first. Note: I haven't done any work with AHK v2 GUI functions, so if anyone has any good template code, that would expedite things.
In trying to convert the two scripts for AHK v2, I have kept running into unusual errors that I don't get in AHK v1, that I am unfamiliar with, thus if someone familiar enough with AHK v2 felt motivated to do it, it would be useful for those scripts to be fully debugged. This is a key reason for me to start again from scratch, I might then be able to to understand the scripts better and anticipate what was causing the errors, and resolve them all myself. Although I think the scripts would benefit from a rewrite anyway.
==================================================
Re. getting access to Desktop.
This may or may not be helpful:
get full paths of selected files on Desktop and Common File Dialogs - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 36#p154836
Also:
WinGet, hWnd, ID, ahk_class Progman
I'd be interested as to whether FindWindowSW be used for Explorer folder windows as well as Desktop, or whether a WBGet equivalent (WBGet is for Internet Explorer) can be made for Explorer folder windows, and Desktop. I.e. one method for both Desktop and folder windows.
WBGet:
Basic Webpage Controls with JavaScript / COM - Tutorial - Tutorials - AutoHotkey Community
https://autohotkey.com/board/topic/4705 ... -tutorial/
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: Acc / AccViewer / iWB2 Learner / Anchor conversion attempts
Oh no, I wasn't suggesting changing AccViewer or IWBLearner. IWBLearner doesn't really concern me at all personally. The only thing I could add to AccViewer would be an acc event viewer - though I have no idea how to do that as I haven't studied acc events... Bear in mind that I still believe inspect.exe is a far better viewer than AccViewer if you have access to it:
Rather I believe these scripts should be put into acc.ahk itself. I know you're not the only one working with acc.ahk but a more up-to-date/feature-rich version of acc.ahk would be nice.
For example Sean's Acc_State() function lacks a huge amount of functionality and it would be better to use accObj.accState with the enums I have provided in class ACC_STATE as these are more feature rich.
Similarly functions like just me's Acc_Selection should absolutely be in the library, as libraries are meant to be general purpose and this just makes obj.accSelection actually usable.
Rather I believe these scripts should be put into acc.ahk itself. I know you're not the only one working with acc.ahk but a more up-to-date/feature-rich version of acc.ahk would be nice.
For example Sean's Acc_State() function lacks a huge amount of functionality and it would be better to use accObj.accState with the enums I have provided in class ACC_STATE as these are more feature rich.
Similarly functions like just me's Acc_Selection should absolutely be in the library, as libraries are meant to be general purpose and this just makes obj.accSelection actually usable.
Re: Acc / AccViewer / iWB2 Learner / Anchor conversion attempts
Acc/AccViewer for AHK v2 has been added to jeeswg's website.