1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
# Simple TortoiseSVN-like Bazaar plugin for the Windows Shell
# Published under the GNU GPL, v2 or later.
# Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
import pythoncom
from win32com.shell import shell, shellcon
import win32gui
import win32con
"""Windows shell extension that adds context menu items to Bazaar branches."""
class BazaarShellExtension:
_reg_progid_ = "Bazaar.ShellExtension.ContextMenu"
_reg_desc_ = "Bazaar Shell Extension"
_reg_clsid_ = "{EEE9936B-73ED-4D45-80C9-AF918354F885}"
_com_interfaces_ = [shell.IID_IShellExtInit, shell.IID_IContextMenu]
_public_methods_ = [
"Initialize", # From IShellExtInit
"QueryContextMenu", "InvokeCommand", "GetCommandString" # IContextMenu
]
def Initialize(self, folder, dataobj, hkey):
self.dataobj = dataobj
def QueryContextMenu(self, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags):
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 = []
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
# FIXME: Run the actual command
def GetCommandString(self, cmd, typ):
return "Hello from Python!!"
registryKeys = [
"*\\shellex\\ContextMenuHandlers",
"Directory\\Background\\shellex\\ContextMenuHandlers",
"Directory\\shellex\\ContextMenuHandlers",
"Folder\\shellex\\ContextmenuHandlers"
]
def DllRegisterServer():
import _winreg
for keyname in registryKeys:
key = _winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT, keyname)
subkey = _winreg.CreateKey(key, "TortoiseBzr")
_winreg.SetValueEx(subkey, None, 0, _winreg.REG_SZ, BazaarShellExtension._reg_clsid_)
_winreg.CloseKey(subkey)
_winreg.CloseKey(key)
print BazaarShellExtension._reg_desc_, "registration complete."
def DllUnregisterServer():
import _winreg
try:
for keyname in registryKeys:
_winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT,
"%s\\TortoiseBzr" % keyname)
except WindowsError, details:
import errno
if details.errno != errno.ENOENT:
raise
print BazaarShellExtension._reg_desc_, "unregistration complete."
if __name__ == '__main__':
from win32com.server import register
register.UseCommandLine(BazaarShellExtension,
finalize_register = DllRegisterServer,
finalize_unregister = DllUnregisterServer)
|