Sign in to follow this  
Followers 0
LarsJ

The Shell Context Menu

27 posts in this topic

#1 ·  Posted (edited)

Posted Image

See original post dated 2012-09-12 below.

Final release: 2012-10-10

Everything put together in one zipfile (bottom of post) with two UDFs: ShellContextMenu.au3 and ShellContextMenuCustom.au3. The zip contains several examples.

If you use ShellContextMenuCustom to add custom items to the context menu or modify existing items you must include five functions in your program to handle the custom/modified items: InsertCustomMenuItems(), InvokeCustomMenuItems(), HelpOnCustomMenuItems(), PrintMenuHelpMessage() and WM_INITMENUPOPUP(). See ListViewCustom.

To add bitmaps to custom menu items you need _GUICtrlMenu_CreateBitmap.au3 and/or GUICtrlMenuEx.au3. See update #2.

You also need APIConstants.au3 v3.8.

Examples

All examples are based on a ListView. Drag and drop some files or folders on the ListView.

ListView.au3: Small example with ShellContextMenu.au3.

ListViewCustom.au3: An example with ShellContextMenuCustom.au3. Shows how to add custom items to the context menu and how to add bitmaps to the custom items.

ExContextMenus.au3: Shows three different context menus. If you right click a file/folder it shows the usual menu. If you right click in the free area of the ListView it shows a context menu similar to the context menu in the free area of Windows Explorer. This menu contains the New-menu. If you right click a label in the bottom of the GUI it shows the desktop context menu.

ExModifyMenu.au3: Shows how to add custom items to the context menu and modify existing items. Also shows how to add bitmaps to custom items and to identify existing items with the language-independent verb. The picture is created from this example.

ExPrintMenu.au3: If you right click a file/folder to display the menu and then quit, info about the menu items will be printed with _ArrayDisplay(). For each item the index, command id, menu text and verb will be printed.

ExSubmenu.au3: Adds the context menu to an existing menu as a submenu.

Update #7 2012-10-08: Cut/Copy/Paste

asdf8 has pointed out that Cut/Copy/Paste commands aren't working. I've been doing some reading on this subject in the weekend. To make Cut/Copy/Paste work just use OleInitialize() to initialize COM in stead of CoInitialize(). Zipfile updated.

Update #6 2012-10-05: Multiple selections

asdf8 has pointed out that the menu commands aren't working if more than one file/folder is selected in the ListView.

If this line in ShellContextMenu.au3 and ShellContextMenuCustom.au3:

If $IShellFolder.GetUIObjectOf( $NULL, 1, $tArray, $tRIID_IContextMenu, 0, $pIContextMenu ) = $S_OK Then

is replaced with this line:

If $IShellFolder.GetUIObjectOf( $NULL, $cidl, $apidl, $tRIID_IContextMenu, 0, $pIContextMenu ) = $S_OK Then

where $cidl is the number of selected files/folders and $apidl is an array of PIDLs for the files/folders relative to the parent folder, then the menu commands are working for multiple selections.

Changed the styles of ListViews to allow multiple selections. Zipfile updated.

Update #5 2012-10-01

Not applicable after update #6:

Changed the style of ListViewCustom.au3 to allow multiple selections and added an example to show the proper Properties dialog box when multiple files/folders are selected. This is done with the function SHMultiFileProperties and the helper function CIDLData_CreateFromIDArray. Both functions are implemented in shell32.dll. On XP CIDLData_CreateFromIDArray can only be called with the ordinal value which is 83.

Fixed an error in ListViewCustom.au3 which could lead to a crash on Windows 7. The function GetCommandVerb( $iCmd ) to get the language-independent verb must not be called if not $iCmd is in the valid range between $idCmdFirst (0x0001) and $idCmdLast (0x6FFF).

Update #4 2012-09-27: Language-independent verb

