Hello!
I would like to beautify my menuitem for the SystemTray Example, does it possible? But it always show "int numOldMenu = myMenu.Count;" has problem? Why?
The coding of SystemTrayExample is listed as following (SystemTray.cs):
using System;
using System.Drawing;
using System.Resources;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading ;
using Utility.NiceMenu;
namespace Demo
{
public class SystemTray : System.Windows.Forms.Form
{
private System.Windows.Forms.NotifyIcon WSNotifyIcon;
private System.ComponentModel.IContainer components;
private Icon mDirIcon = new Icon(typeof(SystemTray).Assembly.GetManifestResourceStream("SystemTrayExample.FLGUSA02.ICO"));
//private NiceMenu myMenu ;
public SystemTray()
{
//constructor for the form
InitializeComponent();
//keep the form hidden
this.Hide();
//OnMyMenu();
//InitializeNotifyIcon();
NiceMenu myNiceMenu = new NiceMenu();
myNiceMenu.UpdateMenu (this.ContextMenu ,new NiceMenuClickEvent (InitializeNotifyIcon));
}
///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.WSNotifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
//
// WSNotifyIcon
//
this.WSNotifyIcon.Text = "";
this.WSNotifyIcon.Visible = true;
//this.WSNotifyIcon.MouseDown += new System.Windows.Forms.MouseEventHandler(this.WSNotifyIcon_MouseDown);
//
// SystemTray
//
this.AccessibleRole = System.Windows.Forms.AccessibleRole.None;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(8, 7);
this.ControlBox = false;
this.Enabled = false;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "SystemTray";
this.Opacity = 0;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
}
#endregion
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.Run(new SystemTray());
}
public void ExitControlForm(object sender, EventArgs e)
{
//Hide the NotifyIcon.
WSNotifyIcon.Visible=false;
this.Close();
}
//private void InitializeNotifyIcon()
private void InitializeNotifyIcon(object sender, System.EventArgs e)
{
//setup the Icon
NotifyIcon WSNotifyIcon = new NotifyIcon();
WSNotifyIcon.Icon = mDirIcon;
WSNotifyIcon.Text = "System Tray Example";
WSNotifyIcon.Visible = true;
//Create the submenus - any number will do
MenuItem[] subMnuItems1 = new MenuItem[3];
subMnuItems1[0] = new MenuItem("Submenu 1", new EventHandler(this.ExitControlForm));
subMnuItems1[1] = new MenuItem("Submenu 2", new EventHandler(this.ExitControlForm));
subMnuItems1[2] = new MenuItem("Submenu 3", new EventHandler(this.ExitControlForm));
//Create the MenuItem objects and add them to
//the context menu of the NotifyIcon.
MenuItem[] mnuItems = new MenuItem[3];
//create the menu items array
mnuItems[0] = new MenuItem("Sub Menu Items");
mnuItems[0].MenuItems.AddRange(subMnuItems1);
mnuItems[0].DefaultItem=true;
mnuItems[1] = new MenuItem("-");
mnuItems[2] = new MenuItem("Exit", new EventHandler(this.ExitControlForm));
//add the menu items to the context menu of the NotifyIcon
ContextMenu notifyIconMenu = new ContextMenu(mnuItems);
WSNotifyIcon.ContextMenu=notifyIconMenu;
}
}
}
The coding of NiceMenu is listed as following (NiceMenu.cs):
/* ***************************************
* NiceMenu.cs (v 1.1)
* --------------------------------------
* This is an improvement by Francesco Natali (
[email protected])
* over an improvement by Sajith M
* of the "Visual Studio .NET Menu Style"
* by Carlos H. Perez that appeared on CodeProject
* (http://www.codeproject.com)
* ---------------------------------------
* How to use it
* You have to add:
* using Utility.NiceMenu;
* and after the "InitializeComponent()" code:
* NiceMenu myNiceMenu = new NiceMenu();
* myNiceMenu.UpdateMenu(this.nameofyourmainmenu, new NiceMenuClickEvent(nameofyourclickfunction));
* ---------------------------------------
* With only three lines of code your menu
* will be AUTOMATICALLY updated with
* a new great .Net style menu!
* ****************************************/
namespace Utility.NiceMenu
{
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Text;
using System.Diagnostics;
using System.Collections;
/* ******************************************************
* NiceMenuClickEvent(object sender, System.EventArgs e)
* ------------------------------------------------------
* this is a delegate event that will be initializate with
* the user function to handle the click event on the menu
* ******************************************************/
public delegate void NiceMenuClickEvent(object sender, System.EventArgs e);
/* ******************************************************
* This is a simple example of a function
* to handle the click event:
* -----------------------------------------------------
public void myClickMenuEvent(object sender, System.EventArgs e)
{
if (typeof(NiceMenu).IsInstanceOfType(sender))
{
NiceMenu item = (NiceMenu)sender;
MessageBox.Show(item.Text); //example
}
}
* ******************************************************/
///
/// A great and free improvement menu class!
///
public class NiceMenu : MenuItem
{
/* If you want to add some incons in your menu
* you have to:
* 1. add an imagelist control in your form
* 2. add your icons in your imagelist control
* 3. add in your menu items the index of the icon
* in the first two characters. For example:
* 00New
* 01Open
* 02Close
* 4. After the "NiceMenu myNiceMenu = new NiceMenu();" code
* you have to add this simple line of code:
* myNiceMenu.imgMenu = nameofyourimagelist;
* */
///
/// Set "MenuImages" with the your ImageList to add icons in your menu.
///
public ImageList MenuImages;
// NiceMenu array to save the main menu item
// so at runtime i can search an item and modify it
private static NiceMenu[] myModifyNiceMenu = new NiceMenu[20];
private static NiceMenu[] myModifyContextNiceMenu = new NiceMenu[20];
private static int contModify = 0;
private static int contModifyContext = 0;
private static Color window;
// Some useful properties to change the color of your menu
private static Color backcolor;
private static Color barcolor;
private static Color selectioncolor;
private static Color framecolor;
private static int iconSize = SystemInformation.SmallIconSize.Width + 5;
private static int itemHeight;
private static bool doColorUpdate = false;
private string shortcuttext = "";
private Image icon = null;
private static int BITMAP_SIZE = 16;
private static int STRIPE_WIDTH = iconSize + 5;
public NiceMenu() : base()
{
OwnerDraw = true; UpdateColors();
}
private NiceMenu(string name) : base(name)
{
OwnerDraw = true; UpdateColors();
}
// public for the AddRecentFile function
public NiceMenu(string name, EventHandler handler) : base(name, handler)
{
OwnerDraw = true; UpdateColors();
}
private NiceMenu(string name, NiceMenu[] items) : base(name, items)
{
OwnerDraw = true; UpdateColors();
}
private NiceMenu(string name, EventHandler handler, Shortcut shortcut) : base(name, handler, shortcut)
{
OwnerDraw = true; UpdateColors();
}
private NiceMenu(MenuMerge mergeType, int mergeOrder, Shortcut shortcut, string name, EventHandler onClick, EventHandler onPopup, EventHandler onSelect, NiceMenu[] items) : base(mergeType, mergeOrder, shortcut, name, onClick, onPopup, onSelect, items)
{
OwnerDraw = true; UpdateColors();
}
private NiceMenu(string name, Image img) : this(name)
{
icon = img;
}
private NiceMenu(string name, EventHandler handler, Image img) : this(name, handler)
{
icon = img;
}
private NiceMenu(string name, EventHandler handler, Shortcut shortcut, Image img) : this(name, handler, shortcut)
{
icon = img;
}
// *********************************************************
private Image Icon
{
get
{ return icon; }
set
{ icon = value; }
}
private string ShortcutText
{
get
{ return shortcuttext; }
set
{ shortcuttext = value; }
}
public Color SelectionColor
{
get
{ return selectioncolor; }
set
{ selectioncolor = value; }
}
public Color BackColor
{
get
{ return backcolor; }
set
{ backcolor = value; }
}
public Color BarColor
{
get
{ return barcolor; }
set
{ barcolor = value; }
}
public Color FrameColor
{
get
{ return framecolor; }
set
{ framecolor = value; }
}
//************************************************************************
private void UpdateColors()
{
window = SystemColors.Window;
backcolor = SystemColors.ControlLightLight;
barcolor = SystemColors.Control;
selectioncolor = SystemColors.Highlight;
framecolor = SystemColors.Highlight;
int wa = (int)window.A;
int wr = (int)window.R;
int wg = (int)window.G;
int wb = (int)window.B;
int mna = (int)backcolor.A;
int mnr = (int)backcolor.R;
int mng = (int)backcolor.G;
int mnb = (int)backcolor.B;
int sta = (int)barcolor.A;
int str = (int)barcolor.R;
int stg = (int)barcolor.G;
int stb = (int)barcolor.B;
int sla = (int)selectioncolor.A;
int slr = (int)selectioncolor.R;
int slg = (int)selectioncolor.G;
int slb = (int)selectioncolor.B;
backcolor = Color.FromArgb(wr-(((wr-mnr)*2)/5), wg-(((wg-mng)*2)/5), wb-(((wb-mnb)*2)/5));
barcolor = Color.FromArgb(wr-(((wr-str)*4)/5), wg-(((wg-stg)*4)/5), wb-(((wb-stb)*4)/5));
selectioncolor = Color.FromArgb(wr-(((wr-slr)*2)/5), wg-(((wg-slg)*2)/5), wb-(((wb-slb)*2)/5));
}
private static void UpdateMenuColors()
{
doColorUpdate = true;
}
private void DoUpdateMenuColors()
{
UpdateColors();
doColorUpdate = false;
}
protected override void OnMeasureItem(MeasureItemEventArgs e)
{
base.OnMeasureItem(e);
if (Shortcut != Shortcut.None)
{
string text = "";
int key = (int)Shortcut;
int ch = key & 0xFF;
if (((int)Keys.Control & key) > 0) text += "Ctrl+";
if (((int)Keys.Shift & key) > 0) text += "Shift+";
if (((int)Keys.Alt & key) > 0) text += "Alt+";
if (ch >= (int)Shortcut.F1 && ch <= (int)Shortcut.F12)
text += "F" + (ch - (int)Shortcut.F1 + 1);
else
{
if ( Shortcut == Shortcut.Del)
{
text += "Del";
}
else
{
text += (char)ch;
}
}
shortcuttext = text;
}
if (Text == "-")
{
e.ItemHeight = 8;
e.ItemWidth = 4;
return;
}
bool topLevel = Parent == Parent.GetMainMenu();
string tempShortcutText = shortcuttext;
if ( topLevel )
{
tempShortcutText = "";
}
int textwidth = (int)(e.Graphics.MeasureString(Text + tempShortcutText, SystemInformation.MenuFont).Width);
int extraHeight = 4;
e.ItemHeight = SystemInformation.MenuHeight + extraHeight;
if ( topLevel )
e.ItemWidth = textwidth - 5;
else
e.ItemWidth = Math.Max(160, textwidth + 50);
itemHeight = e.ItemHeight;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
if ( doColorUpdate)
{
DoUpdateMenuColors();
}
base.OnDrawItem(e);
Graphics g = e.Graphics;
Rectangle bounds = e.Bounds;
bool selected = (e.State & DrawItemState.Selected) > 0;
bool toplevel = (Parent == Parent.GetMainMenu());
bool hasicon = Icon != null;
bool enabled = Enabled;
DrawBackground(g, bounds, e.State, toplevel, hasicon, enabled);
if (hasicon)
DrawIcon(g, Icon, bounds, selected, Enabled, Checked);
else
{
if (Checked)
DrawCheckmark(g, bounds, selected);
if (RadioCheck)
DrawRadioCheckmark(g, bounds, selected);
}
if (Text == "-")
{ DrawSeparator(g, bounds); }
else
{ DrawMenuText(g, bounds, Text, shortcuttext, Enabled, toplevel, e.State); }
}
/* ******************************
* DrawRadioCheckmark
* ******************************/
private void DrawRadioCheckmark(Graphics g, Rectangle bounds, bool selected)
{
int checkTop = bounds.Top + (itemHeight - BITMAP_SIZE)/2;
int checkLeft = bounds.Left + ( STRIPE_WIDTH - BITMAP_SIZE)/2;
ControlPaint.DrawMenuGlyph(g, new Rectangle(checkLeft, checkTop, BITMAP_SIZE, BITMAP_SIZE), MenuGlyph.Bullet);
g.DrawRectangle(new Pen(framecolor), checkLeft-1, checkTop-1, BITMAP_SIZE+1, BITMAP_SIZE+1);
}
private void DrawCheckmark(Graphics g, Rectangle bounds, bool selected)
{
int checkTop = bounds.Top + (itemHeight - BITMAP_SIZE)/2;
int checkLeft = bounds.Left + ( STRIPE_WIDTH - BITMAP_SIZE)/2;
ControlPaint.DrawMenuGlyph(g, new Rectangle(checkLeft, checkTop, BITMAP_SIZE, BITMAP_SIZE), MenuGlyph.Checkmark);
g.DrawRectangle(new Pen(framecolor), checkLeft-1, checkTop-1, BITMAP_SIZE+1, BITMAP_SIZE+1);
}
private void DrawIcon(Graphics g, Image icon, Rectangle bounds, bool selected, bool enabled, bool ischecked)
{
int iconTop = bounds.Top + (itemHeight - BITMAP_SIZE)/2;
int iconLeft = bounds.Left + (STRIPE_WIDTH - BITMAP_SIZE)/2;
if (enabled)
{
if (selected)
{
ControlPaint.DrawImageDisabled(g, icon, iconLeft + 1, iconTop, Color.Black);
g.DrawImage(icon, iconLeft, iconTop-1);
}
else
{
g.DrawImage(icon, iconLeft + 1, iconTop);
}
}
else
{
ControlPaint.DrawImageDisabled(g, icon, iconLeft + 1, iconTop, SystemColors.HighlightText);
}
}
private void DrawSeparator(Graphics g, Rectangle bounds)
{
int y = bounds.Y + bounds.Height / 2;
g.DrawLine(new Pen(SystemColors.ControlDark), bounds.X + iconSize + 7, y, bounds.X + bounds.Width - 2, y);
}
private void DrawBackground(Graphics g, Rectangle bounds, DrawItemState state, bool toplevel, bool hasicon, bool enabled)
{
bool selected = (state & DrawItemState.Selected) > 0;
if (selected || ((state & DrawItemState.HotLight) > 0))
{
if (toplevel && selected)
{
bounds.Inflate(-1, 0);
g.FillRectangle(new SolidBrush(barcolor), bounds);
ControlPaint.DrawBorder3D(g, bounds.Left, bounds.Top, bounds.Width, bounds.Height, Border3DStyle.Flat, Border3DSide.Top | Border3DSide.Left | Border3DSide.Right);
}
else
{
if ( enabled )
{
g.FillRectangle(new SolidBrush(selectioncolor), bounds);
g.DrawRectangle(new Pen(framecolor), bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);
}
else
{
g.FillRectangle(new SolidBrush(barcolor), bounds);
bounds.X += STRIPE_WIDTH;
bounds.Width -= STRIPE_WIDTH;
g.FillRectangle(new SolidBrush(backcolor), bounds);
}
}
}
else
{
if (!toplevel)
{
g.FillRectangle(new SolidBrush(barcolor), bounds);
bounds.X += STRIPE_WIDTH;
bounds.Width -= STRIPE_WIDTH;
g.FillRectangle(new SolidBrush(backcolor), bounds);
}
else
{
g.FillRectangle(SystemBrushes.Control, bounds);
}
}
}
private void DrawMenuText(Graphics g, Rectangle bounds, string text, string shortcut, bool enabled, bool toplevel, DrawItemState state )
{
StringFormat stringformat = new StringFormat();
stringformat.HotkeyPrefix = ((state & DrawItemState.NoAccelerator) > 0) ? HotkeyPrefix.Hide : HotkeyPrefix.Show;
if ( toplevel )
{
int index = text.IndexOf("&");
if ( index != -1 )
{
text = text.Remove(index,1);
}
}
int textwidth = (int)(g.MeasureString(text, SystemInformation.MenuFont).Width);
int x = toplevel ? bounds.Left + (bounds.Width - textwidth) / 2: bounds.Left + iconSize + 10;
int topGap = 4;
if ( toplevel ) topGap = 2;
int y = bounds.Top + topGap;
Brush brush = null;
if (!enabled)
brush = new SolidBrush(SystemColors.GrayText);
else
brush = new SolidBrush(SystemColors.MenuText);
g.DrawString(text, SystemInformation.MenuFont, brush, x, y, stringformat);
if ( !toplevel )
{
stringformat.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
g.DrawString(shortcut, SystemInformation.MenuFont, brush, bounds.Width - 10 , bounds.Top + topGap, stringformat);
}
}
/* ******************************************************
* UpdateMenu(MainMenu yourOldMenu)
* UpdateMenu(ContextMenu yourOldMenu)
* ------------------------------------------------------
* this function will update the user old menu
* ******************************************************/
///
/// this function will update your Main Menu.
///
public void UpdateMenu(MainMenu yourOldMenu, NiceMenuClickEvent yourClickFunction)
{
IList myMenuList = new Menu.MenuItemCollection(yourOldMenu);
BuildMenuTree(myMenuList, yourOldMenu, yourClickFunction);
}
///
/// this function will update your Context Menu.
///
public void UpdateMenu(ContextMenu yourOldMenu, NiceMenuClickEvent yourClickFunction)
{
IList myMenuList = new Menu.MenuItemCollection(yourOldMenu);
BuildMenuTree(myMenuList, yourOldMenu, yourClickFunction);
}
/* ***********************************************************
* BuildMenuTree (IList myMenu, MenuItem parentMenu)
* -----------------------------------------------------------
* build the new submenu item
* ***********************************************************/
private void BuildMenuTree(IList myMenu, MenuItem parentMenu, NiceMenuClickEvent yourClickFunction)
{
foreach (MenuItem myMenuItem in myMenu)
{
// Declaration
NiceMenu newSubMenu;
string IndexImage = "";
bool AddMenuImage = false;
/* If in the first two characters of the menu item text
* there is a number I set AddMenuImage = true and the
* IndexImage to get the icon in the image list control. */
if (myMenuItem.Text.Length > 2)
{
IndexImage = myMenuItem.Text.Substring(0,2);
if (Char.IsNumber(IndexImage,1) == true)
{
AddMenuImage = true;
// I have to delete first two characters
myMenuItem.Text = myMenuItem.Text.Substring(2);
}
}
if (AddMenuImage == true)
newSubMenu = new NiceMenu(myMenuItem.Text, new EventHandler(yourClickFunction), myMenuItem.Shortcut, MenuImages.Images[Convert.ToInt32(IndexImage)]);
else
newSubMenu = new NiceMenu(myMenuItem.Text, new EventHandler(yourClickFunction), myMenuItem.Shortcut);
// I add the new menu item to its parent
parentMenu.MenuItems.Add(newSubMenu);
// Checked
if (myMenuItem.Checked == true) newSubMenu.Checked = true;
// RadioCheck
if (myMenuItem.RadioCheck == true)
if (myMenuItem.Checked == true) newSubMenu.RadioCheck = true;
// DefaultItem
if (myMenuItem.DefaultItem == true) newSubMenu.DefaultItem = true;
// Enabled
if (myMenuItem.Enabled == false) newSubMenu.Enabled = false;
// If this menu item contains child menu items
if (myMenuItem.IsParent == true)
{
IList mySubMenu = new Menu.MenuItemCollection(myMenuItem);
BuildMenuTree(mySubMenu, newSubMenu, yourClickFunction);
}
}
}
/* ***********************************************************
* BuildMenuTree (IList myMenu, MainMenu parentMenu)
* BuildMenuTree (IList myMenu, ContextMenu parentMenu, NiceMenuClickEvent yourClickFunction)
* -----------------------------------------------------------
* build the new main menus and delete the old ones
* ***********************************************************/
private void BuildMenuTree(IList myMenu, MainMenu parentMenu, NiceMenuClickEvent yourClickFunction)
{
int numOldMenu = myMenu.Count;
foreach (MenuItem myMenuItem in myMenu)
{
NiceMenu newMainMenu = new NiceMenu(myMenuItem.Text);
parentMenu.MenuItems.Add(newMainMenu);
if (myModifyNiceMenu[contModify] == null)
{
myModifyNiceMenu[contModify] = newMainMenu;
contModify ++;
}
if (myMenuItem.IsParent == true)
{
IList mySubMenu = new Menu.MenuItemCollection(myMenuItem);
BuildMenuTree(mySubMenu, newMainMenu, yourClickFunction);
}
}
// Now I have to delete the old menus
for (int i=0;i
2)
{
IndexImage = myMenuItem.Text.Substring(0,2);
if (Char.IsNumber(IndexImage,1) == true)
{
AddMenuImage = true;
// I have to delete first two characters
myMenuItem.Text = myMenuItem.Text.Substring(2);
}
}
if (AddMenuImage == true)
newMainMenu = new NiceMenu(myMenuItem.Text, new EventHandler(yourClickFunction), myMenuItem.Shortcut, MenuImages.Images[Convert.ToInt32(IndexImage)]);
else
newMainMenu = new NiceMenu(myMenuItem.Text, new EventHandler(yourClickFunction), myMenuItem.Shortcut);
parentMenu.MenuItems.Add(newMainMenu);
if (myModifyContextNiceMenu[contModifyContext] == null)
{
myModifyContextNiceMenu[contModifyContext] = newMainMenu;
contModifyContext ++;
}
if (myMenuItem.IsParent == true)
{
IList mySubMenu = new Menu.MenuItemCollection(myMenuItem);
BuildMenuTree(mySubMenu, newMainMenu, yourClickFunction);
}
}
// Now I have to delete the old menus
for (int i=0;i