Open Context Menu (Function) Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
F4Jonatas
Posts: 45
Joined: 22 Oct 2015, 06:35
Contact:

Open Context Menu (Function)

09 Feb 2017, 14:18

Is there any way to open the context menu of any file?

Image
User avatar
F4Jonatas
Posts: 45
Joined: 22 Oct 2015, 06:35
Contact:

Re: Open Context Menu (Function)

10 Feb 2017, 06:36

Exactly what I was looking for. :salute:

I have decided to remove lines 6, 7, 8 and 78.
On line 5 I changed the variable "win_hwnd"


"WindowProc" function does not work in 32 bits?

Code: Select all

ShellContextMenu( sPath, win_hwnd = 0 ) {
   if ( !sPath  )
      return
   if !win_hwnd
   win_hwnd := DllCall( "User32.dll\FindWindow", "Str", "AutoHotkey", "Str", A_ScriptFullPath ( A_IsCompiled ? "" : " - AutoHotkey v" A_AhkVersion ))

   If sPath Is Not Integer
      DllCall("shell32\SHParseDisplayName", "Wstr", sPath, "Ptr", 0, "Ptr*", pidl, "Uint", 0, "Uint*", 0)
      ;This function is the preferred method to convert a string to a pointer to an item identifier list (PIDL).
   else
      DllCall("shell32\SHGetFolderLocation", "Ptr", 0, "int", sPath, "Ptr", 0, "Uint", 0, "Ptr*", pidl)
   DllCall("shell32\SHBindToParent", "Ptr", pidl, "Ptr", GUID4String(IID_IShellFolder,"{000214E6-0000-0000-C000-000000000046}"), "Ptr*", pIShellFolder, "Ptr*", pidlChild)
   ;IShellFolder->GetUIObjectOf
   DllCall(VTable(pIShellFolder, 10), "Ptr", pIShellFolder, "Ptr", 0, "Uint", 1, "Ptr*", pidlChild, "Ptr", GUID4String(IID_IContextMenu,"{000214E4-0000-0000-C000-000000000046}"), "Ptr", 0, "Ptr*", pIContextMenu)
   ObjRelease(pIShellFolder)
   CoTaskMemFree(pidl)

   hMenu := DllCall("CreatePopupMenu")
   ;IContextMenu->QueryContextMenu
   ;http://msdn.microsoft.com/en-us/library/bb776097%28v=VS.85%29.aspx
   DllCall(VTable(pIContextMenu, 3), "Ptr", pIContextMenu, "Ptr", hMenu, "Uint", 0, "Uint", 3, "Uint", 0x7FFF, "Uint", 0x100)   ;CMF_EXTENDEDVERBS
   ComObjError(0)
      global pIContextMenu2 := ComObjQuery(pIContextMenu, IID_IContextMenu2:="{000214F4-0000-0000-C000-000000000046}")
      global pIContextMenu3 := ComObjQuery(pIContextMenu, IID_IContextMenu3:="{BCFCE0A0-EC17-11D0-8D10-00A0C90F2719}")
   e := A_LastError ;GetLastError()
   ComObjError(1)
   if (e != 0)
      goTo, StopContextMenu
   Global   WPOld:= DllCall("SetWindowLongPtr", "Ptr", win_hwnd, "int",-4, "Ptr",RegisterCallback("WindowProc"),"UPtr")
   DllCall("GetCursorPos", "int64*", pt)
   DllCall("InsertMenu", "Ptr", hMenu, "Uint", 0, "Uint", 0x0400|0x800, "Ptr", 2, "Ptr", 0)
   DllCall("InsertMenu", "Ptr", hMenu, "Uint", 0, "Uint", 0x0400|0x002, "Ptr", 1, "Ptr", &sPath)

   idn := DllCall("TrackPopupMenuEx", "Ptr", hMenu, "Uint", 0x0100|0x0001, "int", pt << 32 >> 32, "int", pt >> 32, "Ptr", win_hwnd, "Uint", 0)

   /*
typedef struct _CMINVOKECOMMANDINFOEX {
   DWORD   cbSize;          0
   DWORD   fMask;           4
   HWND    hwnd;            8
   LPCSTR  lpVerb;          8+A_PtrSize
   LPCSTR  lpParameters;    8+2*A_PtrSize
   LPCSTR  lpDirectory;     8+3*A_PtrSize
   int     nShow;           8+4*A_PtrSize
   DWORD   dwHotKey;        12+4*A_PtrSize
   HANDLE  hIcon;           16+4*A_PtrSize
   LPCSTR  lpTitle;         16+5*A_PtrSize
   LPCWSTR lpVerbW;         16+6*A_PtrSize
   LPCWSTR lpParametersW;   16+7*A_PtrSize
   LPCWSTR lpDirectoryW;    16+8*A_PtrSize
   LPCWSTR lpTitleW;        16+9*A_PtrSize
   POINT   ptInvoke;        16+10*A_PtrSize
   } CMINVOKECOMMANDINFOEX, *LPCMINVOKECOMMANDINFOEX;
   http://msdn.microsoft.com/en-us/library/bb773217%28v=VS.85%29.aspx
   */
   struct_size  :=  16+11*A_PtrSize
   VarSetCapacity(pici,struct_size,0)
   NumPut(struct_size,pici,0,"Uint")         ;cbSize
   NumPut(0x4000|0x20000000|0x00100000,pici,4,"Uint")   ;fMask
   NumPut(win_hwnd,pici,8,"UPtr")       ;hwnd
   NumPut(1,pici,8+4*A_PtrSize,"Uint")       ;nShow
   NumPut(idn-3,pici,8+A_PtrSize,"UPtr")     ;lpVerb
   NumPut(idn-3,pici,16+6*A_PtrSize,"UPtr")  ;lpVerbW
   NumPut(pt,pici,16+10*A_PtrSize,"Uptr")    ;ptInvoke

   DllCall(VTable(pIContextMenu, 4), "Ptr", pIContextMenu, "Ptr", &pici)   ; InvokeCommand

   DllCall("GlobalFree", "Ptr", DllCall("SetWindowLongPtr", "Ptr", win_hwnd, "int", -4, "Ptr", WPOld,"UPtr"))
   DllCall("DestroyMenu", "Ptr", hMenu)
StopContextMenu:
   ObjRelease(pIContextMenu3)
   ObjRelease(pIContextMenu2)
   ObjRelease(pIContextMenu)
   pIContextMenu2:=pIContextMenu3:=WPOld:=0
   return idn
}
WindowProc(hWnd, nMsg, wParam, lParam)
{
   Global   pIContextMenu2, pIContextMenu3, WPOld
   If   pIContextMenu3
   {    ;IContextMenu3->HandleMenuMsg2
      If   !DllCall(VTable(pIContextMenu3, 7), "Ptr", pIContextMenu3, "Uint", nMsg, "Ptr", wParam, "Ptr", lParam, "Ptr*", lResult)
         Return   lResult
   }
   Else If   pIContextMenu2
   {    ;IContextMenu2->HandleMenuMsg
      If   !DllCall(VTable(pIContextMenu2, 6), "Ptr", pIContextMenu2, "Uint", nMsg, "Ptr", wParam, "Ptr", lParam)
         Return   0
   }
   Return   DllCall("user32.dll\CallWindowProcW", "Ptr", WPOld, "Ptr", hWnd, "Uint", nMsg, "Ptr", wParam, "Ptr", lParam)
}
VTable(ppv, idx)
{
   Return   NumGet(NumGet(1*ppv)+A_PtrSize*idx)
}
GUID4String(ByRef CLSID, String)
{
   VarSetCapacity(CLSID, 16,0)
   return DllCall("ole32\CLSIDFromString", "wstr", String, "Ptr", &CLSID) >= 0 ? &CLSID : ""
}
CoTaskMemFree(pv)
{
   Return   DllCall("ole32\CoTaskMemFree", "Ptr", pv)
}
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
Contact:

