问题
I'm using Firefox and I was looking for an autohotkey script which would enable me to skip the whole series of clicks when I bookmark a page in a specific folder and replace it with a single keyboard shortcut.
Although I've read forum threads on Autohotkey forum and here I still don't know how to make a working script that would reduce bookmarking a page to hitting a keyboard shortcut and the initial letter of the folder where I want to store that page. Using KeyWait command I've made it work for a single folder and don't know how to make it work for any letter or a number that I could possibly use as a name for a bookmark folder. Say I have a folder named XXXX, this script does send the webpage to the XXXX folder after hitting the assigned shortcut and the letter x (MouseClick command is needed to focus the window with folder in the Bookmark Dialog pane):
!+^w::
Send,^d
Sleep,400
MouseClick,Left,864,304
Sleep,400
KeyWait, x ,D
Sleep, 400
Send,^{Enter}
return
I don't know how to make this script work for any letter or number, not only for a single one. Also a big problem with this script is that it blocks the keyboard until I hit X key. If I have that page bookmarked already, hitting escape to remove the bookmark pane will block the keyboard and I can unblock it only if I rerun the autohotkey script.
I've also tried using Input command as the contributors the Autohotkey forum pages suggested, but it didn't work either, because I don't understand how the Input command works. I did make it work for a single letter as the above script with KeyWait, but that's the best I could do. This script also blocks the keyboard until the letter is hit:
!+^w::
Send,^d
MouseClick,Left,864,304
Sleep,400
Input, Character, L1
If Character = t
Send, t
Sleep,400
Send,^{Enter}
return
Hope someone can help me with this, it would be convenient simplifying the bookmarking process in Firefox this way.
回答1:
I have a nice idea. This will open the add bookmark dialog and navigate you into the folder selection part and expand all folders. All you need to do is enter the folders name (or a part of it) and it will get selected automatically. When you're done, just hit enter.
!+^w:: ;Hotkey: Ctrl+Alt+Shift+w
Send, ^d ;send Ctrl+d to open the add-bookmark dialog
Sleep, 500 ;wait for the dialog to open
Send, {Tab}{Tab}{Enter} ;navigate into the folder selection
Sleep, 300 ;wait to make sure we are there
Send,{Home} ;select the first item in the list
;The following line should expand all the folders so that you can just type the folders name to search for it
Loop, 100 { ;Increase the number if it doesn't expand all folders
SendInput, {Right}{Down} ;expand folders
}
Send, {Home} ;navigate to the first item in the list again
Input, L, V L1 T2 ;wait until you start typing a folder name (if you just wait 2 seconds, the bookmark won't be created)
If (ErrorLevel = "Timeout") {
Send, {Tab 5} ;press tab 5 times to navigate to the cancel button
Send, {Enter} ;cancel the bookmark
Return ;end of the hotkey
}
Loop { ;wait until you haven't typed a new letter for 0.4 seconds
Input, L, V L1 T0.4
If (ErrorLevel = "Timeout")
Break
}
Send, {Tab 4} ;press tab 4 times to navigate to the enter button
Send, {Enter} ;save the bookmark
Return
回答2:
My variant. Press f1 to create bookmark in folder test1. Press f2 to create bookmark in folder test2.
SetBatchLines, -1
Folders := {F1: "test1", F2: "test2"}
#IfWinActive, ahk_class MozillaWindowClass
F1::
F2::
Folder := Folders[A_ThisHotkey]
Send, ^d
AccFirefox := Acc_ObjectFromWindow(WinExist("ahk_class MozillaWindowClass"))
AccElem := SearchElement(AccFirefox, ROLE_SYSTEM_LISTITEM := 0x22, Folder, "")
AccElem.accDoDefaultAction(0)
sleep 100
Send {Enter}
msgbox done
return
#IfWinActive
SearchElement(ParentElement, params*)
{
found := 1
for k, v in params {
(k = 1 && ParentElement.accRole(0) != v && found := "")
(k = 2 && ParentElement.accName(0) != v && found := "")
(k = 3 && ParentElement.accValue(0) != v && found := "")
}
if found
Return ParentElement
for k, v in Acc_Children(ParentElement)
if obj := SearchElement(v, params*)
Return obj
}
Acc_Init()
{
Static h
If Not h
h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromWindow(hWnd, idObject = 0)
{
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
Return ComObjEnwrap(9,pacc,1)
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
try return ComObj(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.Insert(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)
}
来源:https://stackoverflow.com/questions/32358449/autohotkey-script-to-bookmark-to-a-specific-folder