Added the CMF_EXTENDEDVERBS flag to the QueryContextMenu method to get extended items (Pin to Start menu) if holding the shift key while right clicking.

To modify existing menu items it's necessary to be able to identify the items. A convenient way to identify the items is to use the language-independent verb. The language-independent verb can be extracted with a function like this:

; Get the verb, the language-independent command name
; Canonical verbs: copy, cut, delete, open, paste, print, rename
Func GetCommandVerb( $iCmd )
Local $uFlags, $szName, $pszName, $tszName
$uFlags = $GCS_VERB
$tszName = DllStructCreate( "wchar[64]" )
$pszName = DllStructGetPtr( $tszName, 1 )
If $IContextMenu.GetCommandString( $iCmd - $idCmdFirst, $uFlags, $NULL, $pszName, 64 ) = $S_OK Then
If BitAND( $uFlags, $GCS_UNICODE ) Then
$szName = DllStructGetData( $tszName, 1 )
If StringLen( $szName ) > 0 Then Return $szName
EndIf
EndIf
Return ""
EndFunc

GetCommandVerb() is called from WM_INITMENUPOPUP(). The WM_INITMENUPOPUP message is catched in the new window procedure.

Examples of these canonical verbs are: copy, cut, delete, open, paste, print and rename.

In ListViewCustom the Cut/Copy commands are renamed to Copy/Paste, the command identifiers are saved in two variables, and custom code is executed in stead of the default code.

Update #3 2012-09-23: Help messages

For Windows Explorer under XP help messages for the context menu are shown in the status bar. A help message is shown when an item is selected (hilited).

When an item is selected it generates a WM_MENUSELECT notification which can be catched in the new window procedure:

; New window procedure to be able to handle messages from the shell context menu
Func NewWindowProc( $hWnd, $iMsg, $iwParam, $ilParam )
If $pIContextMenu Then
If $iMsg = $WM_MENUSELECT Then WM_MENUSELECT( $hWnd, $iMsg, $iwParam, $ilParam )
...
EndFunc

In the WM_MENUSELECT() function help messages are printed with the GetCommandString method of the IContextMenu interface.

Update #2 2012-09-20: Bitmaps

To add bitmaps to system-drawn (not owner-drawn) menu items (Custom1 and Custom2) you can use the UDF _GUICtrlMenu_CreateBitmap.au3 by UEZ. You can get it in the German forum by following this link: http://www.autoit.de/index.php?page=Thread&threadID=21001. The UDF is not included in the zip.

To add bitmaps to owner-drawn menu items (Custom3, Custom4 and Custom5) you can use the UDF GUICtrlMenuEx.au3 by Ward. You can get it here: http://www.autoitscript.com/forum/index.php?showtopic=123223. The UDF is not included in the zip.

If you want slightly more space between the owner-drawn menu items you can modify a line in the __GUICtrlMenuEx_WM_MEASUREITEM() function like this:

DllStructSetData($MeasureItem, "itemHeight", $Size[1]) The original line
DllStructSetData($MeasureItem, "itemHeight", $Size[1]+4) Add 4 extra pixels of space

This is done in the picture.

Added a new zip at the bottom.

Update #1 2012-09-17: Custom menu items

When we have a handle to the context menu it's easy to add custom items. The zip at the bottom is updated.

2012-09-12

With ObjCreateInterface() it's possible to create a Shell Context Menu (Windows Explorer right click menu) for files and folders e.g. in a ListView or TreeView.

This can also be implemented with AutoItObject or with a C/C++ dll-file (there is an example of that in this forum). Here is used ObjCreateInterface() so this is pure AutoIt.

To create a Shell Context Menu you use the GetUIObjectOf method of the IShellFolder interface to get a pointer for the IContextMenu interface. With the QueryContextMenu method of this interface you add commands to the context menu and you execute the selected command with the InvokeCommand method.