Re: Open Context Menu (Function)

10 Feb 2017, 06:58

F4Jonatas wrote:"WindowProc" function does not work in 32 bits?
SetWindowLongPtr doesn't exist in a 32-bit user32.dll. Try replacing Global WPOld:= DllCall("SetWindowLongPtr", "Ptr", win_hwnd, "int",-4, "Ptr",RegisterCallback("WindowProc"),"UPtr") with Global WPOld:= DllCall(A_PtrSize == 8 ? "SetWindowLongPtr" : "SetWindowLong", "Ptr", win_hwnd, "int",-4, "Ptr",RegisterCallback("WindowProc"),"Ptr")

Code: Select all

win_hwnd := DllCall( "User32.dll\FindWindow", "Str", "AutoHotkey", "Str", A_ScriptFullPath ( A_IsCompiled ? "" : " - AutoHotkey v" A_AhkVersion ))
A_ScriptHwnd
User avatar
F4Jonatas
Posts: 45
Joined: 22 Oct 2015, 06:35
Contact:

Re: Open Context Menu (Function)

12 Feb 2017, 07:59

are you aware that Shift+F10 opens the context menu for the currently selected item?
Yes. But what I want is to open the context menu of another app.
Qwerty already solved this for me.
:salute:
User avatar
lmstearn
Posts: 688
Joined: 11 Aug 2016, 02:32
Contact:

