Hi Folks,
The FileCreateShortcut command includes an option to specify a ShortcutKey. However, the FileGetShortcut command does not retrieve that as one of the output variables. Is there some other way to determine what the ShortcutKey is? My goal is to save and restore all aspects of a shortcut, but the inability to get the ShortcutKey via FileGetShortcut makes that impossible to do via FileCreateShortcut, as far as I can tell. Thanks much, Joe
How to get the ShortcutKey of a shortcut
- JoeWinograd
- Posts: 2213
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
-
- Posts: 4400
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: How to get the ShortcutKey of a shortcut
Hi
Try this:
I'm not sure about HOTKEYF_EXT.
Try this:
Code: Select all
lnk := A_Desktop . "\FreeMind.lnk"
S_OK := 0, STGM_READ := 0
CLSID_ShellLink := "{00021401-0000-0000-C000-000000000046}"
IID_IShellLinkA := "{000214EE-0000-0000-C000-000000000046}"
IID_IShellLinkW := "{000214F9-0000-0000-C000-000000000046}"
IID_IPersistFile := "{0000010B-0000-0000-C000-000000000046}"
IID_IShellLink := A_IsUnicode ? IID_IShellLinkW : IID_IShellLinkA
HOTKEYF_SHIFT := 0x1
HOTKEYF_CONTROL := 0x2
HOTKEYF_ALT := 0x4
HOTKEYF_EXT := 0x8
IShellLink := ComObjCreate(CLSID_ShellLink, IID_IShellLink)
GetHotkey := 12
IPersistFile := ComObjQuery(IShellLink, IID_IPersistFile)
Load := 5
XFmt := Func("Format").Bind("{:#x}")
Loop 1 {
hr := Vtable(IPersistFile, Load).Call("Ptr", &lnk, "UInt", STGM_READ, "UInt")
if (hr != S_OK && error := "IPersistFile::Load failed, error: " . XFmt.Call(hr))
break
hr := Vtable(IShellLink, GetHotkey).Call("UShortP", buff, "UInt")
(hr != S_OK && error := "IShellLink::GetHotkey failed, error: " . XFmt.Call(hr))
}
ObjRelease(IPersistFile)
ObjRelease(IShellLink)
if error
throw Exception(error)
key := GetKeyName("vk" . Format("{:X}", buff & 0xFF))
mod := buff >> 8
Shift := mod & HOTKEYF_SHIFT ? "Shift + " : ""
Ctrl := mod & HOTKEYF_CONTROL ? "Ctrl + " : ""
Alt := mod & HOTKEYF_ALT ? "Alt + " : ""
Ext := mod & HOTKEYF_EXT ? "Numpad" : "" ; not sure
MsgBox, % Shift . Ctrl . Alt . Ext . key
Vtable(ptr, n) {
return Func("DllCall").Bind(NumGet(NumGet(ptr+0), A_PtrSize*n), "Ptr", ptr)
}
Re: How to get the ShortcutKey of a shortcut
For reference, I wrote something similar here:
Get shortcut target without evaluating environment variables - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=66420
Get shortcut target without evaluating environment variables - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=66420
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
- JoeWinograd
- Posts: 2213
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: How to get the ShortcutKey of a shortcut
Hi teadrinker,
Superb! Works perfectly! HOTKEYF_EXT (NumPad) works fine, too. Tested on both W7 and W10. Thanks very much! My only problem now is that FileCreateShortcut creates all shortcut keys as Ctrl+Alt shortcuts. Cheers, Joe
Superb! Works perfectly! HOTKEYF_EXT (NumPad) works fine, too. Tested on both W7 and W10. Thanks very much! My only problem now is that FileCreateShortcut creates all shortcut keys as Ctrl+Alt shortcuts. Cheers, Joe
- JoeWinograd
- Posts: 2213
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: How to get the ShortcutKey of a shortcut
Hi jeeswg,
Thanks for the link...I'll have a look at it. Regards, Joe
Thanks for the link...I'll have a look at it. Regards, Joe
Re: How to get the ShortcutKey of a shortcut
My link includes an alternative version of FileCreateShortcut.
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
- JoeWinograd
- Posts: 2213
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: How to get the ShortcutKey of a shortcut
Does it support other than Ctrl+Alt shortcuts?jeeswg wrote:an alternative version of FileCreateShortcut
Re: How to get the ShortcutKey of a shortcut
That was the main reason I wrote the function, to handle shortcut keys generally.
Although the functions may not handle HOTKEYF_EXT (NumPad) correctly. So you might want to tweak them.
That said, if you just wanted to store shortcut information, then restore it, you could create modified versions of the functions, that get/set the raw shortcut key number, obtained via IShellLink::GetHotkey/IShellLink::SetHotkey, but that do not convert them to a friendly string.
Although the functions may not handle HOTKEYF_EXT (NumPad) correctly. So you might want to tweak them.
That said, if you just wanted to store shortcut information, then restore it, you could create modified versions of the functions, that get/set the raw shortcut key number, obtained via IShellLink::GetHotkey/IShellLink::SetHotkey, but that do not convert them to a friendly string.
Last edited by jeeswg on 02 Dec 2019, 21:21, edited 1 time 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
- JoeWinograd
- Posts: 2213
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: How to get the ShortcutKey of a shortcut
Yes, that's my entire purpose for this! I want to be able to delete a shortcut from the desktop, then restore it at a later time, fully intact.jeeswg wrote:if you just wanted to store shortcut information, then restore it
- JoeWinograd
- Posts: 2213
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: How to get the ShortcutKey of a shortcut
Hi jeeswg,
One of your comments at the thread you posted says that you updated JEE_FileGetShortcut and JEE_FileCreateShortcut. I'd like to be sure that I have the latest versions of them...please post links to both. Thanks, Joe
One of your comments at the thread you posted says that you updated JEE_FileGetShortcut and JEE_FileCreateShortcut. I'd like to be sure that I have the latest versions of them...please post links to both. Thanks, Joe
Re: How to get the ShortcutKey of a shortcut
The most up-to-date version of each function, would be the lowest-down appearance of the function definition on that page. Cheers.
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
- JoeWinograd
- Posts: 2213
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: How to get the ShortcutKey of a shortcut
Hi jeeswg,
I think I got the latest ones...JEE_FileCreateShortcut is here:
https://www.autohotkey.com/boards/viewtopic.php?f=5&t=66420#p287004
But I cannot get it to create the shortcut key...can you?
Running on W7/64-bit with v1.1.32.00/U64, if that matters. The test script that I'm using is below. It creates the shortcut with everything set properly...except for the shortcut key...that displays in the shortcut's Properties as None. Regards, Joe
I think I got the latest ones...JEE_FileCreateShortcut is here:
https://www.autohotkey.com/boards/viewtopic.php?f=5&t=66420#p287004
But I cannot get it to create the shortcut key...can you?
Running on W7/64-bit with v1.1.32.00/U64, if that matters. The test script that I'm using is below. It creates the shortcut with everything set properly...except for the shortcut key...that displays in the shortcut's Properties as None. Regards, Joe
Code: Select all
vTarget:="c:\temp\test jeeswg.txt"
vPathLink:=A_Desktop . "\test jeeswg link " . A_Now . ".lnk"
vWorkingDir:=A_ScriptDir
vArgs:="a b c"
vDescription:="shortcut description"
vIconFile:=A_AhkPath
vShortcutKey:="^!+q"
vIconNum:=4
vRunState:=1
JEE_FileCreateShortcut(vTarget,vPathLink,vWorkingDir,vArgs,vDescription,vIconFile,vShortcutKey,vIconNum,vRunState)
MsgBox,4096,Create Done,%vPathLink%
ExitApp
JEE_FileCreateShortcut(vTarget, vPathLink, vWorkingDir:="", vArgs:="", vDescription:="", vIconFile:="", vShortcutKey:="", vIconNum:=0, vRunState:="")
{
local
static IID_IShellLinkW := "{000214F9-0000-0000-C000-000000000046}"
static CLSID_ShellLink := "{00021401-0000-0000-C000-000000000046}"
static IID_IPersistFile := "{0000010b-0000-0000-C000-000000000046}"
if !(pSL := ComObjCreate(CLSID_ShellLink, IID_IShellLinkW))
return 0
;set Target
;SLGP_RAWPATH := 0x4 ;SLGP_UNCPRIORITY := 0x2 ;SLGP_SHORTPATH := 0x1 ;source: ShObjIdl.h
if DllCall(NumGet(NumGet(pSL+0) + 20*A_PtrSize), "Ptr",pSL, "WStr",vTarget) ;IShellLink::SetPath
return 0
;set WorkingDir
if !(vWorkingDir = "")
&& DllCall(NumGet(NumGet(pSL+0) + 9*A_PtrSize), "Ptr",pSL, "WStr",vWorkingDir) ;IShellLink::SetWorkingDirectory
return 0
;set Args
if !(vArgs = "")
&& DllCall(NumGet(NumGet(pSL+0) + 11*A_PtrSize), "Ptr",pSL, "WStr",vArgs) ;IShellLink::SetArguments
return 0
;set Description
if !(vDescription = "")
&& DllCall(NumGet(NumGet(pSL+0) + 7*A_PtrSize), "Ptr",pSL, "WStr",vDescription) ;IShellLink::SetDescription
return 0
;set IconFile and IconNum
if !(vIconFile = "")
&& DllCall(NumGet(NumGet(pSL+0) + 17*A_PtrSize), "Ptr",pSL, "WStr",vIconFile, "Int",vIconNum) ;IShellLink::SetIconLocation
return 0
if !(vShortcutKey = "")
{
vHotkeyNum := 0
if RegExMatch(vShortcutKey, "^.?\+.")
{
vHotkeyNum |= (0x1 << 8) ;HOTKEYF_SHIFT := 0x1
vShortcutKey := StrReplace(vShortcutKey, "+", "",, 1)
}
if RegExMatch(vShortcutKey, "^.?\^.")
{
vHotkeyNum |= (0x2 << 8) ;HOTKEYF_CONTROL := 0x2
vShortcutKey := StrReplace(vShortcutKey, "^", "",, 1)
}
if RegExMatch(vShortcutKey, "^.?!.")
{
vHotkeyNum |= (0x4 << 8) ;HOTKEYF_ALT := 0x4
vShortcutKey := StrReplace(vShortcutKey, "!", "",, 1)
}
if vVK := GetKeyVK(vShortcutKey)
vHotkeyNum |= vVK
if vVK
&& DllCall(NumGet(NumGet(pSL+0) + 13*A_PtrSize), "Ptr",pSL, "UShort",vHotkeyNum) ;IShellLink::SetHotkey
return 0
}
if !(vRunState = "")
&& DllCall(NumGet(NumGet(pSL+0) + 15*A_PtrSize), "Ptr",pSL, "Int",vRunState) ;IShellLink::SetShowCmd
return 0
if !(pPF := ComObjQuery(pSL, IID_IPersistFile))
return 0
vSize := DllCall("kernel32\GetFullPathNameW", "WStr","\\?\" vPathLink, "UInt",0, "Ptr",0, "Ptr*",0, "UInt")
VarSetCapacity(vPath2, vSize*2, 0)
if !DllCall("kernel32\GetFullPathNameW", "WStr","\\?\" vPathLink, "UInt",vSize, "Ptr",&vPath2, "Ptr*",0, "UInt")
return 0
if DllCall(NumGet(NumGet(pPF+0) + 6*A_PtrSize), "Ptr",pPF, "Ptr",&vPath2, "Int",1) ;IPersistFile::Save
return 0
ObjRelease(pPF)
ObjRelease(pSL)
return 1
}
Re: How to get the ShortcutKey of a shortcut
Try vShortcutKey:="+^!q".
There's a slight issue with the RegEx, I'll post again when I've replaced it with something slightly more intuitive.
There's a slight issue with the RegEx, I'll post again when I've replaced it with something slightly more intuitive.
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
- JoeWinograd
- Posts: 2213
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: How to get the ShortcutKey of a shortcut
That works!vShortcutKey:="+^!q"
Looking forward to it, but it's almost 3:00am in my neck of the woods, so this is my last post for the night. Will check back into the thread first thing in my morning. Regards, JoeI'll post again when I've replaced it with something slightly more intuitive.
Re: How to get the ShortcutKey of a shortcut
OK. Done.
I'm thinking we need a built-in HotkeySplit function.
So +^!a would split to +^! and a.
That might seem like a relatively minor function to have.
However, the way AHK parses hotkeys is pretty complex, and only if it were built-in, would it be really reliable.
And extra modifiers like $ would have to be handled also.
So I think it's just about worth implementing, and hopefully should be relatively trivial since AutoHotkey already contains the logic to do this.
Similarly, it would be useful to have an IsHotkey or IsValidHotkey function.
One use would be in parsing AHK scripts.
does string look like a hotkey - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=58131
Cheers.
I'm thinking we need a built-in HotkeySplit function.
So +^!a would split to +^! and a.
Code: Select all
;q:: ;test split hotkeys
vList := " ;continuation section
(
!+^q
!^+q
+!^q
+^!q
^!+q
^+!q
!+q
!^q
+!q
+^q
^!q
^+q
!q
+q
^q
q
)"
vList2 := vList
vList2 .= "`n" StrReplace(vList, "q", "Left")
vList2 .= "`n" StrReplace(vList, "q", "")
vList2 .= "`n" StrReplace(vList, "q", "+")
vList2 .= "`n" StrReplace(vList, "q", "^")
vList2 .= "`n" StrReplace(vList, "q", "!")
vIsV1 := RegExMatch("", "", o) && !IsObject(o)
vPfx := vIsV1 ? "O)" : ""
vOutput := ""
Loop Parse, vList2, % "`n", % "`r"
{
vHotkey := A_LoopField
RegExMatch(vHotkey, vPfx "^([+^!]{0,3})(.+)$", oMatch)
vOutput .= vHotkey "`t" oMatch.1 "`t" oMatch.2 "`r`n"
}
Clipboard := vOutput
MsgBox, % "done"
return
That might seem like a relatively minor function to have.
However, the way AHK parses hotkeys is pretty complex, and only if it were built-in, would it be really reliable.
And extra modifiers like $ would have to be handled also.
So I think it's just about worth implementing, and hopefully should be relatively trivial since AutoHotkey already contains the logic to do this.
Similarly, it would be useful to have an IsHotkey or IsValidHotkey function.
One use would be in parsing AHK scripts.
does string look like a hotkey - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=58131
Cheers.
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
- JoeWinograd
- Posts: 2213
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: How to get the ShortcutKey of a shortcut
Hi jeeswg,
Thanks for the updates. Just tested both on W7...worked perfectly! Btw, you should change a comment there...both sentences before the links say, "Get shortcut target..." You should change the second one to say, "Create shortcut target..."
Interesting idea on the HotkeySplit and IsValidHotkey functions...post them on the Wish List.
Thanks again to both teadrinker and you...great stuff! Regards, Joe
Thanks for the updates. Just tested both on W7...worked perfectly! Btw, you should change a comment there...both sentences before the links say, "Get shortcut target..." You should change the second one to say, "Create shortcut target..."
Interesting idea on the HotkeySplit and IsValidHotkey functions...post them on the Wish List.
Thanks again to both teadrinker and you...great stuff! Regards, Joe
Re: How to get the ShortcutKey of a shortcut
In the post, I'd written the thread title (which starts with 'Get shortcut target') before each of the 2 urls, I've now removed the thread titles, leaving just the urls. Good suggestion. Thanks.
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