1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
23 // Peter Bartok pbartok@novell.com
32 namespace System.Windows.Forms {
33 public sealed class NotifyIcon : System.ComponentModel.Component {
34 #region Local Variables
35 private ContextMenu context_menu;
37 private Bitmap icon_bitmap;
40 private NotifyIconWindow window;
41 private bool systray_active;
42 private ToolTip tooltip;
43 #endregion // Local Variables
45 #region NotifyIconWindow Class
46 internal class NotifyIconWindow : Control {
50 public NotifyIconWindow(NotifyIcon owner) {
53 rect = new Rectangle(0, 0, 1, 1);
57 Paint += new PaintEventHandler(HandlePaint);
58 SizeChanged += new EventHandler(HandleSizeChanged);
60 // Events that need to be sent to our parent
61 Click += new EventHandler(HandleClick);
62 DoubleClick += new EventHandler(HandleDoubleClick);
63 MouseDown +=new MouseEventHandler(HandleMouseDown);
64 MouseUp +=new MouseEventHandler(HandleMouseUp);
65 MouseMove +=new MouseEventHandler(HandleMouseMove);
66 ContextMenu = owner.context_menu;
69 protected override CreateParams CreateParams {
\r
73 cp = base.CreateParams;
\r
75 cp.Parent = IntPtr.Zero;
\r
76 cp.Style = (int)WindowStyles.WS_POPUP;
\r
77 cp.Style |= (int)WindowStyles.WS_CLIPSIBLINGS;
\r
79 cp.ExStyle = (int)(WindowStyles.WS_EX_TOOLWINDOW);
85 protected override void WndProc(ref Message m) {
\r
86 switch((Msg)m.Msg) {
\r
88 switch ((Msg)m.LParam.ToInt32()) {
\r
89 case Msg.WM_LBUTTONDOWN: {
\r
90 HandleMouseDown(this, new MouseEventArgs(MouseButtons.Left, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
\r
94 case Msg.WM_LBUTTONUP: {
\r
95 HandleMouseUp(this, new MouseEventArgs(MouseButtons.Left, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
\r
96 HandleClick(this, EventArgs.Empty);
\r
100 case Msg.WM_LBUTTONDBLCLK: {
\r
101 HandleDoubleClick(this, EventArgs.Empty);
\r
105 case Msg.WM_MOUSEMOVE: {
\r
106 HandleMouseMove(this, new MouseEventArgs(MouseButtons.None, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
\r
110 case Msg.WM_RBUTTONDOWN: {
\r
111 HandleMouseDown(this, new MouseEventArgs(MouseButtons.Right, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
\r
115 case Msg.WM_RBUTTONUP: {
\r
116 HandleMouseUp(this, new MouseEventArgs(MouseButtons.Right, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
\r
117 HandleClick(this, EventArgs.Empty);
\r
121 case Msg.WM_RBUTTONDBLCLK: {
\r
122 HandleDoubleClick(this, EventArgs.Empty);
\r
129 base.WndProc (ref m);
\r
132 internal void CalculateIconRect() {
\r
133 if (owner != null && owner.icon != null) {
\r
138 Console.WriteLine("CalculateIconRect: Width:{0}, Height:{1}", Width, Height);
\r
140 // Icons are always square. Try to center them in the window
\r
141 if (ClientRectangle.Width < ClientRectangle.Height) {
\r
142 size = ClientRectangle.Width;
\r
144 size = ClientRectangle.Height;
\r
146 x = this.ClientRectangle.Width / 2 - size / 2;
\r
147 y = this.ClientRectangle.Height / 2 - size / 2;
\r
148 rect = new Rectangle(x, y, size, size);
\r
150 // Force our window to be square
\r
152 this.Height = size;
\r
156 private void HandlePaint(object sender, PaintEventArgs e) {
\r
157 if (owner.icon != null) {
\r
158 e.Graphics.DrawImage(owner.icon_bitmap, rect);
\r
163 private void HandleSizeChanged(object sender, EventArgs e) {
\r
164 CalculateIconRect();
\r
167 private void HandleClick(object sender, EventArgs e) {
\r
168 if (owner.Click != null) {
\r
169 owner.Click(owner, e);
\r
173 private void HandleDoubleClick(object sender, EventArgs e) {
\r
174 if (owner.DoubleClick != null) {
\r
175 owner.DoubleClick(owner, e);
\r
179 private void HandleMouseDown(object sender, MouseEventArgs e) {
\r
180 if (owner.MouseDown != null) {
\r
181 owner.MouseDown(owner, e);
\r
185 private void HandleMouseUp(object sender, MouseEventArgs e) {
\r
186 if (owner.context_menu != null) {
\r
187 owner.context_menu.Show(this, new Point(e.X, e.Y));
\r
190 if (owner.MouseUp != null) {
\r
191 owner.MouseUp(owner, e);
\r
195 private void HandleMouseMove(object sender, MouseEventArgs e) {
\r
196 if (owner.MouseMove != null) {
\r
197 owner.MouseMove(owner, e);
\r
201 #endregion // NotifyIconWindow Class
203 #region Public Constructors
204 public NotifyIcon() {
205 window = new NotifyIconWindow(this);
206 systray_active = false;
209 public NotifyIcon(System.ComponentModel.IContainer container) : this() {
211 #endregion // Public Constructors
213 #region Private Methods
214 private void ShowSystray(bool property_changed) {
215 if (property_changed) {
216 window.CalculateIconRect();
219 if (systray_active) {
220 if (property_changed) {
227 icon_bitmap = icon.ToBitmap();
230 systray_active = true;
231 XplatUI.SystrayAdd(window.Handle, text, icon, out tooltip);
234 private void HideSystray() {
235 if (!systray_active) {
239 systray_active = false;
240 XplatUI.SystrayRemove(window.Handle, ref tooltip);
243 private void UpdateSystray() {
244 if (icon_bitmap != null) {
245 icon_bitmap.Dispose();
249 icon_bitmap = icon.ToBitmap();
252 XplatUI.SystrayChange(window.Handle, text, icon, ref tooltip);
255 #endregion // Private Methods
257 #region Public Instance Properties
258 public ContextMenu ContextMenu {
264 if (context_menu != value) {
265 context_menu = value;
266 window.ContextMenu = value;
294 if (value.Length >= 64) {
295 throw new ArgumentException("ToolTip length must be less than 64 characters long", "Text");
298 if (text == string.Empty && icon == null) {
307 public bool Visible {
313 if (visible != value) {
316 // Let our control know, too
317 window.is_visible = value;
327 #endregion // Public Instance Properties
329 #region Protected Instance Methods
330 protected override void Dispose(bool disposing) {
\r
331 if (icon != null) {
\r
335 if (icon_bitmap != null) {
\r
336 icon_bitmap.Dispose();
\r
338 base.Dispose (disposing);
\r
341 #endregion // Protected Instance Methods
344 public event EventHandler Click;
345 public event EventHandler DoubleClick;
346 public event MouseEventHandler MouseDown;
347 public event MouseEventHandler MouseMove;
348 public event MouseEventHandler MouseUp;