With QueryInterface you can get pointers to the IContextMenu2 and IContextMenu3 interfaces. You need these interfaces to be able to handle owner-drawn menu items e.g. the "Open With" or "Send To" submenues. To handle the events of the owner-drawn menu items you also need a new window procedure and you must initialize COM.

This is the function in the UDF that shows the context menu:

; Show the Shell Context Menu
Func ShellContextMenu( $hWnd, $hWndContext, $tPOINT, $sFullPath )
Local $pidlFQ, $pidlRel, $pIShellFolder, $IShellFolder
Local $pIContextMenu, $IContextMenu, $tArray = DllStructCreate( "ptr" )
Local $hPopup, $iX, $iY, $iCmd, $fMask, $KeyState

; Get the fully qualified PIDL associated with the file
$pidlFQ = ILCreateFromPath( $sFullPath )

; Get an IShellFolder interface pointer ($pIShellFolder) for the parent folder
; and a PIDL ($pidlRel) associated with the file relative to the parent folder.
SHBindToParent( $pidlFQ, DllStructGetPtr( $tRIID_IShellFolder ), $pIShellFolder, $pidlRel )

; Create an IDispatch-Object for the IShellFolder Interface
$IShellFolder = ObjCreateInterface( $pIShellFolder, $sIID_IShellFolder, $dtagIShellFolder )

; Get a pointer to the IContextMenu Interface
DllStructSetData( $tArray, 1, $pidlRel )
If $IShellFolder.GetUIObjectOf( $NULL, 1, $tArray, $tRIID_IContextMenu, 0, $pIContextMenu ) = $S_OK Then

; Create an IDispatch-Object for the IContextMenu Interface
$IContextMenu = ObjCreateInterface( $pIContextMenu, $sIID_IContextMenu, $dtagIContextMenu )

; Create a Popup menu
$hPopup = CreatePopupMenu()

; Add commands to the Popup menu
$IContextMenu.QueryContextMenu( $hPopup, 0, $idCmdFirst, $idCmdLast, $CMF_NORMAL )

; Create an IDispatch-Object for the IContextMenu2 Interface
$IContextMenu.QueryInterface( DllStructGetPtr( $tRIID_IContextMenu2 ), $pIContextMenu2 )
$IContextMenu2 = ObjCreateInterface( $pIContextMenu2, $sIID_IContextMenu2, $dtagIContextMenu2 )

; Create an IDispatch-Object for the IContextMenu3 Interface
$IContextMenu.QueryInterface( DllStructGetPtr( $tRIID_IContextMenu3 ), $pIContextMenu3 )
$IContextMenu3 = ObjCreateInterface( $pIContextMenu3, $sIID_IContextMenu3, $dtagIContextMenu3 )

; Convert client coordinates to screen coordinates.
; This is among other things used to place the upper left corner
; of the Properties dialog box at the position of the mouse cursor.
_WinAPI_ClientToScreen( $hWndContext, $tPoint )
$iX = DllStructGetData( $tPoint, "X" )
$iY = DllStructGetData( $tPoint, "Y" )

; Show the Popup menu and track the selection
$iCmd = TrackPopupMenuEx( $hPopup, $TPM_RETURNCMD, $iX, $iY, $hWnd )