Re: Open Context Menu (Function)

14 May 2020, 11:52

As a matter of interest, all the menu functions in @F4Jonatas's modification work on this machine except for the dialog of the properties item at the bottom of the list. (User_as_Admin related?)
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Open Context Menu (Function)

14 May 2020, 15:24

Try this:

Code: Select all

filePath := "C:\MyFile.ext"
if !RunFileContextMenuItem(filePath, "Properties")
   MsgBox, "Properties" item not found
else {
   while !WinExist("ahk_class #32770 ahk_pid " . DllCall("GetCurrentProcessId"))
      Sleep, 50
   while WinExist()
      Sleep, 50
}

RunFileContextMenuItem(filePath, contextMenuItemName) {
   SplitPath, filePath, fileName, dir
   (!dir && dir := A_ScriptDir)
   try Folder := ComObjCreate("Shell.Application").Namespace(dir)
   catch
      Return
   for Item in Folder.Items {
      if (Item.Name != fileName)
         continue
      Loop % Item.Verbs.Count {
         Verb := Item.Verbs.Item(A_Index - 1)
         if StrReplace(Verb.Name, "&") = StrReplace(contextMenuItemName, "&") && found := true
            break 2
      }
   }
   if found {
      Verb.DoIt()
      Return true
   }
}
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Open Context Menu (Function)

17 May 2020, 11:30

You can open context menu on some elements with IUIAutomationElement3::ShowContextMenu method. Win 8.1+
https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement3-showcontextmenu
This will open context menu of "This PC" icon on desktop:

Code: Select all

name := "This PC"

