[python-win32] Context menu troubles

2012-03-02 Thread Chris Ness

disclaimer: I have only the faintest idea what I'm doing!

I'm trying to get a windows explorer context menu in my app. I can get 
the menu to show, but it does not execute any commands (e.g. 'copy')


my code is based on 
http://bcbjournal.org/articles/vol4/0006/Using_the_shell_context_menu.htm and 
partly on http://netez.com/2xExplorer/shellFAQ/bas_context.html


I'm new to both win32 and pywin32. Any help or advice will be readily 
accepted!


Cheers!

Chris.

DesktopFolder = shell.SHGetDesktopFolder()
if not DesktopFolder:
raise Exception("Failed to get Desktop folder.")
# Get a pidl for the folder the file
# is located in.
FilePath = 'J:\\'
FileName = 'tree.xml'
Eaten, ParentPidl, attr = DesktopFolder.ParseDisplayName(Handle, None, 
FilePath)
# Get an IShellFolder for the folder
# the file is located in.
ParentFolder = DesktopFolder.BindToObject(ParentPidl, None, 
shell.IID_IShellFolder)
CM_plus = None
# Get a pidl for the file itself.
Eaten, Pidl, attr = ParentFolder.ParseDisplayName(Handle, None, FileName)
# Get the IContextMenu for the file.
i, CM = ParentFolder.GetUIObjectOf(Handle, [Pidl], shell.IID_IContextMenu, 
0)
#else:
# Get the IContextMenu for the folder. 
#i, CM = ParentFolder.GetUIObjectOf(Handle, [ParentPidl], 
shell.IID_IContextMenu, 0)
if not CM:
raise Exception("Unable to get context menu interface.")
else:
# try to obtain a higher level pointer, first 3 then 2
try:
CM_plus = CM.QueryInterface(shell.IID_IContextMenu3, None)
pcmType = 3
except Exception:
try:
CM_plus = CM.QueryInterface(shell.IID_IContextMenu2, None)
pcmType = 2
except Exception:
pass

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

hMenu = win32gui.CreatePopupMenu()
Flags = CMF_EXPLORE
# Optionally the shell will show the extended
# context menu on some operating systems when
# the shift key is held down at the time the
# context menu is invoked. The following is
# commented out but you can uncommnent this
# line to show the extended context menu.
# Flags |= 0x0080;
CM.QueryContextMenu(hMenu, 0, 1, 0x7FFF, Flags)
# Show the menu.
x, y =  win32gui.GetCursorPos()
flags = ( win32gui.TPM_LEFTALIGN
 | win32gui.TPM_LEFTBUTTON
 | win32gui.TPM_RIGHTBUTTON
 #| win32gui.TPM_RETURNCMD,
)
hr = win32gui.TrackPopupMenu(hMenu, flags, x, y, 0, Handle, None)
if hr != 1:
e = win32api.GetLastError()
s = win32api.FormatMessage(e)


___
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32


Re: [python-win32] Context menu troubles

2012-03-02 Thread Chris Ness

Thanks for reply Tim.

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?


Also forgot to mention, using python3.2 32bit, pywon32 build 217 on 
windows 7


I've simplified/condensed it a bit, stripped comments and changed 
TrackPopupMenu return variable to something more appropriate.


Chris.

DesktopFolder = shell.SHGetDesktopFolder()
if not DesktopFolder:
raise Exception("Failed to get Desktop folder.")
FilePath = 'J:\\'
FileName = 'tree.xml'
Eaten, ParentPidl, attr = DesktopFolder.ParseDisplayName(Handle, None, 
FilePath)
ParentFolder = DesktopFolder.BindToObject(ParentPidl, None, 
shell.IID_IShellFolder)
CM_plus = None
Eaten, Pidl, attr = ParentFolder.ParseDisplayName(Handle, None, FileName)
i, CM = ParentFolder.GetUIObjectOf(Handle, [Pidl], shell.IID_IContextMenu, 
0)
hMenu = win32gui.CreatePopupMenu()
Flags = CMF_EXPLORE
CM.QueryContextMenu(hMenu, 0, 1, 0x7FFF, Flags)
x, y =  win32gui.GetCursorPos()
flags = win32gui.TPM_LEFTALIGN
hr = win32gui.TrackPopupMenu(hMenu, flags, x, y, 0, Handle, None)
if hr != 1:
e = win32api.GetLastError()
s = win32api.FormatMessage(e) #< "command completed 
successfully"


On 02/03/2012 18:42, Tim Roberts wrote:

Chris Ness wrote:

disclaimer: I have only the faintest idea what I'm doing!

I'm trying to get a windows explorer context menu in my app. I can get
the menu to show, but it does not execute any commands (e.g. 'copy')

Right, because you haven't told it to.  You implemented the stuff form
the articles pretty closely until the call to TrackPopupMenu, then you
went awry.  TrackPopupMenu does not actually return a boolean.  It
returns 0 if the call fails, but if the call succeeds, it returns the
command ID of the menu item that was selected, and you have to tell the
shell to go invoke that command.

So, if it returns a value other than 0, you need to create a
CMINVOKECOMMANDINFO structure, fill it in, and pass it to
CM.InvokeCommand.  That will trigger the real action.



___
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32


Re: [python-win32] Context menu troubles

2012-03-02 Thread Chris Ness
Also, the first article mentions OleInitialise(), which I tried but 
pythoncom.OleInitialise() does not exist in the module (AttributeError), 
despite what the docs say?


Chris.

___
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32


Re: [python-win32] Context menu troubles

2012-03-02 Thread Chris Ness
Aah. It makes sense now. messages and such like. my lack of 
knowledge of win32 shows.


I'll let you know how I get on.

Am I right in thinking the win32 api is awfull?

Chris.

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.



___
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32


Re: [python-win32] Context menu troubles

2012-03-03 Thread Chris Ness

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 = 3
# Flags |= 0x0080; #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)

___
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32


[python-win32] Win7 explorer "include in library" submenu

2012-05-26 Thread Chris Ness
I'm trying to replicate the win 7 explorer context menu on the fly. All 
works well apart from the "Include in Library" submenu, which shows one 
greyed out entry: "retrieving libraries...". Well it's not retrieving 
anything because the code to read the menus has returned! Here is my 
code that reads the menu entries...


def __getMenuItems(hMenu, contextMenu):
num_items = win32gui.GetMenuItemCount(hMenu)
rval = []
for i in range(num_items):
mi = EmptyMENUITEMINFO()
win32gui.GetMenuItemInfo(hMenu, i, True, mi[0])
item = UnpackMENUITEMINFO(mi[0])
fType, fState, wID, hSubMenu, hbmpChecked, hbmpUnchecked, dwItemData, 
text, hbmpItem = item
if hSubMenu:
hSubMenu = win32gui.GetSubMenu(hMenu, i)
rval.append((__getMenuItems(hSubMenu, contextMenu), text))
else:
rval.append((wID, text))
return rval


I have no idea what to do and google is no help. Do I need to initiate 
something? Wait for something? Any help much appreciated!


chris

___
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32