按修改日期排序的键盘快捷键

按修改日期排序的键盘快捷键

菜鸟,每当我在文件资源管理器中时,我都会使用自动热键按修改日期排序。

问题是,在某些文件夹中,如果列的顺序不同,我的脚本就不起作用。

有人知道修改日期是否有唯一的代码吗?

答案1

可以使用辅助功能在资源管理器窗口中找到按钮(您要单击的按钮),然后以编程方式执行它。

不幸的是,下载辅助功能库的链接(acc.ahk)似乎不再有效(https://autohotkey.com/board/topic/77303-acc-library-ahk-l-updated-09272012/),因此您可能需要在其他论坛页面之一上(可能从新论坛开始)或 github 上的某个地方找到一份副本,然后在下面包含额外的扩展功能。

对于下面的代码,弄清楚如何确定使用哪个控件名称和 childPath 作为辅助功能函数的参数超出了此处解释的范围,但可以使用Spy++和来确定Accessibility Info Viewer

执行时,此代码与用鼠标单击排序列标题上的按钮具有相同的效果,因此如果以一种方式排序,则再次执行它将以另一种方式排序。

如果您想要按其他字段之一进行排序,您也可以将 myName 参数中的“日期”替换为要按其排序的其他列之一(名称、类型等)。

此代码需要acc.ahk如上所述,并且经过测试,可用于按日期对 Explorer 窗口进行排序。它还可以抵御列名的更改或移动,因为对的调用会遍历acc_doIfChildName()存在的列名列表,直到找到myName传入的参数,然后执行该按钮的默认操作。如果找不到匹配的按钮,它将返回False返回foundAndExecuted值。

#Persistent
#SingleInstance, Force
#NoEnv

;-----------------------------------------------------------------------------------------------------------------------
; Press F2 to Sort by date in any active Explorer window
;-----------------------------------------------------------------------------------------------------------------------
#IfWinActive ahk_class CabinetWClass ahk_exe Explorer.exe
F2::
    Tooltip % "Sorting by date..."  ; acc functions can take a second, show user status in progress...

    myHwnd:=ControlGet(cmd:="Hwnd", val:="", ctl:="ShellView", "ahk_class CabinetWClass ahk_exe explorer.exe")
    retVal:=acc_doIfChildName(myName:="Date", childPath:="4.1.4.1", statusBarObj:="ahk_id" myHwnd, loopBackward:=False)    

    Tooltip   ; clear status Tooltip
Return
#IfWinActive

ExitApp

#Include acc.ahk

;-----------------------------------------------------------------------------------------------------------------------
; acc_doIfChildName() - Iterate all children looking for the correct childname to try and execute...
;-----------------------------------------------------------------------------------------------------------------------
acc_doIfChildName(myName, childPathArg, myWinTitleOrObj, loopBackward:=False, startIndex:=1) {

    ;-------------------------------------------------------------------------------
    ; Set for multiple dialogs below during debugging
    ;-------------------------------------------------------------------------------
    debug:=False

    Loop, % childCount:=acc_get("childCount", childPathArg, childID:=0, myWinTitleOrObj) {

        If acc_doIfName(myName, childPath:=childPathArg "." (loopBackward ? childCount+1-A_Index : A_Index), myWinTitleOrObj)       ; Loop backwards to find faster since it will be at the end
            Return foundAndExecuted:=True
        Else If debug {
            ctlName :=acc_get("name",  childPath, childID:=0, myWinTitleOrObj)
            ctlValue:=acc_get("value", childPath, childID:=0, myWinTitleOrObj)
            MsgBox % "A_Index=" A_Index "`n" . "ctlName=" ctlName "`n" . "ctlValue=" ctlValue "`n"
        }
    }

    Return foundAndExecuted:=False
}


;-----------------------------------------------------------------------------------------------------------------------
; acc_doIfName() - doDefaultAction() if searchItemName matches the control name at childPath
;-----------------------------------------------------------------------------------------------------------------------
acc_doIfName(myName, childPath, myWinTitle) {
    Return acc_doIf("Name", myName, childPath, myWinTitle)
}



;-----------------------------------------------------------------------------------------------------------------------
; acc_doIf() - doDefaultAction() if field and value match correctly for childPath
;-----------------------------------------------------------------------------------------------------------------------
acc_doIf(accField, searchItem, childPath, myWinTitle) {

    foundAndExecuted:=False
    Try { 
        If ((ctlName:=acc_get(accField, ChildPath, childID:=0, myWinTitle))=searchItem) {

            oAcc := acc_Get("Object", ChildPath, ChildID, myWinTitle)
            oAcc.accDoDefaultAction(ChildID)
            foundAndExecuted:=True
        }
    }

    Return foundAndExecuted
}



;-----------------------------------------------------------------------------------------------------------------------
; ControlGet()
;-----------------------------------------------------------------------------------------------------------------------
ControlGet(Cmd, Value:="", Control:="", WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="") {
    ControlGet, v, % Cmd, % Value, % Control, % WinTitle, % WinText, % ExcludeTitle, % ExcludeText
    Return, v
}

相关内容