f11::
if !hwnd
{
   ControlGet, hwnd, hwnd,, SysListView321, ahk_class Progman
   if (hwnd = "")
      ControlGet, hwnd, hwnd,, SysListView321, ahk_class WorkerW
   IUIAutomation := ComObjCreate(CLSID_CUIAutomation := "{ff48dba4-60ef-4201-aa87-54103eef594e}", IID_IUIAutomation := "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")
   DllCall(NumGet(NumGet(IUIAutomation+0)+6*A_PtrSize), "ptr", IUIAutomation, "ptr", hwnd, "ptr*", element)   ; IUIAutomation::ElementFromHandle
   name := DllCall("oleaut32\SysAllocString", "str", name, "ptr")
   VarSetCapacity(variant, 8+A_PtrSize*2, 0)
   NumPut(VT_BSTR := 8, variant, 0, "ushort")
   NumPut(name, variant, 8, "ptr")
   DllCall("oleaut32\SysFreeString", "ptr", name)
   if (A_PtrSize = 4)
      DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_NamePropertyId := 30005, "int64", NumGet(variant, 0, "int64"), "int64", NumGet(variant, 8, "int64"), "ptr*", condition)   ; IUIAutomation::CreatePropertyCondition
   else
      DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_NamePropertyId := 30005, "ptr", &variant, "ptr*", condition)   ; IUIAutomation::CreatePropertyCondition
}
DllCall(NumGet(NumGet(element+0)+5*A_PtrSize), "ptr", element, "int", TreeScope_Descendants := 0x4, "ptr", condition, "ptr*", FoundElement) ; IUIAutomationElement::FindFirst
DllCall(NumGet(NumGet(FoundElement+0)+91*A_PtrSize), "ptr", FoundElement)   ; IUIAutomationElement3::ShowContextMenu
ObjRelease(FoundElement)
User avatar
lmstearn
Posts: 688
Joined: 11 Aug 2016, 02:32
Contact:

Re: Open Context Menu (Function)

24 May 2020, 01:48

Sorry, about the delay getting back, thanks for the responses.
@Malcev: Very interesting approach, however, nothing here. The last two functions produce a blank for FoundElement on Win10.

Code: Select all

msgbox % " NumGet(IUIAutomation+0) " NumGet(IUIAutomation+0) " NumGet(element+0) " NumGet(element+0) " NumGet(FoundElement+0) " NumGet(FoundElement+0)
@Teadrinker: Great, that works, thanks.
Had a go at integrating that into @querty's script. There's no straight-forward path to instant success.
Played around with it a bit. Launching the menu from another thread gets the menu and properties working. There's also an attempt to get the original GUI launcher thread to intercept the menu messages- no dice.

Code: Select all

#NoEnv
#SingleInstance, Off
SetWorkingDir, %A_ScriptDir%
;WM_MENUCOMMAND = 0x126
;OnMessage(WM_MENUCOMMAND, Checkprops)
noCheckProps := -1

