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.
  • [get | view] (2009-11-18 19:31:58, 4.1 KB) [[attachment:sysmenu-test.py]]
  • [get | view] (2009-11-18 19:47:48, 4.7 KB) [[attachment:sysmenu.py]]
  • [get | view] (2009-11-18 19:22:28, 8.6 KB) [[attachment:sysmenu1.png]]
  • [get | view] (2009-11-18 19:22:46, 13.0 KB) [[attachment:sysmenu2.png]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.