If $iCmd > 0 Then
; Create and fill a $tagCMINVOKECOMMANDINFOEX structure
     Local $tCMINVOKECOMMANDINFOEX = DllStructCreate( $tagCMINVOKECOMMANDINFOEX )
     DllStructSetData( $tCMINVOKECOMMANDINFOEX, "cbSize", DllStructGetSize( $tCMINVOKECOMMANDINFOEX ) )
     $fMask = BitOr( $CMIC_MASK_UNICODE, $CMIC_MASK_PTINVOKE )
     $KeyState = GetKeyState( $VK_CONTROL )
     If $KeyState < 0 Or $KeyState > 32768 Then _
     $fMask = BitOr( $fMask, $CMIC_MASK_CONTROL_DOWN )
     $KeyState = GetKeyState( $VK_SHIFT )
     If $KeyState < 0 Or $KeyState > 32768 Then _
     $fMask = BitOr( $fMask, $CMIC_MASK_SHIFT_DOWN )
     DllStructSetData( $tCMINVOKECOMMANDINFOEX, "fMask", $fMask )
     DllStructSetData( $tCMINVOKECOMMANDINFOEX, "hWnd", $hWnd )
     DllStructSetData( $tCMINVOKECOMMANDINFOEX, "lpVerb", $iCmd - $idCmdFirst )
     DllStructSetData( $tCMINVOKECOMMANDINFOEX, "lpVerbW", $iCmd - $idCmdFirst )
     DllStructSetData( $tCMINVOKECOMMANDINFOEX, "nShow", $SW_SHOWNORMAL )
     DllStructSetData( $tCMINVOKECOMMANDINFOEX, "X", $iX )
     DllStructSetData( $tCMINVOKECOMMANDINFOEX, "Y", $iY )
     ; Invoke the command
     $IContextMenu.InvokeCommand( $tCMINVOKECOMMANDINFOEX )
    EndIf

    ; Free memory allocated by the PIDL
    CoTaskMemFree( $pidlFQ )

    ; Destroy menu and free memory
    DestroyMenu( $hPopup )

    $pIContextMenu3 = 0
    $pIContextMenu2 = 0
    $IContextMenu3 = 0
    $IContextMenu2 = 0
    $IContextMenu = 0
    $IShellFolder = 0
EndIf
EndFunc

Double click

To open a file or folder in Windows Explorer you double click it. It's the same as right click and select the default (bold) menu item. When you double click you use the CMF_DEFAULTONLY flag to tell the QueryContextMenu that you only want the default menu item.

This is the function in the UDF that executes the default menu item:

; Execute the default menu item
Func InvokeCommand( $hWnd, $sFullPath )
Local $pidlFQ, $pidlRel, $pIShellFolder, $IShellFolder
Local $pIContextMenu, $IContextMenu, $tArray = DllStructCreate( "ptr" )
Local $hPopup, $aRet, $idMenu

; Get the fully qualified PIDL associated with the file
$pidlFQ = ILCreateFromPath( $sFullPath )

; Get an IShellFolder interface pointer ($pIShellFolder) for the parent folder
; and a PIDL ($pidlRel) associated with the file relative to the parent folder.
SHBindToParent( $pidlFQ, DllStructGetPtr( $tRIID_IShellFolder ), $pIShellFolder, $pidlRel )

; Create an IDispatch-Object for the IShellFolder Interface
$IShellFolder = ObjCreateInterface( $pIShellFolder, $sIID_IShellFolder, $dtagIShellFolder )

; Get a pointer to the IContextMenu Interface
DllStructSetData( $tArray, 1, $pidlRel )
If $IShellFolder.GetUIObjectOf( $NULL, 1, $tArray, $tRIID_IContextMenu, 0, $pIContextMenu ) = $S_OK Then

; Create an IDispatch-Object for the IContextMenu Interface
    $IContextMenu = ObjCreateInterface( $pIContextMenu, $sIID_IContextMenu, $dtagIContextMenu )

; Create a Popup menu
$hPopup = CreatePopupMenu()

; Add the default command to the Popup menu
$aRet = $IContextMenu.QueryContextMenu( $hPopup, 0, $idCmdFirst, $idCmdLast, $CMF_DEFAULTONLY )

If $aRet >= 0 Then
     ; Get the menu item identifier