SplitPath A_ScriptFullPath,,,,MutexName

    ;-----------------------------------
    ; check named mutex object
    ;-----------------------------------
    If (hMutex := DllCall("OpenMutex", "Int", 0x100000, "Int", NULL, "Str", MutexName))
	{
	; show menu then quit
		if !(win_hwnd := DllCall( "User32.dll\FindWindow", "Str", "AutoHotkey", "Str", A_ScriptFullPath ( A_IsCompiled ? "" : " - AutoHotkey v" A_AhkVersion )))
		Return

	ShellContextMenu( A_ScriptFullPath, hMenu, win_hwnd)

	sleep 6000

	ExitApp
	}
	else
	{

    ;-----------------------------------
    ; use a GUI to keep script running
    ;-----------------------------------

    Gui,New, hWNDguiHwnd
	;Gui, Margin, % A_ScreenWidth/18, % A_ScreenHeight/18
	Gui, Add, Text,, Timeout for`nmenu is 6000
    Gui, Show,, Mutex

	; https://autohotkey.com/board/topic/80644-how-to-hook-on-to-shell-to-receive-its-messages/
	DllCall( "RegisterShellHookWindow", UInt,guiHwnd )
	MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )

	;LastActiveWindowID := WinActive("A")	

    ;-----------------------------------
    ; create named mutex object
    ;-----------------------------------\

    hMutex := DllCall("CreateMutex", "Int",NULL, "Int",False, "Str", MutexName)



	
	ComObjCreate("Shell.Application").Windows.FindWindowSW(0, 0, 8, 0, 1).Document.Application.ShellExecute(Chr(34) A_ScriptFullPath Chr(34))
	Sleep 50
	OnMessage( MsgNum, "ShellMessage" )

	noCheckProps := 0

	/*; Nada working
	hHook := DllCall("SetWinEventHook","UInt",0x0004,"UInt",0x0006,"Ptr",0,"Ptr",RegisterCallback("Checkprops"),"UInt",DllCall("GetCurrentProcessId"),"UInt",0,"UInt",0)
	;EVENT_SYSTEM_MENUPOPUPSTART := 0x0006 EVENT_SYSTEM_MENUSTART := 0x0004
	msgbox % nhook
	OnExit( Func("FreeResource").Bind(hHook) )
	*/

	

	}

Return


ShellMessage( wParam,lParam )
{

	If ( wParam == 32772) ;wParam = 9 : HSHELL_SYSMENU := 9
	Checkprops()
}


;-------------------------------------------------------------------------------
GuiClose: ; clean up
;-------------------------------------------------------------------------------
SetTitleMatchMode, 3

While WinExist(MutexName . ".ahk")
{
	WinGet, PID , PID, %hMutex%
	Process, Close, ahk_pid %PID%
	DllCall("ReleaseMutex", Ptr,hMutex)
}
exitapp

FreeResource(hHook)
{
   DllCall("UnhookWindowsHookEx", "Ptr", hHook)
}

Checkprops()
{
Global
	if (noCheckProps)
	Return


	if !(x := ReadPipe())
	{
	msgbox Error reading pipe. 
	Return
	}

hmenu := Substr(x, 1, Instr(x, ",") - 1)
win_hwnd := Substr(x, Instr(x, ",") + 1)
selectedItem := DllCall("TrackPopupMenuEx", "Ptr", hMenu, "Uint", 0x0100|0x0001, "int", pt << 32 >> 32, "int", pt >> 32, "Ptr", win_hwnd, "Uint", 0)
itemCount := DllCall("GetMenuItemCount", "Ptr", hMenu)
msgbox % " GUI thread:`nhmenu " hmenu " win_hwnd " win_hwnd "`nitemCount seems to populate the first time this script is run. In subsequent runs it may not for various reasons including mouse hover, object release etc..`nitemCount " itemCount "`nselectedItem is not captured at all in this iteration of the script.`nselectedItem " selectedItem

if (itemCount = selectedItem)
{
	if !RunFileContextMenuItem(A_ScriptFullPath, "Properties")
	MsgBox, "Properties" item not found
	else
	{
		while !WinExist("ahk_class #32770 ahk_pid " . DllCall("GetCurrentProcessId"))
		Sleep, 50
		while WinExist()
		Sleep, 50
	noCheckProps := 1
	}
}
}


