Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ Python ➜ Colourize your menu

Colourize your menu

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Ked   Russia  (524 posts)  Bio
Date Fri 09 Sep 2005 11:16 AM (UTC)

Amended on Fri 09 Sep 2005 12:50 PM (UTC) by Ked

Message
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 *



# 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)
    ]

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)
    # Get the frame handle
    hwnd = c_int(int(world.GetFrame))
    # Instantiate MENUINFO
    menuinfo = MENUINFO()
    # Important to set the size
    menuinfo.cbSize = sizeof(MENUINFO)
    menuinfo.fMask = win32con.MIM_BACKGROUND
    col = COLORREF(55, 150, 12)
    menuinfo.hbrBack = CreateSolidBrush(col)
    # Important! Pass *pointer* of the menuinfo instance to the win32 call
    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.
Top

Posted by Shadowfyr   USA  (1,790 posts)  Bio
Date Reply #1 on Fri 09 Sep 2005 05:57 PM (UTC)
Message
http://www.mentalis.org/agnet/apiguide.shtml

The program they have here is useful, but not 100% complete. It only contains calls and examples that they have provided such examples of on their site and 'some' things are missing, like the actual values of certain flags. Or in others words if they list:

SOMETHING - Does something.
SOMETHING2 - Does something else.

It won't tell you that 'something' = 0x02 and 'something2' = 0x04. You end up having to check Microsoft's site for that, or a developers handbook/MFC Bible, etc.

As an example of the limitations, the API Guide (for the WinInet API) contains InternetGetConnectedState, but *not* InternetGetConnectedStateEx, InternetHangUp, InternetDial, InternetAutoDial or InternetAutoDialHangUp. You could therefor (if using a dialup modem), detect 'if' its connected but not dial in or disconnect by looking in the API Guide for how. I have no idea what other functions are missing, but probably a lot. Still, its interesting to look through and more convenient that paying $60+ for a book that also misses things or hunting online for something you don't really know the name of. ;)
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


15,348 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.