Local $idMenu = GetMenuItemID( $hPopup, 0 )
     ; Create and fill a $tagCMINVOKECOMMANDINFO structure
     Local $tCMINVOKECOMMANDINFO = DllStructCreate( $tagCMINVOKECOMMANDINFO )
     DllStructSetData( $tCMINVOKECOMMANDINFO, "cbSize", DllStructGetSize( $tCMINVOKECOMMANDINFO ) )
     DllStructSetData( $tCMINVOKECOMMANDINFO, "fMask", 0 )
     DllStructSetData( $tCMINVOKECOMMANDINFO, "hWnd", $hWnd )
     DllStructSetData( $tCMINVOKECOMMANDINFO, "lpVerb", $idMenu - $idCmdFirst )
     DllStructSetData( $tCMINVOKECOMMANDINFO, "nShow", $SW_SHOWNORMAL )
     ; Invoke the command
     $IContextMenu.InvokeCommand( $tCMINVOKECOMMANDINFO )
EndIf

; Free memory allocated by the PIDL
CoTaskMemFree( $pidlFQ )

; Destroy menu and free memory
DestroyMenu( $hPopup )

$IContextMenu = 0
$IShellFolder = 0
EndIf
EndFunc

This is a demonstration of how to use these functions to execute the default menu item when you double click. You can do exactly the same thing in one line with the builtin function ShellExecute().

Example

This is a small example with a ListView. Drag and drop some files and folders on the ListView and right click to show the context menu or double click to open.

(If the window with the ListView is inactive then activate the window by clicking the titlebar or click in the ListView outside the items. If you click a LV item in an inactive window it generates a double click and opens the corresponding file or folder.)

#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include "ShellContextMenu.au3"

Opt( "MustDeclareVars", 1 )

Global $hGui, $idLV, $hLV, $idLVdropFiles, $aLVfiles[1]
Global $idLVrightClick, $idLVdoubleClick, $tLVpoint, $iLVidx

MainScript()

Func MainScript()

$hGui = GUICreate( "The Shell Context Menu", 300, 200, 600, 300, -1, BitOR( $WS_EX_ACCEPTFILES, $WS_EX_TOPMOST ) )

$idLV = GUICtrlCreateListView( "", 0, 0, 300, 200 )
GUICtrlSetStyle( $idLV, BitOR( $LVS_LIST, $GUI_SS_DEFAULT_LISTVIEW ) )
GUICtrlSetState( $idLV, $GUI_DROPACCEPTED )
$hLV = ControlGetHandle( $hGui, "", $idLV )

$idLVdropFiles = GUICtrlCreateDummy()
$idLVrightClick = GUICtrlCreateDummy()
$idLVdoubleClick = GUICtrlCreateDummy()

; Window Procedures
$hNewWinProc = DllCallbackRegister( "NewWindowProc", "int", "hwnd;uint;wparam;lparam" )      ; New window procedure
$hOldWinProc = _WinAPI_SetWindowLong( $hGui, $GWL_WNDPROC, DllCallbackGetPtr( $hNewWinProc ) ) ; Old window procedure

GUIRegisterMsg( $WM_DROPFILES, "WM_DROPFILES" )
GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )

GUISetState( @SW_SHOW )

; Initialize COM
CoInitialize()

While 1

Switch GUIGetMsg()

     Case $GUI_EVENT_CLOSE
     GUIDelete( $hGui )
     ; Cleanup
     DllCallbackFree( $hNewWinProc )
     CoUninitialize()
     CloseDlls()
     Exit

     Case $idLVdropFiles
     LVupdate()

     Case $idLVrightClick
     ; Show the Shell Context Menu
     ShellContextMenu( $hGui, $hLV, $tLVpoint, $aLVfiles[$iLVidx] )

     Case $idLVdoubleClick
     ; Execute the default menu item
     InvokeCommand( $hGui, $aLVfiles[$iLVidx] )

EndSwitch

WEnd

EndFunc