ShellContextMenu( sPath, byref hMenu, byref win_hwnd := 0 )
{
		if ( !sPath  )
		return

		If sPath Is Not Integer
		DllCall("shell32\SHParseDisplayName", "Wstr", sPath, "Ptr", 0, "Ptr*", pidl, "Uint", 0, "Uint*", 0)
		;This function is the preferred method to convert a string to a pointer to an item identifier list (PIDL).
		else
		DllCall("shell32\SHGetFolderLocation", "Ptr", 0, "int", sPath, "Ptr", 0, "Uint", 0, "Ptr*", pidl)
	
	
	DllCall("shell32\SHBindToParent", "Ptr", pidl, "Ptr", GUID4String(IID_IShellFolder,"{000214E6-0000-0000-C000-000000000046}"), "Ptr*", pIShellFolder, "Ptr*", pidlChild)
	;IShellFolder->GetUIObjectOf
	DllCall(VTable(pIShellFolder, 10), "Ptr", pIShellFolder, "Ptr", 0, "Uint", 1, "Ptr*", pidlChild, "Ptr", GUID4String(IID_IContextMenu,"{000214E4-0000-0000-C000-000000000046}"), "Ptr", 0, "Ptr*", pIContextMenu)
	ObjRelease(pIShellFolder)
	CoTaskMemFree(pidl)

	hMenu := DllCall("CreatePopupMenu")
	;IContextMenu->QueryContextMenu
	;http://msdn.microsoft.com/en-us/library/bb776097%28v=VS.85%29.aspx
	DllCall(VTable(pIContextMenu, 3), "Ptr", pIContextMenu, "Ptr", hMenu, "Uint", 0, "Uint", 3, "Uint", 0x7FFF, "Uint", 0x100)   ;CMF_EXTENDEDVERBS
	ComObjError(0)
	global pIContextMenu2 := ComObjQuery(pIContextMenu, IID_IContextMenu2:="{000214F4-0000-0000-C000-000000000046}")
	global pIContextMenu3 := ComObjQuery(pIContextMenu, IID_IContextMenu3:="{BCFCE0A0-EC17-11D0-8D10-00A0C90F2719}")
	e := A_LastError ;GetLastError()
	ComObjError(1)
		if (e != 0)
		goTo, StopContextMenu
	Global WPOld:= DllCall(A_PtrSize == 8 ? "SetWindowLongPtr" : "SetWindowLong", "Ptr", win_hwnd, "int",-4, "Ptr",RegisterCallback("WindowProc"),"Ptr")
	DllCall("GetCursorPos", "int64*", pt)
	DllCall("InsertMenu", "Ptr", hMenu, "Uint", 0, "Uint", 0x0400|0x800, "Ptr", 2, "Ptr", 0)
	DllCall("InsertMenu", "Ptr", hMenu, "Uint", 0, "Uint", 0x0400|0x002, "Ptr", 1, "Ptr", &sPath)

	idn := DllCall("TrackPopupMenuEx", "Ptr", hMenu, "Uint", 0x0100|0x0001, "int", pt << 32 >> 32, "int", pt >> 32, "Ptr", win_hwnd, "Uint", 0)
	/*
	typedef struct _CMINVOKECOMMANDINFOEX {
	DWORD   cbSize;          0
	DWORD   fMask;           4
	HWND    hwnd;            8
	LPCSTR  lpVerb;          8+A_PtrSize
	LPCSTR  lpParameters;    8+2*A_PtrSize
	LPCSTR  lpDirectory;     8+3*A_PtrSize
	int     nShow;           8+4*A_PtrSize
	DWORD   dwHotKey;        12+4*A_PtrSize
	HANDLE  hIcon;           16+4*A_PtrSize
	LPCSTR  lpTitle;         16+5*A_PtrSize
	LPCWSTR lpVerbW;         16+6*A_PtrSize
	LPCWSTR lpParametersW;   16+7*A_PtrSize
	LPCWSTR lpDirectoryW;    16+8*A_PtrSize
	LPCWSTR lpTitleW;        16+9*A_PtrSize
	POINT   ptInvoke;        16+10*A_PtrSize
	} CMINVOKECOMMANDINFOEX, *LPCMINVOKECOMMANDINFOEX;
	http://msdn.microsoft.com/en-us/library/bb773217%28v=VS.85%29.aspx
	*/
	struct_size  :=  16+11*A_PtrSize
	VarSetCapacity(pici,struct_size,0)
	NumPut(struct_size,pici,0,"Uint")         ;cbSize
	NumPut(0x4000|0x20000000|0x00100000,pici,4,"Uint")   ;fMask
	NumPut(win_hwnd,pici,8,"UPtr")       ;hwnd
	NumPut(1,pici,8+4*A_PtrSize,"Uint")       ;nShow
	NumPut(idn-3,pici,8+A_PtrSize,"UPtr")     ;lpVerb
	NumPut(idn-3,pici,16+6*A_PtrSize,"UPtr")  ;lpVerbW
	NumPut(pt,pici,16+10*A_PtrSize,"Uptr")    ;ptInvoke
	; ptInvoke:  Int64 for Uptr? https://autohotkey.com/board/topic/82814-invoking-directly-contextmenu-of-files-and-folders-in-win-7/#p552452
	WritePipe(hMenu, win_hwnd)
	DllCall(VTable(pIContextMenu, 4), "Ptr", pIContextMenu, "Ptr", &pici)   ; InvokeCommand


	DllCall("GlobalFree", "Ptr", DllCall("SetWindowLongPtr", "Ptr", win_hwnd, "int", -4, "Ptr", WPOld,"UPtr"))
	DllCall("DestroyMenu", "Ptr", hMenu)

	StopContextMenu:

	ObjRelease(pIContextMenu3)
	ObjRelease(pIContextMenu2)
	ObjRelease(pIContextMenu)
	pIContextMenu2:=pIContextMenu3:=WPOld:=0
	return idn
}
WindowProc(hWnd, nMsg, wParam, lParam)
{
	Global   pIContextMenu2, pIContextMenu3, WPOld
	If   pIContextMenu3
	{
    ;IContextMenu3->HandleMenuMsg2
		If   !DllCall(VTable(pIContextMenu3, 7), "Ptr", pIContextMenu3, "Uint", nMsg, "Ptr", wParam, "Ptr", lParam, "Ptr*", lResult)
		Return   lResult
	}
	Else If   pIContextMenu2
	{    ;IContextMenu2->HandleMenuMsg
		If   !DllCall(VTable(pIContextMenu2, 6), "Ptr", pIContextMenu2, "Uint", nMsg, "Ptr", wParam, "Ptr", lParam)
		Return   0
	}
	Return   DllCall("user32.dll\CallWindowProcW", "Ptr", WPOld, "Ptr", hWnd, "Uint", nMsg, "Ptr", wParam, "Ptr", lParam)
}
VTable(ppv, idx)
{
	Return   NumGet(NumGet(1*ppv)+A_PtrSize*idx)
}
GUID4String(ByRef CLSID, String)
{
	VarSetCapacity(CLSID, 16,0)
	return DllCall("ole32\CLSIDFromString", "wstr", String, "Ptr", &CLSID) >= 0 ? &CLSID : ""
}
CoTaskMemFree(pv)
{
	Return   DllCall("ole32\CoTaskMemFree", "Ptr", pv)
}
RunFileContextMenuItem(filePath, contextMenuItemName) {
	SplitPath, filePath, fileName, dir
	(!dir && dir := A_ScriptDir)

		try Folder := ComObjCreate("Shell.Application").Namespace(dir)
		catch
		Return

		for Item in Folder.Items
		{
		if (Item.Name != fileName)
		continue
		Loop % Item.Verbs.Count
			{
			Verb := Item.Verbs.Item(A_Index - 1)
			if StrReplace(Verb.Name, "&") = StrReplace(contextMenuItemName, "&") && found := true
			break 2
			}
		}

		if found
		{
		Verb.DoIt()
		Return true
		}
}

