Bonjour à tous,

Voir deuxième poste

Je viens vous présenter ici ma modeste contribution. Mon projet est relativement simple :
pouvoir creer facilement un menu dans la zone de notification.

Pour ce faire, j'ai écrit la classe suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
 
using System;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;
 
namespace NotificationMenu {
	public class SystemTrayMenu {
		// Fields
		private NotifyIcon _notifyIcon;
		private MenuStrip _strip;
		private ToolStripItemCollection _menus;
 
		public SystemTrayIcon () {
			this._notifyIcon = new NotifyIcon();
			this._strip = new MenuStrip();
			this._menus = new ToolStripItemCollection( _strip, new ToolStripItem[0] );
		}
 
		// Properties
		public Icon Icon {
			set { this._notifyIcon.Icon = value; }
		}
 
		public bool Visible {
			set { this._notifyIcon.Visible = value; }
		}
 
		public ToolStripItemCollection Menu {
			get { return this._menus; }
		}
 
		public ToolStripMenuItem this[string path] {
			get {
				string[] patterns = path.Split( '/' );
				ToolStripMenuItem menu = (ToolStripMenuItem)_menus[patterns[1]];
 
				for ( int i = 2 ; i < patterns.Length ; i++ )
					if ( patterns[i] != "" )
						try {
							menu = (ToolStripMenuItem)menu.DropDownItems[patterns[i]];
						} catch ( Exception ) {
							throw new Exception( "The menu '" + patterns[i] + "' doesn't exist" );
						}
 
				return menu;
			}
		}
 
		// Methods - public
		public void LoadMenuFromXml ( string path ) {
			XmlDocument xml = new XmlDocument();
 
			using ( FileStream stream = new FileStream( path, FileMode.Open, FileAccess.Read ) ) {
				xml.Load( stream );
			}
 
			LoadMenuFromXml( xml );
		}
 
		public void LoadMenuFromXml ( XmlDocument xml ) {
			ToolStripMenuItem root = new ToolStripMenuItem();
 
			foreach ( XmlNode node in xml.LastChild.ChildNodes )
				Node2ToolStripMenu( node, ref root );
 
			this._menus.AddRange( root.DropDownItems );
			this._strip.Items.AddRange( _menus );
			this._notifyIcon.ContextMenuStrip = this.BuildContextMenu();
		}
 
		public void ReloadContextMenu () {
			this._notifyIcon.ContextMenuStrip = this.BuildContextMenu();
		}
 
		// Methods - private
		private ContextMenuStrip BuildContextMenu () {
			ContextMenuStrip retour = new ContextMenuStrip();
			retour.Items.AddRange( this._menus );
			return retour;
		}
 
		private void Node2ToolStripMenu ( XmlNode node, ref ToolStripMenuItem parent ) {
			switch ( node.Name ) {
				case "menu":
					if ( node.HasChildNodes )
						if ( node.Attributes["text"] != null ) {
							ToolStripMenuItem actualMenu = NewMenuItem(
								node.Attributes["name"] != null ?
									node.Attributes["name"].Value :
									null,
								node.Attributes["text"].Value,
								node.Attributes["icon"] != null ?
									new Icon( node.Attributes["icon"].Value ).ToBitmap() :
									null
							);
 
							parent.DropDownItems.Add( actualMenu );
 
							foreach ( XmlNode child in node.ChildNodes )
								Node2ToolStripMenu( child, ref actualMenu );
						} else
							throw new Exception( "The attribute 'text' can't be missing" );
					else
						if ( node.Attributes["text"] != null )
							if ( node.Attributes["assembly"] != null && node.Attributes["type"] != null && node.Attributes["method"] != null )
								parent.DropDownItems.Add(
									AddEventHandler(
										NewMenuItem(
											node.Attributes["name"] != null ?
												node.Attributes["name"].Value :
												null,
											node.Attributes["text"].Value,
											node.Attributes["icon"] != null ?
												new Icon( node.Attributes["icon"].Value ).ToBitmap() :
												null
										),
										"Click",
										node.Attributes["assembly"].Value,
										node.Attributes["type"].Value,
										node.Attributes["method"].Value
									)
								);
							else
								parent.DropDownItems.Add(
									NewMenuItem(
										node.Attributes["name"] != null ?
											node.Attributes["name"].Value :
											null,
										node.Attributes["text"].Value,
										node.Attributes["icon"] != null ?
											new Icon( node.Attributes["icon"].Value ).ToBitmap() :
											null
									)
								);
						else
							throw new Exception( "The attribute 'text' can't be missing" );
 
					break;
				case "separator":
					parent.DropDownItems.Add( new ToolStripSeparator() );
					break;
				default:
					throw new Exception( "Incorrect tag. It must be : menu or separator." );
			}
 
		}
 
