# This script demonstrates changing the color of the menu bar/individual
# menus in a wxPython UI for the Win32 platform
# Requires
# - ctypes to access the user32 and gdi32 modules, to set up structures
# and other win32 oriented helper functions
# - pywin32 module, to use win32con and access constants (this is optional
# but really handy). Alternative is to get the values of the constants
# from MSDN.
import wx
import win32con
from ctypes import *
import sys
# Structure passed to CreateSolidBrush function
# Represents RGB
class COLORREF(Structure):
_fields_ = [
("byRed", c_byte),
("byGreen", c_byte),
("byBlue", c_byte)
]
# Menu structure used in calls to SetMenuInfo
class MENUINFO(Structure):
_fields_ = [
("cbSize", c_long),
("fMask", c_long),
("dwStyle", c_long),
('cyMax', c_long),
("hbrBack", c_long),
("dwContextHelpID", c_long),
("dwMenuData", c_long)
]
class TestFrame(wx.Frame):
"""
Subclass of wx.Frame that presents the app's main window
"""
def __init__(self, parent, id=-1, title='Test Menu',
pos=wx.DefaultPosition,
size=wx.DefaultSize,
style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE,
name='TestFrame',
shadesubmenus=False):
wx.Frame.__init__(self, parent, id, title, pos, size, style, name)
self.bShadeSubMenus = shadesubmenus
menubar = wx.MenuBar()
menu1 = wx.Menu()
menu1.Append(-1, 'Open', 'Open new file')
menu1.Append(-1, 'Exit', 'Quit application')
menubar.Append(menu1, 'File')
menu2 = wx.Menu()
menu2.Append(-1, 'About', 'About')
menubar.Append(menu2, 'Help')
self.SetMenuBar(menubar)
self.Show(True)
self.size = self.GetSize()
# Get my windows handle - hwnd
self.hwnd = self.GetHandle()
self.ChangeMenuBarColor()
def ChangeMenuBarColor(self):
"""
Changes the background color of the menubar and optionally gives
different colors to menu items
"""
user32 = windll.user32
DrawMenuBar = user32.DrawMenuBar
GetMenu = user32.GetMenu
GetSubMenu = user32.GetSubMenu
GetSystemMenu = user32.GetSystemMenu
SetMenuInfo = user32.SetMenuInfo
GetMenuInfo = user32.GetMenuInfo
gdi32 = windll.gdi32
CreateSolidBrush = gdi32.CreateSolidBrush
# Instantiate MENUINFO
menuinfo = MENUINFO()
# Important to set the size
menuinfo.cbSize = sizeof(MENUINFO)
menuinfo.fMask = win32con.MIM_BACKGROUND
if not self.bShadeSubMenus:
menuinfo.fMask |= win32con.MIM_APPLYTOSUBMENUS
menuinfo.hbrBack = CreateSolidBrush(COLORREF(255, 0, 0))
# Important! Pass *pointer* of the menuinfo instance to the win32 call
SetMenuInfo(GetMenu(self.hwnd), pointer(menuinfo))
if self.bShadeSubMenus:
menuinfo.fMask = win32con.MIM_BACKGROUND | win32con.MIM_APPLYTOSUBMENUS
menuinfo.hbrBack = CreateSolidBrush(COLORREF(255, 255, 0))
SetMenuInfo(GetSubMenu(GetMenu(self.hwnd), 0), pointer(menuinfo))
menuinfo.fMask = win32con.MIM_BACKGROUND | win32con.MIM_APPLYTOSUBMENUS
menuinfo.hbrBack = CreateSolidBrush(COLORREF(128, 255, 128))
SetMenuInfo(GetSubMenu(GetMenu(self.hwnd), 1), pointer(menuinfo))
DrawMenuBar(self.hwnd)
if __name__ == '__main__':
try:
bShadeSubMenus = sys.argv[1]
except:
bShadeSubMenus = False
app = wx.PySimpleApp()
f = TestFrame(None, shadesubmenus=bShadeSubMenus)
app.MainLoop()