Func WM_DROPFILES( $hWnd, $iMsg, $iwParam, $ilParam )
#forceref $iMsg, $ilParam
Switch $hWnd
Case $hGui
     Local $aRet, $nSize, $tFileName
     $aRet = DllCall( $dllShell32, "int", "DragQueryFile", "hwnd", $iwParam, "int", -1, "ptr", 0, "int", 255 )
     For $i = 0 To $aRet[0] - 1
     $nSize = DllCall( $dllShell32, "int", "DragQueryFile", "hwnd", $iwParam, "int", $i, "ptr", 0, "int", 0 )
     $nSize = $nSize[0] + 1
     $tFileName = DllStructCreate( "char[" & $nSize & "]" )
     DllCall( $dllShell32, "int", "DragQueryFile", "hwnd", $iwParam, "int", $i, "ptr", DllStructGetPtr( $tFileName ), "int", $nSize )
     ReDim $aLVfiles[$i+1]
     $aLVfiles[$i] = DllStructGetData( $tFileName, 1 )
     $tFileName = 0
     Next
     GUICtrlSendToDummy( $idLVdropFiles )
     Return 0
EndSwitch
EndFunc

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $tNMHDR, $hWndFrom, $iCode
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $hLV
     Switch $iCode
     Case $NM_DBLCLK
         $tLVpoint = _WinAPI_GetMousePos( True, $hLV )
         Local $iX = DllStructGetData( $tLVpoint, "X" )
         Local $iY = DllStructGetData( $tLVpoint, "Y" )
         Local $aHit = _GUICtrlListView_HitTest( $hLV, $iX, $iY )
         If $aHit[2] Or $aHit[3] Then
         $iLVidx = $aHit[0]
         GUICtrlSendToDummy( $idLVdoubleClick )
         EndIf
     Case $NM_RCLICK
         $tLVpoint = _WinAPI_GetMousePos( True, $hLV )
         Local $iX = DllStructGetData( $tLVpoint, "X" )
         Local $iY = DllStructGetData( $tLVpoint, "Y" )
         Local $aHit = _GUICtrlListView_HitTest( $hLV, $iX, $iY )
         If $aHit[2] Or $aHit[3] Then
         $iLVidx = $aHit[0]
         GUICtrlSendToDummy( $idLVrightClick )
         Return 0
         EndIf
     EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc

