[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