123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- # A sample context menu handler.
- # Adds a 'Hello from Python' menu entry to .py files. When clicked, a
- # simple message box is displayed.
- #
- # To demostrate:
- # * Execute this script to register the context menu.
- # * Open Windows Explorer, and browse to a directory with a .py file.
- # * Right-Click on a .py file - locate and click on 'Hello from Python' on
- # the context menu.
- import pythoncom
- from win32com.shell import shell, shellcon
- import win32gui
- import win32con
- class ShellExtension:
- _reg_progid_ = "Python.ShellExtension.ContextMenu"
- _reg_desc_ = "Python Sample Shell Extension (context menu)"
- _reg_clsid_ = "{CED0336C-C9EE-4a7f-8D7F-C660393C381F}"
- _com_interfaces_ = [shell.IID_IShellExtInit, shell.IID_IContextMenu]
- _public_methods_ = shellcon.IContextMenu_Methods + shellcon.IShellExtInit_Methods
- def Initialize(self, folder, dataobj, hkey):
- print "Init", folder, dataobj, hkey
- self.dataobj = dataobj
- def QueryContextMenu(self, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags):
- print "QCM", hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags
- # Query the items clicked on
- format_etc = win32con.CF_HDROP, None, 1, -1, pythoncom.TYMED_HGLOBAL
- sm = self.dataobj.GetData(format_etc)
- num_files = shell.DragQueryFile(sm.data_handle, -1)
- if num_files>1:
- msg = "&Hello from Python (with %d files selected)" % num_files
- else:
- fname = shell.DragQueryFile(sm.data_handle, 0)
- msg = "&Hello from Python (with '%s' selected)" % fname
- idCmd = idCmdFirst
- items = ['First Python content menu item']
- if (uFlags & 0x000F) == shellcon.CMF_NORMAL: # Check == here, since CMF_NORMAL=0
- print "CMF_NORMAL..."
- items.append(msg)
- elif uFlags & shellcon.CMF_VERBSONLY:
- print "CMF_VERBSONLY..."
- items.append(msg + " - shortcut")
- elif uFlags & shellcon.CMF_EXPLORE:
- print "CMF_EXPLORE..."
- items.append(msg + " - normal file, right-click in Explorer")
- elif uFlags & CMF_DEFAULTONLY:
- print "CMF_DEFAULTONLY...\r\n"
- else:
- print "** unknown flags", uFlags
- win32gui.InsertMenu(hMenu, indexMenu,
- win32con.MF_SEPARATOR|win32con.MF_BYPOSITION,
- 0, None)
- indexMenu += 1
- for item in items:
- win32gui.InsertMenu(hMenu, indexMenu,
- win32con.MF_STRING|win32con.MF_BYPOSITION,
- idCmd, item)
- indexMenu += 1
- idCmd += 1
- win32gui.InsertMenu(hMenu, indexMenu,
- win32con.MF_SEPARATOR|win32con.MF_BYPOSITION,
- 0, None)
- indexMenu += 1
- return idCmd-idCmdFirst # Must return number of menu items we added.
- def InvokeCommand(self, ci):
- mask, hwnd, verb, params, dir, nShow, hotkey, hicon = ci
- win32gui.MessageBox(hwnd, "Hello", "Wow", win32con.MB_OK)
- def GetCommandString(self, cmd, typ):
- # If GetCommandString returns the same string for all items then
- # the shell seems to ignore all but one. This is even true in
- # Win7 etc where there is no status bar (and hence this string seems
- # ignored)
- return "Hello from Python (cmd=%d)!!" % (cmd,)
- def DllRegisterServer():
- import _winreg
- key = _winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT,
- "Python.File\\shellex")
- subkey = _winreg.CreateKey(key, "ContextMenuHandlers")
- subkey2 = _winreg.CreateKey(subkey, "PythonSample")
- _winreg.SetValueEx(subkey2, None, 0, _winreg.REG_SZ, ShellExtension._reg_clsid_)
- print ShellExtension._reg_desc_, "registration complete."
- def DllUnregisterServer():
- import _winreg
- try:
- key = _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT,
- "Python.File\\shellex\\ContextMenuHandlers\\PythonSample")
- except WindowsError, details:
- import errno
- if details.errno != errno.ENOENT:
- raise
- print ShellExtension._reg_desc_, "unregistration complete."
- if __name__=='__main__':
- from win32com.server import register
- register.UseCommandLine(ShellExtension,
- finalize_register = DllRegisterServer,
- finalize_unregister = DllUnregisterServer)
|