Func LVupdate()
_GUICtrlListView_DeleteAllItems( $hLV )
For $file In $aLVfiles
GUICtrlCreateListViewItem( StringRight( $file, StringLen( $file ) - StringInStr( $file, "\", 0, -1 ) ), $idLV )
Next
EndFunc

The example is also contained in the zipfile.

Zipfile

The zipfile contains the ShellContextMenu.au3 and ShellContextMenuCustom.au3 UDFs with the necessary globals, structures, interface definitions and functions. You need APIConstants.au3 v3.8 by Yashied. The zip contains several examples too.

Testet on XP and 7. It would be nice if someone would test the UDF on Vista.

The zipfile can be opened with 7-Zip.

ShellContextMenu.zip

(You need _GUICtrlMenu_CreateBitmap.au3 and/or GUICtrlMenuEx.au3. See top of post.)

Edited by LarsJ
4 people like this

Share this post


Link to post
Share on other sites



Thanks for sharing.


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Share this post


Link to post
Share on other sites

I had to register to say thanks for this, the timing couldn't have been better for me... I wanted to add the default shell right click menu to a small util I'm making and amazingly this post appears on the very same day! Many thanks this saved me a great deal of time and works great.

Share this post


Link to post
Share on other sites

Nice stuff! Thanks for sharing!

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Added bitmaps to custom menu items.

humpty, You are very welcome.

UEZ, Thank you and same to you for the _GUICtrlMenu_CreateBitmap.au3 UDF in the German forum as I'm using to add bitmaps to the system-drawn custom menu items. I've added a link to your UDF in the top of the first post.

Lars.

Share this post


Link to post
Share on other sites

Good job.

How to use this menu as a submenu?

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

asdf8, Do you mean something like this:

Custom Menu 1

Custom Menu 2

-------------

Shell Menu >

This is pretty easy. Put a copy of ShellContextMenu() in your script and modify it to your needs.

Example added to the zip.

Edited by LarsJ

Share this post


Link to post
Share on other sites

LarsJ

This is what i had in mind.

Thanks a lot.

Share this post


Link to post
Share on other sites

This is pretty cool, I could make use of this in a few applications.

Thanks.

Share this post


Link to post
Share on other sites

LarsJ

Do not work the menu items "Copy" and "Cut".

Can this be fixed?

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

asdf8, I don't think it can be fixed, but there are workarounds.

The shell context menu is supposed to be used in Windows Explorer. If you use the menu in your own program, there might be commands that aren't working.

If you don't need these commands you can delete them or make them disabled (dimmed). This can be done with the functions in GuiMenu.au3.

If you need these commands you have to implement the functionality yourself.

Here is an example where the Cut/Copy commands are renamed to Copy/Paste, the command identifiers are saved in two variables, and custom code are executed in stead of the not working default code.

; Modify the Popup menu to your needs
; This is an example where Cut/Copy are renamed to Copy/Paste
; The commend identifiers for Cut/Copy are saved in $idCopy and $idPaste
; Custom code CopyCmd()/PasteCmd() are executed in stead of the default code for Cut/Copy
Local $count = _GUICtrlMenu_GetItemCount( $hPopup ), $sTxt, $j = 0
For $i = 0 To $count - 1
$iCmd = _GUICtrlMenu_GetItemID( $hPopup, $i )
$sTxt = _GUICtrlMenu_GetItemText( $hPopup, $i )
;ConsoleWrite( "Index, CmdId, Text: " & $i & ", " & $iCmd & ", " & $sTxt & @CRLF )
If $iCmd > 0 Then
If $sTxt = "Cu&t" Then
_GUICtrlMenu_SetItemText( $hPopup, $i, "Copy" )
$idCopy = $iCmd
$j += 1
If $j = 2 Then ExitLoop
ElseIf $sTxt = "&Copy" Then
_GUICtrlMenu_SetItemText( $hPopup, $i, "Paste" )
If $sCopyFile = "" Then _GUICtrlMenu_SetItemDisabled( $hPopup, $i )
$idPaste = $iCmd
$j += 1
If $j = 2 Then ExitLoop
EndIf
EndIf
Next
If $j <> 2 Then
MsgBox( 0, "The Shell Context Menu", "Cut/Copy commands not identified", 0, $hGui )
EndIf

Wrong answer. I apologize. See first post. Example added to the zip.

Edited by LarsJ

Share this post


Link to post
Share on other sites

It is a pity that nothing could be done.

Processing of these items is also a problem - the names of items depends on the language settings PC, and don't understand how can cut, copy the file to a common clipboard.

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites

Added functions to identify existing menu items with the language-independent verb

Now can use the handler to copy/cut, such as

Still wondering how to call the menu for a group of files/folders?

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

asdf8, Here is an example with multiple selections. Use Copy to read file/folder names and Paste to print the names in a MsgBox.

Example added to the zip.

Edited by LarsJ

Share this post


Link to post
Share on other sites

Thank LarsJ.

I was referring to another - now for a group of selected files context menu appears relevant only to the first file of the group (you can check the menu item "Properties").

Is it possible to display the menu corresponding to the group of files?

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

asdf8, I think that the context menu for a group of files is the same as the menu for a single file. It depends on the exact file that you right click, and not the group of files. But the function executed when you select a command can be different for a group of files.

To get the Properties for a group of files you use the function SHMultiFileProperties. And when you use the context menu in an AutoIt script you have to call this function yourself.

I don't think there is an easy way to get around the problem of menu commands not working exactly in the same way in an AutoIt script and in Windows Explorer.

Wrong answer. I apologize. See first post.

Edited by LarsJ

Share this post


Link to post
Share on other sites

Lars, thank you very much for the explanation and examples.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0