		private ToolStripMenuItem AddEventHandler ( ToolStripMenuItem menu, string eventType, string assembly, string type, string method ) {
			menu.GetType().GetEvent( eventType ).AddEventHandler(
				menu,
				Delegate.CreateDelegate(
					typeof( EventHandler ),
					Assembly.Load( assembly ).GetType( type ).GetMethod( method )
				)
			);
 
			return menu;
		}
 
		private ToolStripMenuItem NewMenuItem ( string text ) {
			return new ToolStripMenuItem( text );
		}
 
		private ToolStripMenuItem NewMenuItem ( string text, Image icon ) {
			return new ToolStripMenuItem( text, icon );
		}
 
		private ToolStripMenuItem NewMenuItem ( string text, ToolStripItem[] children ) {
			return new ToolStripMenuItem( text, null, children );
		}
 
		private ToolStripMenuItem NewMenuItem ( string text, Image icon, ToolStripItem[] children ) {
			return new ToolStripMenuItem( text, icon, children );
		}
 
		private ToolStripMenuItem NewMenuItem ( string name, string text ) {
			return new ToolStripMenuItem( text, null, null, name );
		}
 
		private ToolStripMenuItem NewMenuItem ( string name, string text, Image icon ) {
			return new ToolStripMenuItem( text, icon, null, name );
		}
 
		private ToolStripMenuItem NewMenuItem ( string name, string text, ToolStripItem[] children ) {
			ToolStripMenuItem menu = new ToolStripMenuItem( text, null, children );
			menu.Name = name;
 
			return menu;
		}
 
		private ToolStripMenuItem NewMenuItem ( string name, string text, Image icon, ToolStripItem[] children ) {
			ToolStripMenuItem menu = new ToolStripMenuItem( text, icon, children );
			menu.Name = name;
 
			return menu;
		}
	}
}
Pour ajouter des menus, il y a deux facons de le faire :
  • Par Xml :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    <?xml version="1.0" encoding="utf-8"?>
    <root>
      <menu text="text" >
        <menu text="text" />
        <menu text="text" icon="icon.ico" />
      </menu>
      <menu text="text" >
        <menu text="text" assembly="assembly" type="namespace+classe" method="method" />
        <menu text="text" icon="icon.ico" />
      </menu>
      <separator/>
      <menu text="text" >
        <menu text="text" />
        <menu text="text" >
          <menu text="text" icon="icon.ico" assembly="assembly" type="namespace+classe" method="method"/ >
          <separator/>
          <menu text="text" assembly="assembly" type="namespace+classe" method="method" />
        </menu>
      </menu>
    </root>
    Les méthodes appelés dans le fichier XML doivent avoir le prototype suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     public static void Method (object sender, EventArgs e);
  • Ou directement dans le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    SystemTrayIcon trayIcon = new SystemTrayIcon ();
    trayIcon.Menu.AddRange( new ToolStripItem[] {
    	new ToolStripMenuItem("menu1", new System.Drawing.Icon("icon.ico").ToBitmap(), new ToolStripItem[] {
    		new ToolStripMenuItem("menu11")
    	}),
    	new ToolStripMenuItem("menu2", null, new EventHandler(OnClick)),
    	new ToolStripMenuItem("menu3", new System.Drawing.Icon("icon.ico").ToBitmap())
    } );
     
    // A ne pas oublier pour prendre en compte les changements
    trayIcon.ReloadContextMenu();
     
    ToolStripMenuItem menu = trayIcon["/menu1/menu11"];


A rajouter :
  • Des propositions ?


Rajouter :
  • Possibilité de mettre des separateur avec la balise <separator/>
  • Passage de la classe de static à non static
  • Possibilité de modifier facilement les menu déjà creer par leur chemin ( ex: "/menu1/menu12" )


J'espere que ca vous sera utile.
Inarius