菜鸟,每当我在文件资源管理器中时,我都会使用自动热键按修改日期排序。
问题是,在某些文件夹中,如果列的顺序不同,我的脚本就不起作用。
有人知道修改日期是否有唯一的代码吗?
答案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
}