Page 1 of 1

Receive .lnk file from Explorer Context menu

Posted: 10 Jul 2017, 17:52
by JnLlnd
Hi,

The FileSelectFile has an option to retrieve the shortcut .lnk file itself instead of the target of the shortcut:
32 [v1.0.43.09+]: Shortcuts (.lnk files) are selected as-is rather than being resolved to their targets. This option also prevents navigation into a folder via a folder shortcut.
https://autohotkey.com/docs/commands/FileSelectFile.htm

My question: I am using the Explorer Context menu to add files or folders to my app. I am using the SendMessage/OnMessage commands. When I receive a file or folder from the Explorer Context menu using this technique, I always get the target file (the "resolved" file). How could I get the shortcut .lnk file itself?

If this can help, here is samples from my code:

1) This is the sample code from the .reg file used to set Explorer context menus in registry:

Code: Select all

;--------------------------------------
; ADD FILE
;--------------------------------------
[HKEY_CLASSES_ROOT\*\shell\Add File to Quick Access Popup menu]
@="Add File to Quick Access Popup menu"
"Icon"="\"C:\\Program Files\\Quick Access Popup\\QuickAccessPopup.exe\""

[HKEY_CLASSES_ROOT\*\shell\Add File to Quick Access Popup menu\command]
@="\"C:\\Program Files\\Quick Access Popup\\QAPmessenger.exe\" AddFile \"%1\""
;--------------------------------------
2) This is the code from my "background" app QAPmessenger.exe receiving the info from the Context menu command and sending it to my main app QuickAccessPopup.exe:

Code: Select all

;-----------------------------------------------------------
Send_WM_COPYDATA(ByRef strStringToSend, ByRef strTargetScriptTitle) ; ByRef saves a little memory in this case.
; Adapted from AHK documentation (https://autohotkey.com/docs/commands/OnMessage.htm)
; This function sends the specified string to the specified window and returns the reply.
; The reply is 1 if the target window processed the message, or 0 if it ignored it.
;-----------------------------------------------------------
{
    VarSetCapacity(varCopyDataStruct, 3 * A_PtrSize, 0) ; Set up the structure's memory area.
	
    ; First set the structure's cbData member to the size of the string, including its zero terminator:
    intSizeInBytes := (StrLen(strStringToSend) + 1) * (A_IsUnicode ? 2 : 1)
    NumPut(intSizeInBytes, varCopyDataStruct, A_PtrSize) ; OS requires that this be done.
    NumPut(&strStringToSend, varCopyDataStruct, 2 * A_PtrSize) ; Set lpData to point to the string itself.

	strPrevDetectHiddenWindows := A_DetectHiddenWindows
    intPrevTitleMatchMode := A_TitleMatchMode
    DetectHiddenWindows On
    SetTitleMatchMode 2
	
    SendMessage, 0x4a, 0, &varCopyDataStruct, , %strTargetScriptTitle% ; 0x4a is WM_COPYDATA. Must use Send not Post.
	
    DetectHiddenWindows %strPrevDetectHiddenWindows% ; Restore original setting for the caller.
    SetTitleMatchMode %intPrevTitleMatchMode% ; Same.
	
    return ErrorLevel ; Return SendMessage's reply back to our caller.
}
;-----------------------------------------------------------
And this code in my main app QuickAccessPopup.exe receiving the message:

Code: Select all

;------------------------------------------------------------
RECEIVE_QAPMESSENGER(wParam, lParam) 
; Adapted from AHK documentation (https://autohotkey.com/docs/commands/OnMessage.htm)
;------------------------------------------------------------
{
	global g_strAppNameText
	global g_strAppVersion
	global g_strNewLocation
	global g_strTargetClass
	global g_strTargetWinId
	
	intStringAddress := NumGet(lParam + 2*A_PtrSize) ; Retrieves the CopyDataStruct's lpData member.
	strCopyOfData := StrGet(intStringAddress) ; Copy the string out of the structure.
	StringSplit, arrData, strCopyOfData, |
	; arrData1 contains the command (AddFile, AddFolder, etc.)
	; arrData2 contains the target (the file or folder added)
	
	if InStr(arrData1, "AddFolder") and (SubStr(arrData2, -1, 2) = ":""") ; -1 extracts the 2 last characters
		; exception for drive paths
		arrData2 := SubStr(arrData2, 1, StrLen(arrData2) - 1) . "\"

	if (arrData2 = "C:""")
		arrData2 := "C:\"
	
	if (arrData1 = "AddFolder")
	{
		g_strNewLocation := arrData2
		Gosub, AddThisFolderFromMsg
	}
	else if (arrData1 = "AddFile")
	{
		g_strNewLocation := arrData2
		Gosub, AddThisFileFromMsg
	}
	else
		return 0

	return 1
}
;------------------------------------------------------------
(I removed code irrelevant to my question)

Re: Receive .lnk file from Explorer Context menu

Posted: 10 Jul 2017, 22:44
by Alguimist
Create another registry association for LNK files.

Code: Select all

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\lnkfile\shell]

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\lnkfile\shell\QAP Menu]
@="Add Shortcut File to Quick Access Popup Menu"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\lnkfile\shell\QAP Menu\Command]
@="\"C:\\Program Files\\Quick Access Popup\\QAPmessenger.exe\" AddFile \"%1\""
Right-clicking a shortcut file will show the item above for the link itself as well as "Add File to Quick Access Popup Menu" for the target file. But having those two items in the menu may confuse the user.

Re: Receive .lnk file from Explorer Context menu

Posted: 11 Jul 2017, 10:50
by JnLlnd
Alguimist wrote:Create another registry association for LNK files.

Right-clicking a shortcut file will show the item above for the link itself as well as "Add File to Quick Access Popup Menu" for the target file. But having those two items in the menu may confuse the user.
Thank you. This is an interesting approach. Maybe this label would diminish confusion:

@="Import Shortcut to Quick Access Popup Menu"

"Import" because the shortcut would be imported with its parameters (start in, state, etc.).

Thank you Alguimist.

Re: Receive .lnk file from Explorer Context menu

Posted: 13 Jul 2017, 07:02
by JnLlnd
A follow-up to close this thread. I implemented this new context menu.

Code: Select all

			;--------------------------------------
			; ADD SHORTCUT
			;--------------------------------------
			[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\lnkfile\shell\Import Windows shortcut to Quick Access Popup menu]
			@="%lContextAddShortcut%"
			"Icon"="\"%strQAPPathDoubleBackslash%\\QuickAccessPopup.ico\""

			[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\lnkfile\shell\Import Windows shortcut to Quick Access Popup menu\command]
			@="\"%strQAPPathDoubleBackslash%\\QAPmessenger.exe\" AddShortcut \"`%1\""
			;--------------------------------------
The context menu for .lnk files includes two items for QAP. I hope the labels are OK to avoid confusion.

Image

Thanks again!