通过 ACC 机能实现左键双击 TC 空白处返回上级目录

判定TC中空白处是一个困难,一些截图软件例如QQ截图、Snipaste等可以判断屏幕上一些远小于控件的元素,查阅发现是一种适合屏幕阅读的功能——ACC,尝试通过这种方式实现功能。

判定TC中空白处是一个困难,一些截图软件例如QQ截图、Snipaste等可以判断屏幕上一些远小于控件的元素,查阅发现是一种适合屏幕阅读的功能——ACC,尝试通过这种方式实现功能。

为防止窗口被列表占满,特地添加了右键双击功能。

#SingleInstance, Force
#NoEnv
;~ #Persistent
/*
提权, 使用管理员模式
*/
if not A_IsAdmin
{
    Run *RunAs "%A_ScriptFullPath%"  ; 需要 v1.0.92.01+
    ExitApp
}
;~ 定义基本全局变量
global TCWins:={}, TCTitle := "ahk_class TTOTAL_CMD", DClkDelay:=300

;~ 建立TC的对象
loop 4
{
    TCWins[A_Index] := {Name:"LCLListBox" A_Index}
}

;~ 监控计时
SetTimer, MouseOver, 1

;~ 首次检测
TestTCWin()
;~ sbox(TCWins)

;~ 快捷键定义
Hotkey, IfWinActive, % TCTitle
Hotkey, ~LButton, ButtonClick
Hotkey, ~RButton, ButtonClick

return
;~ 通过定义对象判断TC窗口控件
/*
数据结构  LCLListBox 四个控件会随机成为TC左右窗,因此要进行判断
这个对象收集基本信息,可能一些信息在本例子中用不到,但思路是建立数据,方便扩展
0001: 键名:< 1 >                                      4个窗口的编号
0002:   |-键名:< CanClick >                           是否列表窗口
0002:   |-键名:< Name >  键值:< LCLListBox1 >           名称
0002:   |-键名:< NotTree >                            判定控件是否树窗口状态
0002:   |-键名:< Visible >  键值:< 1 >                  是否当前可用
0001: 键名:< 2 >  
0002:   |-键名:< CanClick >  键值:< 1 >
0002:   |-键名:< Name >  键值:< LCLListBox2 >
0002:   |-键名:< NotTree >  键值:< 1 >
0002:   |-键名:< Visible >  键值:< 1 >
0001: 键名:< 3 >  
0002:   |-键名:< CanClick >  键值:< 1 >
0002:   |-键名:< Name >  键值:< LCLListBox3 >
0002:   |-键名:< NotTree >  键值:< 1 >
0002:   |-键名:< Visible >  键值:< 1 >
0001: 键名:< 4 >  
0002:   |-键名:< CanClick >  
0002:   |-键名:< Name >  键值:< LCLListBox4 >
0002:   |-键名:< NotTree >  键值:< 1 >
0002:   |-键名:< Visible >  
0001: 键名:< LCLListBox2 >                        控件名
0002:   |-键名:< 1 >  键值:< 2 >                    对应编号
0002:   |-键名:< 2 >  键值:< 0x20ae8 >              实时 hwnd 值
0001: 键名:< LCLListBox3 >  
0002:   |-键名:< 1 >  键值:< 3 >
0002:   |-键名:< 2 >  键值:< 0x20aee >
*/
TestTCWin()
{
    loop 4
    {
        tObj := TCWins[A_Index]
        ControlGetText, text, % tObj.Name, % TCTitle
        ControlGet, Visible, Visible,, % tObj.Name, % TCTitle
        tObj.NotTree := !(text~="W_TreeList")
        	, tObj.Visible := Visible
        	, tObj.CanClick := tObj.NotTree && tObj.Visible
        	, TCWins["LCLListBox" A_Index] := tObj.CanClick?[A_Index, getClassNNHwnd("LCLListBox" A_Index)]:
    }
}
;~ 激发双击模式后的处理
ButtonClick:
;~ 是否双击判定
    if (A_ThisHotkey!=A_PriorHotkey)
        return
;~ 双击延迟判定
    if (A_TimeSincePriorHotkey>DClkDelay)
        return
;~ 当前是否可双击
    if !isCanClick
        return
;~ 获取当前鼠标下控件的ACC状态,byref 变量 Child 可判定当前鼠标下是否有子Acc模块,如有则不是“空白处”
    MouseGetPos, OutputVarX, OutputVarY
    Acc_ObjectFromPoint(Child, OutputVarX, OutputVarY)
;~ 判定是否空白处双击,是则发送返回上层目录消息
;~ 发送消息的防错能力远高于发送键击
    if  (RB:=RegExMatch(A_ThisHotkey, "^~R")) || !Child && !RB
        Postmessage, 1075, 2002,,, % TCTitle
return
;~ 监控鼠标悬停状态,功能是减少程序占用
MouseOver:
;~ 监控当前是否悬停于TC上
    WinGetClass, OutputVar, A
    if !(isTCWin := RegExMatch(TCTitle,OutputVar))
    {
        return
    }
;~ 获取当前悬停控件
    MouseGetPos, , , , OutputVaRControl
    TestTCWin()
    OutputVaRControl := Trim(OutputVaRControl)
        , isNotOut:=(OldOutputVaRControl=OutputVaRControl)
;~ 悬停控件是否切换,
    if isNotOut
        return
    OldOutputVaRControl := OutputVaRControl
;~ 悬停于左右窗口时全速运行,否则降低占用
    if (isCanClick:=TCWins[OutputVaRControl])
    {
        SetBatchLines, -1
    }
    else
    {
        SetBatchLines, 20ms
    }
return

getClassNNHwnd(ClassNN:="")
{
    ControlGet, Hwnd, Hwnd,, % ClassNN, % TCTitle
    return Hwnd
}


;~ Acc代码

Acc_Init()
{
    Static	h
    if Not	h
        h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
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
        return	ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

 

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

TC 文件夹双击返回上级目录

2017-4-22 13:51:47

其他案例

[办公][输入法]input-ahk 0.2: 用ahk写一个简单的输入法

2017-4-28 18:43:38

3 条回复 A文章作者 M管理员
  1. Jeffrey

    非常感谢大神完善,不过我测试了下acc鼠标下控件判断,发现不是很有效,有时候误判,比如点击文件夹时候检测出来控件数为0

    • 昏睡墨鱼

      这个样本是判定鼠标下ACC元素未原则的,而且是实施了双击动作以后才进行判断,可能实现过程有瑕疵,对 ACC 的机理了解不是很透彻. 还是希望有大神能够解惑.

      纯属抛砖引玉了

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