;Read.ahk:
;-------------------------------------------------------------------------------------------
ReadPipe()
{
ComputerName = %1%
If !ComputerName
ComputerName = .

;pipe_name := "\\" . ComputerName . "\pipe\testpipe"
pipe_name := "\\.\pipe\testpipe"
While !DllCall("WaitNamedPipe", "Str", pipe_name, "UInt", 0xffffffff)
Sleep, 30

Loop, read, %pipe_name%
Return A_LoopReadLine


}
;-------------------------------------------------------------------------------------------

;Write.ahk
;-------------------------------------------------------------------------------------------
WritePipe(hMenu, win_hwnd)
{
ptr := A_PtrSize ? "Ptr" : "UInt"
char_size := A_IsUnicode ? 2 : 1

pipe_name := "\\.\pipe\testpipe"


;CreateNamedPipe(Name, OpenMode=2, PipeMode=0, MaxInstances=255) ;PIPE_ACCESS_INBOUND 0x00000001 ;PIPE_ACCESS_OUTBOUND 0x00000002
hpipe := DllCall("CreateNamedPipe", "str", pipe_name, "uint", 2, "uint", 0, "uint", 2, "uint", 0, "uint", 0, "uint", 0, "ptr", 0, "ptr")
If hpipe = -1
{
MsgBox % "CreateNamedPipe failed with Error: " A_LastError
Return
}

pipe := FileOpen(hpipe, "h")

DllCall("ConnectNamedPipe", "ptr", hpipe, "ptr", 0)

;MsgBox, Connected

x := (A_IsUnicode ? chr(0xfeff) : chr(239) chr(187) chr(191)) . hMenu . "," . win_hwnd
If !DllCall("WriteFile", "ptr", hpipe, "str", x, "uint", (StrLen(x)+1)*char_size, "uint*", 0, "ptr", 0)
MsgBox WriteFile failed: %ErrorLevel%/%A_LastError%
;msgbox % " hmenu " hmenu " win_hwnd " win_hwnd 
;MsgBox, Click OK to close handle

DllCall("CloseHandle", "ptr", hpipe)
}
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Open Context Menu (Function)

