I found a recipe on ActiveState's Cookbook that shows how to change colours of an application's menu, and immediately recalled that Mushclient has that world.GetFrame callback. So here's a function that will add some colour to the menu bar in Mushclient. This requires you to have the ctypes package installed (in addition to a working Python installation of course). Ctypes is a tiny extension that allows you to call native DLL's - both *nix and Windows - directly from Python without requiring any additional wrapping.
| | | """ Borrowed from ASPN Cookbook recipe: | | aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440507 | | """ | | | | import win32con | | from ctypes import * | | | | | | | | | | | | class COLORREF(Structure): | | _fields_ = [ | | ("byRed", c_byte), | | ("byGreen", c_byte), | | ("byBlue", c_byte) | | ] | | | | | | 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) | | ] | | | | 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 | | | | def ChangeMenuBarColor(): | | """ | | Changes the background color of the menubar and optionally gives | | different colors to menu items | | """ | | col = COLORREF(255,255,255) | | | | hwnd = c_int(int(world.GetFrame)) | | | | menuinfo = MENUINFO() | | | | menuinfo.cbSize = sizeof(MENUINFO) | | menuinfo.fMask = win32con.MIM_BACKGROUND | | col = COLORREF(55, 150, 12) | | menuinfo.hbrBack = CreateSolidBrush(col) | | | | SetMenuInfo(GetMenu(hwnd), byref(menuinfo)) | | menuinfo.fMask = win32con.MIM_BACKGROUND | win32con.MIM_APPLYTOSUBMENUS | | col = COLORREF(255, 255, 0) | | menuinfo.hbrBack = CreateSolidBrush(col) | | SetMenuInfo(GetSubMenu(GetMenu(hwnd), 0), byref(menuinfo)) | | menuinfo.fMask = win32con.MIM_BACKGROUND | win32con.MIM_APPLYTOSUBMENUS | | col = COLORREF(128, 255, 128) | | menuinfo.hbrBack = CreateSolidBrush(col) | | SetMenuInfo(GetSubMenu(GetMenu(hwnd), 1), byref(menuinfo)) | | menuinfo.fMask = win32con.MIM_BACKGROUND | win32con.MIM_APPLYTOSUBMENUS | | menuinfo.hbrBack = CreateSolidBrush(col) | | SetMenuInfo(GetSubMenu(GetMenu(hwnd), 2), byref(menuinfo)) | | menuinfo.fMask = win32con.MIM_BACKGROUND | win32con.MIM_APPLYTOSUBMENUS | | menuinfo.hbrBack = CreateSolidBrush(col) | | SetMenuInfo(GetSubMenu(GetMenu(hwnd), 3), byref(menuinfo)) | | menuinfo.fMask = win32con.MIM_BACKGROUND | win32con.MIM_APPLYTOSUBMENUS | | menuinfo.hbrBack = CreateSolidBrush(col) | | SetMenuInfo(GetSubMenu(GetMenu(hwnd), 4), byref(menuinfo)) | | menuinfo.fMask = win32con.MIM_BACKGROUND | win32con.MIM_APPLYTOSUBMENUS | | menuinfo.hbrBack = CreateSolidBrush(col) | | SetMenuInfo(GetSubMenu(GetMenu(hwnd), 5), byref(menuinfo)) | | menuinfo.fMask = win32con.MIM_BACKGROUND | win32con.MIM_APPLYTOSUBMENUS | | menuinfo.hbrBack = CreateSolidBrush(col) | | SetMenuInfo(GetSubMenu(GetMenu(hwnd), 6), byref(menuinfo)) | | menuinfo.fMask = win32con.MIM_BACKGROUND | win32con.MIM_APPLYTOSUBMENUS | | menuinfo.hbrBack = CreateSolidBrush(col) | | SetMenuInfo(GetSubMenu(GetMenu(hwnd), 7), byref(menuinfo)) | | menuinfo.fMask = win32con.MIM_BACKGROUND | win32con.MIM_APPLYTOSUBMENUS | | menuinfo.hbrBack = CreateSolidBrush(col) | | SetMenuInfo(GetSubMenu(GetMenu(hwnd), 8), byref(menuinfo)) | | menuinfo.fMask = win32con.MIM_BACKGROUND | win32con.MIM_APPLYTOSUBMENUS | | menuinfo.hbrBack = CreateSolidBrush(col) | | SetMenuInfo(GetSubMenu(GetMenu(hwnd), 9), byref(menuinfo)) | | | | DrawMenuBar(hwnd) | | | | |
As you can see, after getting the window handle from Mushclient, the function above makes direct calls to User32 and GDI32 Windows libraries to set the new colour values. Put the above in your world file and just enter:
/ChangeMenuBarColor()
in the input window (if you have inline scripting enabled and your script prefix is the default "/").
The functionality of ctypes isn't limited to changing menu colours only, of course. There's alot more one can do with Win API, but as I don't know it at all I can't think of any particularly cool ways to hack up Mushclient's interface. Ideas?
EDIT: I seem to have somehow broken and then fixed this back. |
댓글
댓글 쓰기