[python-win32] Context menu troubles

Chris Ness karbonforms at gmail.com
Sat Mar 3 12:37:48 CET 2012


On 02/03/2012 20:16, Tim Roberts wrote:
> Chris Ness wrote:
>> I had decided not to use the command ID technique until I got things
>> working, so TPM_RETURNCMD was commented out when I defines flags. From
>> my understanding of MSDN and pywin32, this should make commands
>> immediately execute and cause TrackPopupMenu to return an HRESULT?
> Hmm, I should have read the doc more closely before I replied.  My fault.
>
> I doesn't work quite that automatically.  TrackPopupMenu is a
> general-purpose Windows API -- it doesn't have any connection to or
> knowledge of Windows Explorer, so it cannot force Explorer to take
> actions.  If you don't specify TPM_RETURNCMD, then the final result of
> selecting a menu item will be that a WM_COMMAND message sent to your
> window.  Your window doesn't know what to do with those command codes,
> so nothing useful will happen.  In this particular case, I think you
> HAVE to use TPM_RETURNCMD.
All seems to be working fine now. Thanks Tim. Learning a lot here.

Having a spot of bother with the context menu for a drive though 
(e.g."C:"). I'm getting a very minimal menu with Open, Manage, Include 
in Library, Copy and Properties. Choosing proprties brings up Control 
Panel->System.

Chris.

def getContextMenu(filePath = 'J:', fileName = ''):
     hwnd = win32gui.GetForegroundWindow()
     # Get an IShellFolder for the desktop.
     desktopFolder = shell.SHGetDesktopFolder()
     if not desktopFolder:
         raise Exception("Failed to get Desktop folder.")
     # Get a pidl for the folder the file is located in.
     eaten, parentPidl, attr = desktopFolder.ParseDisplayName(hwnd, None, filePath)
     # Get an IShellFolder for the folder the file is located in.
     parentFolder = desktopFolder.BindToObject(parentPidl, None, shell.IID_IShellFolder)
     if fileName:
         # Get a pidl for the file itself.
         eaten, pidl, attr = parentFolder.ParseDisplayName(hwnd, None, fileName)
         # Get the IContextMenu for the file.
         i, contextMenu = parentFolder.GetUIObjectOf(hwnd, [pidl], shell.IID_IContextMenu, 0)
     else:
         i, contextMenu = desktopFolder.GetUIObjectOf(hwnd, [parentPidl], shell.IID_IContextMenu, 0) #<----- where i attempt to get menu for a drive.
     contextMenu_plus = None
     if contextMenu:
         # try to obtain a higher level pointer, first 3 then 2
         try:
             contextMenu_plus = contextMenu.QueryInterface(shell.IID_IContextMenu3, None)
             pcmType = 3
         except Exception:
             try:
                 contextMenu_plus = contextMenu.QueryInterface(shell.IID_IContextMenu2, None)
                 pcmType = 2
             except Exception:
                 pass
     else:
         raise Exception("Unable to get context menu interface.")

     if contextMenu_plus:
         contextMenu.Release() # free initial "v1.0" interface
         contextMenu = contextMenu_plus
     else: # no higher version supported
         pcmType = 1

     hMenu = win32gui.CreatePopupMenu()
     MIN_SHELL_ID = 1
     MAX_SHELL_ID = 30000
     # Flags |= 0x00000080; #to show the extended context menu.
     contextMenu.QueryContextMenu(hMenu, 0, MIN_SHELL_ID, MAX_SHELL_ID, CMF_EXPLORE)
     x, y =  win32gui.GetCursorPos()
     flags = win32gui.TPM_LEFTALIGN | win32gui.TPM_RETURNCMD #| win32gui.TPM_LEFTBUTTON | win32gui.TPM_RIGHTBUTTON
     cmd = win32gui.TrackPopupMenu(hMenu, flags, x, y, 0, hwnd, None)
     if not cmd:
         e = win32api.GetLastError()
         if e:
             s = win32api.FormatMessage(e)
             raise Exception(s)
     CI = (  0,                  #Mask
             hwnd,               #hwnd
             cmd - MIN_SHELL_ID, #Verb
             '',                 #Parameters
             '',                 #Directory
             SW_SHOWNORMAL,      #Show
             0,                  #HotKey
             None                #Icon
     )
     contextMenu.InvokeCommand(CI)



More information about the python-win32 mailing list