24 May 2020, 05:06

You have to test for return values of each dllcall to com methods and if any of this != 0 then it is error.
Start with hwnd.
If return value of this method != 0

Code: Select all

msgbox % DllCall(NumGet(NumGet(IUIAutomation+0)+6*A_PtrSize), "ptr", IUIAutomation, "ptr", hwnd, "ptr*", element)   ; IUIAutomation::ElementFromHandle
then it something wrong with getting of hwnd.
User avatar
lmstearn
Posts: 688
Joined: 11 Aug 2016, 02:32
Contact:

Re: Open Context Menu (Function)

24 May 2020, 06:52

Thanks for the info, hwnd has a value, will test the other functions later.
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Open Context Menu (Function)

24 May 2020, 07:06

Also may be name of the icon is not "This PC".
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Open Context Menu (Function)

24 May 2020, 13:53

lmstearn wrote: Had a go at integrating that into @querty's script.
What exactly would you like to get?
User avatar
lmstearn
Posts: 688
Joined: 11 Aug 2016, 02:32
Contact:

Re: Open Context Menu (Function)

25 May 2020, 00:18

lmstearn wrote:
14 May 2020, 11:52
As a matter of interest, all the menu functions in @F4Jonatas's modification work on this machine except for the dialog of the properties item at the bottom of the list. (User_as_Admin related?)
Hi @Teadrinker- have you tried @F4Jonatas's modification? All the items on the menu generated by the script function as advertised on this rig except for the Properties. Thus, it's Properties from the menu, not just the Properties alone.
The script I posted does it- however, if everyone else gets the property dialog from @F4Jonatas's code, then obviously there's an error in this implementation of Shell.
In either case, it's no worry here. :)
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH
User avatar
F4Jonatas
Posts: 45
Joined: 22 Oct 2015, 06:35
Contact:

Re: Open Context Menu (Function)

25 May 2020, 13:37

Hello @lmstearn!

Did you notice if the script closes when you click properties?

In this case, this is the main problem, but it is possible that we can improve...

Otherwise, we will have to check line by line...

I tested the function and needed #Persistent
User avatar
lmstearn
Posts: 688
Joined: 11 Aug 2016, 02:32
Contact:

Re: Open Context Menu (Function)

25 May 2020, 23:49

Hi @F4Jonatas glad you found me. :)
Properties works for you then? Could you post the code with the calling function? e.g. with A_ScriptFullPath? Thanks.
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH
User avatar
F4Jonatas
Posts: 45
Joined: 22 Oct 2015, 06:35
Contact:

Re: Open Context Menu (Function)

26 May 2020, 00:01

Put those two lines and tell me if it works.

Code: Select all

#Persistent
ShellContextMenu( A_ScriptFullPath )
User avatar
lmstearn
Posts: 688
Joined: 11 Aug 2016, 02:32
Contact:

Re: Open Context Menu (Function)

26 May 2020, 04:08

Yep, that worked! :thumbup:
Didn't twig the menu was thread dependent, regardless of how the script was launched. :facepalm:
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH
User avatar
F4Jonatas
Posts: 45
Joined: 22 Oct 2015, 06:35
Contact:

Re: Open Context Menu (Function)

26 May 2020, 23:48

Do you understand about structure?
If yes, give me a help in this post :D

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: JoeWinograd, Mannaia666 and 137 guests