Attachment 'sysmenu.py'
Download 1 #!/usr/bin/env python
2 #coding=utf-8
3
4 # Module : sysmenu.py
5 # author : Oswaldo Hernández - oswaldo@soft-com.es
6 # Date : 16-11-2009
7 # License : wxPython license
8
9 """
10 Add methods to Frames and Dialogs to use the system menu.
11 """
12 import wx
13
14 if wx.Platform != '__WXMSW__':
15 raise NotImplementedError("Only Implemented in Windows")
16
17 import ctypes
18 user32 = ctypes.windll.user32
19 GWL_WNDPROC = -4
20 WM_DESTROY = 0x0002 # 2
21 WM_SYSCOMMAND = 0x0112 # 274
22 MF_BYCOMMAND = 0x00000000L
23 MF_BYPOSITION = 0x00000400L
24 MF_SEPARATOR = 0x00000800L #2048
25 MF_STRING = 0x00000000L # 0
26 MF_UNCHECKED = 0x00000000L
27 MF_CHECKED = 0x00000008L
28 MF_ENABLED = 0x00000000L
29 MF_GRAYED = 0x00000001L
30 MF_DISABLED = 0x00000002L
31 MF_UNHILITE = 0x00000000L
32 MF_HILITE = 0x00000080L
33
34 class mixSysMenu:
35
36 __SysMenuProcOrg = None
37 __SysMenuHandlers = None
38
39 # --- Public methods ---
40
41 def SysMenuAppendItem(self, MenuText, ItemId, CallBack):
42 """
43 Append option to system menu
44 MenuText: Text to display
45 MenuId: Identifier for the option, the ID must be unique.
46 If the identifier is None will be generated automatically.
47 CallBack: method or function to execute when you select the option
48 CallBack prototype:
49 def OnSysMenu(self, ItemId)
50 """
51 if not self.IsTopLevel():
52 raise ValueError("mixSysMenu only for Top Level Windows")
53
54 hWnd = self.GetHandle()
55 if not ItemId: ItemId = wx.NewId()
56 SysMenu = user32.GetSystemMenu(hWnd, 0)
57 user32.AppendMenuW(SysMenu, MF_STRING, ItemId, unicode(MenuText))
58
59 if not self.__SysMenuProcOrg:
60 Prototype = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_long, ctypes.c_int, ctypes.c_int, ctypes.c_int)
61 self.__NewProc = Prototype(self.__SysMenuHandler)
62 self.__SysMenuProcOrg = user32.SetWindowLongW(hWnd, GWL_WNDPROC, self.__NewProc)
63 self.__SysMenuHandlers = {}
64
65 self.__SysMenuHandlers[ItemId] = CallBack
66
67 def SysMenuAddSeparator(self):
68 """ Append separator line """
69 SysMenu = user32.GetSystemMenu(self.GetHandle(), 0)
70 user32.AppendMenuW(SysMenu, MF_SEPARATOR, 0, 0)
71
72 def SysMenuSetState(self, ItemId, state):
73 """
74 Set a new state to the menu item.
75 States: MF_CHECKED, MF_UNCHECKED, MF_GRAYED, MF_ENABLED, MF_DISABLED,
76 MF_HILITE, MF_UNHILITE
77 """
78 SysMenu = user32.GetSystemMenu(self.GetHandle(), 0)
79 text = self.SysMenuGetMenuString(ItemId)
80 user32.ModifyMenuW(SysMenu, ItemId, MF_BYCOMMAND|MF_STRING|state, ItemId, text)
81
82 def SysMenuGetState(self, ItemId, state):
83 """ Checks if the item is in the state indicated """
84 SysMenu = user32.GetSystemMenu(self.GetHandle(), 0)
85 mask = user32.GetMenuState(SysMenu, ItemId, MF_BYCOMMAND)
86 return mask & state == state
87
88 def SysMenuSetText(self, ItemId, MenuText):
89 """ Change item text """
90 SysMenu = user32.GetSystemMenu(self.GetHandle(), 0)
91 flags = user32.GetMenuState(SysMenu, ItemId, MF_BYCOMMAND)
92 user32.ModifyMenuW(SysMenu, ItemId, MF_BYCOMMAND|MF_STRING|flags, ItemId, unicode(MenuText))
93
94 def SysMenuGetMenuString(self, ItemId):
95 """ Get item text """
96 SysMenu = user32.GetSystemMenu(self.GetHandle(), 0)
97 buf = ctypes.create_unicode_buffer('\000' * 128)
98 user32.GetMenuStringW(SysMenu, ItemId, buf, 100, MF_BYCOMMAND)
99 return buf.value
100
101 def SysMenuDeleteItem(self, ItemId):
102 """ Delete item """
103 SysMenu = user32.GetSystemMenu(self.GetHandle(), 0)
104 user32.DeleteMenu(SysMenu, ItemId, MF_BYCOMMAND)
105
106 def SysMenuGetItemsList(self):
107 """ Get list of (ItemId, ItemText)
108 """
109 SysMenu = user32.GetSystemMenu(self.GetHandle(), 0)
110 nItems = user32.GetMenuItemCount(SysMenu)
111 Items = []
112 for i in range(nItems):
113 itemid = user32.GetMenuItemID(SysMenu, i)
114 #if id in self.__SysMenuHandlers or id == 0:
115 if itemid in self.__SysMenuHandlers:
116 Items.append((itemid, self.SysMenuGetMenuString(itemid)))
117
118 return Items
119
120 # --- Internal Handler ---
121
122 def __SysMenuHandler(self, hWnd, msg, wParam, lParam):
123 if msg == WM_DESTROY:
124 user32.SetWindowLongW(hWnd, GWL_WNDPROC, self.__SysMenuProcOrg)
125
126 elif msg == WM_SYSCOMMAND and wParam in self.__SysMenuHandlers:
127 #self.__SysMenuHandlers[wParam](wParam)
128 wx.CallAfter(self.__SysMenuHandlers[wParam], wParam)
129
130 return user32.CallWindowProcW(self.__SysMenuProcOrg, hWnd, msg, wParam, lParam)
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.