1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Server/NotifyIconAdv.cs Sun Jan 18 18:11:32 2015 +0100
1.3 @@ -0,0 +1,969 @@
1.4 +/*
1.5 +
1.6 + This Source Code Form is subject to the terms of the Mozilla Public
1.7 + License, v. 2.0. If a copy of the MPL was not distributed with this
1.8 + file, You can obtain one at http://mozilla.org/MPL/2.0/.
1.9 +
1.10 + Copyright (C) 2012 Michael Möller <mmoeller@openhardwaremonitor.org>
1.11 +
1.12 +*/
1.13 +
1.14 +using System;
1.15 +using System.ComponentModel;
1.16 +using System.Drawing;
1.17 +using System.Reflection;
1.18 +using System.Runtime.InteropServices;
1.19 +using System.Windows.Forms;
1.20 +
1.21 +namespace SharpDisplayManager
1.22 +{
1.23 + public class NotifyIconAdv : IDisposable
1.24 + {
1.25 + private NotifyIcon genericNotifyIcon;
1.26 + private NotifyIconWindowsImplementation windowsNotifyIcon;
1.27 +
1.28 + public NotifyIconAdv()
1.29 + {
1.30 + int p = (int)Environment.OSVersion.Platform;
1.31 + if ((p == 4) || (p == 128))
1.32 + { // Unix
1.33 + genericNotifyIcon = new NotifyIcon();
1.34 + }
1.35 + else
1.36 + { // Windows
1.37 + windowsNotifyIcon = new NotifyIconWindowsImplementation();
1.38 + }
1.39 + }
1.40 +
1.41 + public event EventHandler BalloonTipClicked
1.42 + {
1.43 + add
1.44 + {
1.45 + if (genericNotifyIcon != null)
1.46 + genericNotifyIcon.BalloonTipClicked += value;
1.47 + else
1.48 + windowsNotifyIcon.BalloonTipClicked += value;
1.49 + }
1.50 + remove
1.51 + {
1.52 + if (genericNotifyIcon != null)
1.53 + genericNotifyIcon.BalloonTipClicked -= value;
1.54 + else
1.55 + windowsNotifyIcon.BalloonTipClicked -= value;
1.56 + }
1.57 + }
1.58 +
1.59 + public event EventHandler BalloonTipClosed
1.60 + {
1.61 + add
1.62 + {
1.63 + if (genericNotifyIcon != null)
1.64 + genericNotifyIcon.BalloonTipClosed += value;
1.65 + else
1.66 + windowsNotifyIcon.BalloonTipClosed += value;
1.67 + }
1.68 + remove
1.69 + {
1.70 + if (genericNotifyIcon != null)
1.71 + genericNotifyIcon.BalloonTipClosed -= value;
1.72 + else
1.73 + windowsNotifyIcon.BalloonTipClosed -= value;
1.74 + }
1.75 + }
1.76 +
1.77 + public event EventHandler BalloonTipShown
1.78 + {
1.79 + add
1.80 + {
1.81 + if (genericNotifyIcon != null)
1.82 + genericNotifyIcon.BalloonTipShown += value;
1.83 + else
1.84 + windowsNotifyIcon.BalloonTipShown += value;
1.85 + }
1.86 + remove
1.87 + {
1.88 + if (genericNotifyIcon != null)
1.89 + genericNotifyIcon.BalloonTipShown -= value;
1.90 + else
1.91 + windowsNotifyIcon.BalloonTipShown -= value;
1.92 + }
1.93 + }
1.94 +
1.95 + public event EventHandler Click
1.96 + {
1.97 + add
1.98 + {
1.99 + if (genericNotifyIcon != null)
1.100 + genericNotifyIcon.Click += value;
1.101 + else
1.102 + windowsNotifyIcon.Click += value;
1.103 + }
1.104 + remove
1.105 + {
1.106 + if (genericNotifyIcon != null)
1.107 + genericNotifyIcon.Click -= value;
1.108 + else
1.109 + windowsNotifyIcon.Click -= value;
1.110 + }
1.111 + }
1.112 +
1.113 + public event EventHandler DoubleClick
1.114 + {
1.115 + add
1.116 + {
1.117 + if (genericNotifyIcon != null)
1.118 + genericNotifyIcon.DoubleClick += value;
1.119 + else
1.120 + windowsNotifyIcon.DoubleClick += value;
1.121 + }
1.122 + remove
1.123 + {
1.124 + if (genericNotifyIcon != null)
1.125 + genericNotifyIcon.DoubleClick -= value;
1.126 + else
1.127 + windowsNotifyIcon.DoubleClick -= value;
1.128 + }
1.129 + }
1.130 +
1.131 + public event MouseEventHandler MouseClick
1.132 + {
1.133 + add
1.134 + {
1.135 + if (genericNotifyIcon != null)
1.136 + genericNotifyIcon.MouseClick += value;
1.137 + else
1.138 + windowsNotifyIcon.MouseClick += value;
1.139 + }
1.140 + remove
1.141 + {
1.142 + if (genericNotifyIcon != null)
1.143 + genericNotifyIcon.MouseClick -= value;
1.144 + else
1.145 + windowsNotifyIcon.MouseClick -= value;
1.146 + }
1.147 + }
1.148 +
1.149 + public event MouseEventHandler MouseDoubleClick
1.150 + {
1.151 + add
1.152 + {
1.153 + if (genericNotifyIcon != null)
1.154 + genericNotifyIcon.MouseDoubleClick += value;
1.155 + else
1.156 + windowsNotifyIcon.MouseDoubleClick += value;
1.157 + }
1.158 + remove
1.159 + {
1.160 + if (genericNotifyIcon != null)
1.161 + genericNotifyIcon.MouseDoubleClick -= value;
1.162 + else
1.163 + windowsNotifyIcon.MouseDoubleClick -= value;
1.164 + }
1.165 + }
1.166 +
1.167 + public event MouseEventHandler MouseDown
1.168 + {
1.169 + add
1.170 + {
1.171 + if (genericNotifyIcon != null)
1.172 + genericNotifyIcon.MouseDown += value;
1.173 + else
1.174 + windowsNotifyIcon.MouseDown += value;
1.175 + }
1.176 + remove
1.177 + {
1.178 + if (genericNotifyIcon != null)
1.179 + genericNotifyIcon.MouseDown -= value;
1.180 + else
1.181 + windowsNotifyIcon.MouseDown -= value;
1.182 + }
1.183 + }
1.184 +
1.185 + public event MouseEventHandler MouseMove
1.186 + {
1.187 + add
1.188 + {
1.189 + if (genericNotifyIcon != null)
1.190 + genericNotifyIcon.MouseMove += value;
1.191 + else
1.192 + windowsNotifyIcon.MouseMove += value;
1.193 + }
1.194 + remove
1.195 + {
1.196 + if (genericNotifyIcon != null)
1.197 + genericNotifyIcon.MouseMove -= value;
1.198 + else
1.199 + windowsNotifyIcon.MouseMove -= value;
1.200 + }
1.201 + }
1.202 +
1.203 + public event MouseEventHandler MouseUp
1.204 + {
1.205 + add
1.206 + {
1.207 + if (genericNotifyIcon != null)
1.208 + genericNotifyIcon.MouseUp += value;
1.209 + else
1.210 + windowsNotifyIcon.MouseUp += value;
1.211 + }
1.212 + remove
1.213 + {
1.214 + if (genericNotifyIcon != null)
1.215 + genericNotifyIcon.MouseUp -= value;
1.216 + else
1.217 + windowsNotifyIcon.MouseUp -= value;
1.218 + }
1.219 + }
1.220 +
1.221 + public string BalloonTipText
1.222 + {
1.223 + get
1.224 + {
1.225 + if (genericNotifyIcon != null)
1.226 + return genericNotifyIcon.BalloonTipText;
1.227 + else
1.228 + return windowsNotifyIcon.BalloonTipText;
1.229 + }
1.230 + set
1.231 + {
1.232 + if (genericNotifyIcon != null)
1.233 + genericNotifyIcon.BalloonTipText = value;
1.234 + else
1.235 + windowsNotifyIcon.BalloonTipText = value;
1.236 + }
1.237 + }
1.238 +
1.239 + public ToolTipIcon BalloonTipIcon
1.240 + {
1.241 + get
1.242 + {
1.243 + if (genericNotifyIcon != null)
1.244 + return genericNotifyIcon.BalloonTipIcon;
1.245 + else
1.246 + return windowsNotifyIcon.BalloonTipIcon;
1.247 + }
1.248 + set
1.249 + {
1.250 + if (genericNotifyIcon != null)
1.251 + genericNotifyIcon.BalloonTipIcon = value;
1.252 + else
1.253 + windowsNotifyIcon.BalloonTipIcon = value;
1.254 + }
1.255 + }
1.256 +
1.257 + public string BalloonTipTitle
1.258 + {
1.259 + get
1.260 + {
1.261 + if (genericNotifyIcon != null)
1.262 + return genericNotifyIcon.BalloonTipTitle;
1.263 + else
1.264 + return windowsNotifyIcon.BalloonTipTitle;
1.265 + }
1.266 + set
1.267 + {
1.268 + if (genericNotifyIcon != null)
1.269 + genericNotifyIcon.BalloonTipTitle = value;
1.270 + else
1.271 + windowsNotifyIcon.BalloonTipTitle = value;
1.272 + }
1.273 + }
1.274 +
1.275 + public ContextMenu ContextMenu
1.276 + {
1.277 + get
1.278 + {
1.279 + if (genericNotifyIcon != null)
1.280 + return genericNotifyIcon.ContextMenu;
1.281 + else
1.282 + return windowsNotifyIcon.ContextMenu;
1.283 + }
1.284 + set
1.285 + {
1.286 + if (genericNotifyIcon != null)
1.287 + genericNotifyIcon.ContextMenu = value;
1.288 + else
1.289 + windowsNotifyIcon.ContextMenu = value;
1.290 + }
1.291 + }
1.292 +
1.293 + public ContextMenuStrip ContextMenuStrip
1.294 + {
1.295 + get
1.296 + {
1.297 + if (genericNotifyIcon != null)
1.298 + return genericNotifyIcon.ContextMenuStrip;
1.299 + else
1.300 + return windowsNotifyIcon.ContextMenuStrip;
1.301 + }
1.302 + set
1.303 + {
1.304 + if (genericNotifyIcon != null)
1.305 + genericNotifyIcon.ContextMenuStrip = value;
1.306 + else
1.307 + windowsNotifyIcon.ContextMenuStrip = value;
1.308 + }
1.309 + }
1.310 +
1.311 + public object Tag { get; set; }
1.312 +
1.313 + public Icon Icon
1.314 + {
1.315 + get
1.316 + {
1.317 + if (genericNotifyIcon != null)
1.318 + return genericNotifyIcon.Icon;
1.319 + else
1.320 + return windowsNotifyIcon.Icon;
1.321 + }
1.322 + set
1.323 + {
1.324 + if (genericNotifyIcon != null)
1.325 + genericNotifyIcon.Icon = value;
1.326 + else
1.327 + windowsNotifyIcon.Icon = value;
1.328 + }
1.329 + }
1.330 +
1.331 + public string Text
1.332 + {
1.333 + get
1.334 + {
1.335 + if (genericNotifyIcon != null)
1.336 + return genericNotifyIcon.Text;
1.337 + else
1.338 + return windowsNotifyIcon.Text;
1.339 + }
1.340 + set
1.341 + {
1.342 + if (genericNotifyIcon != null)
1.343 + genericNotifyIcon.Text = value;
1.344 + else
1.345 + windowsNotifyIcon.Text = value;
1.346 + }
1.347 + }
1.348 +
1.349 + public bool Visible
1.350 + {
1.351 + get
1.352 + {
1.353 + if (genericNotifyIcon != null)
1.354 + return genericNotifyIcon.Visible;
1.355 + else
1.356 + return windowsNotifyIcon.Visible;
1.357 + }
1.358 + set
1.359 + {
1.360 + if (genericNotifyIcon != null)
1.361 + genericNotifyIcon.Visible = value;
1.362 + else
1.363 + windowsNotifyIcon.Visible = value;
1.364 + }
1.365 + }
1.366 +
1.367 + public void Dispose()
1.368 + {
1.369 + if (genericNotifyIcon != null)
1.370 + genericNotifyIcon.Dispose();
1.371 + else
1.372 + windowsNotifyIcon.Dispose();
1.373 + }
1.374 +
1.375 + public void ShowBalloonTip(int timeout)
1.376 + {
1.377 + ShowBalloonTip(timeout, BalloonTipTitle, BalloonTipText, BalloonTipIcon);
1.378 + }
1.379 +
1.380 + public void ShowBalloonTip(int timeout, string tipTitle, string tipText,
1.381 + ToolTipIcon tipIcon)
1.382 + {
1.383 + if (genericNotifyIcon != null)
1.384 + genericNotifyIcon.ShowBalloonTip(timeout, tipTitle, tipText, tipIcon);
1.385 + else
1.386 + windowsNotifyIcon.ShowBalloonTip(timeout, tipTitle, tipText, tipIcon);
1.387 + }
1.388 +
1.389 + private class NotifyIconWindowsImplementation : Component
1.390 + {
1.391 + private static int nextId = 0;
1.392 +
1.393 + private object syncObj = new object();
1.394 + private Icon icon;
1.395 + private string text = "";
1.396 + private int id;
1.397 + private bool created;
1.398 + private NotifyIconNativeWindow window;
1.399 + private bool doubleClickDown;
1.400 + private bool visible;
1.401 + private MethodInfo commandDispatch;
1.402 +
1.403 + public event EventHandler BalloonTipClicked;
1.404 +
1.405 + public event EventHandler BalloonTipClosed;
1.406 +
1.407 + public event EventHandler BalloonTipShown;
1.408 +
1.409 + public event EventHandler Click;
1.410 +
1.411 + public event EventHandler DoubleClick;
1.412 +
1.413 + public event MouseEventHandler MouseClick;
1.414 +
1.415 + public event MouseEventHandler MouseDoubleClick;
1.416 +
1.417 + public event MouseEventHandler MouseDown;
1.418 +
1.419 + public event MouseEventHandler MouseMove;
1.420 +
1.421 + public event MouseEventHandler MouseUp;
1.422 +
1.423 + public string BalloonTipText { get; set; }
1.424 +
1.425 + public ToolTipIcon BalloonTipIcon { get; set; }
1.426 +
1.427 + public string BalloonTipTitle { get; set; }
1.428 +
1.429 + public ContextMenu ContextMenu { get; set; }
1.430 +
1.431 + public ContextMenuStrip ContextMenuStrip { get; set; }
1.432 +
1.433 + public object Tag { get; set; }
1.434 +
1.435 + public Icon Icon
1.436 + {
1.437 + get
1.438 + {
1.439 + return icon;
1.440 + }
1.441 + set
1.442 + {
1.443 + if (icon != value)
1.444 + {
1.445 + icon = value;
1.446 + UpdateNotifyIcon(visible);
1.447 + }
1.448 + }
1.449 + }
1.450 +
1.451 + public string Text
1.452 + {
1.453 + get
1.454 + {
1.455 + return text;
1.456 + }
1.457 + set
1.458 + {
1.459 + if (value == null)
1.460 + value = "";
1.461 +
1.462 + if (value.Length > 63)
1.463 + throw new ArgumentOutOfRangeException();
1.464 +
1.465 + if (!value.Equals(text))
1.466 + {
1.467 + text = value;
1.468 +
1.469 + if (visible)
1.470 + UpdateNotifyIcon(visible);
1.471 + }
1.472 + }
1.473 + }
1.474 +
1.475 + public bool Visible
1.476 + {
1.477 + get
1.478 + {
1.479 + return visible;
1.480 + }
1.481 + set
1.482 + {
1.483 + if (visible != value)
1.484 + {
1.485 + visible = value;
1.486 + UpdateNotifyIcon(visible);
1.487 + }
1.488 + }
1.489 + }
1.490 +
1.491 + public NotifyIconWindowsImplementation()
1.492 + {
1.493 + BalloonTipText = "";
1.494 + BalloonTipTitle = "";
1.495 +
1.496 + commandDispatch = typeof(Form).Assembly.
1.497 + GetType("System.Windows.Forms.Command").GetMethod("DispatchID",
1.498 + BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public,
1.499 + null, new Type[] { typeof(int) }, null);
1.500 +
1.501 + id = ++NotifyIconWindowsImplementation.nextId;
1.502 + window = new NotifyIconNativeWindow(this);
1.503 + UpdateNotifyIcon(visible);
1.504 + }
1.505 +
1.506 + protected override void Dispose(bool disposing)
1.507 + {
1.508 + if (disposing)
1.509 + {
1.510 + if (window != null)
1.511 + {
1.512 + icon = null;
1.513 + text = "";
1.514 + UpdateNotifyIcon(false);
1.515 + window.DestroyHandle();
1.516 + window = null;
1.517 + ContextMenu = null;
1.518 + ContextMenuStrip = null;
1.519 + }
1.520 + }
1.521 + else
1.522 + {
1.523 + if (window != null && window.Handle != IntPtr.Zero)
1.524 + {
1.525 + NativeMethods.PostMessage(
1.526 + new HandleRef(window, window.Handle), WM_CLOSE, 0, 0);
1.527 + window.ReleaseHandle();
1.528 + }
1.529 + }
1.530 + base.Dispose(disposing);
1.531 + }
1.532 +
1.533 + public void ShowBalloonTip(int timeout)
1.534 + {
1.535 + ShowBalloonTip(timeout, BalloonTipTitle, BalloonTipText, BalloonTipIcon);
1.536 + }
1.537 +
1.538 + public void ShowBalloonTip(int timeout, string tipTitle, string tipText,
1.539 + ToolTipIcon tipIcon)
1.540 + {
1.541 + if (timeout < 0)
1.542 + throw new ArgumentOutOfRangeException("timeout");
1.543 +
1.544 + if (string.IsNullOrEmpty(tipText))
1.545 + throw new ArgumentException("tipText");
1.546 +
1.547 + if (DesignMode)
1.548 + return;
1.549 +
1.550 + if (created)
1.551 + {
1.552 + NativeMethods.NotifyIconData data = new NativeMethods.NotifyIconData();
1.553 + if (window.Handle == IntPtr.Zero)
1.554 + window.CreateHandle(new CreateParams());
1.555 +
1.556 + data.Window = window.Handle;
1.557 + data.ID = id;
1.558 + data.Flags = NativeMethods.NotifyIconDataFlags.Info;
1.559 + data.TimeoutOrVersion = timeout;
1.560 + data.InfoTitle = tipTitle;
1.561 + data.Info = tipText;
1.562 + data.InfoFlags = (int)tipIcon;
1.563 +
1.564 + NativeMethods.Shell_NotifyIcon(
1.565 + NativeMethods.NotifyIconMessage.Modify, data);
1.566 + }
1.567 + }
1.568 +
1.569 + private void ShowContextMenu()
1.570 + {
1.571 + if (ContextMenu == null && ContextMenuStrip == null)
1.572 + return;
1.573 +
1.574 + NativeMethods.Point p = new NativeMethods.Point();
1.575 + NativeMethods.GetCursorPos(ref p);
1.576 + NativeMethods.SetForegroundWindow(
1.577 + new HandleRef(window, window.Handle));
1.578 +
1.579 + if (ContextMenu != null)
1.580 + {
1.581 + ContextMenu.GetType().InvokeMember("OnPopup",
1.582 + BindingFlags.NonPublic | BindingFlags.InvokeMethod |
1.583 + BindingFlags.Instance, null, ContextMenu,
1.584 + new Object[] { System.EventArgs.Empty });
1.585 +
1.586 + NativeMethods.TrackPopupMenuEx(
1.587 + new HandleRef(ContextMenu, ContextMenu.Handle), 72,
1.588 + p.x, p.y, new HandleRef(window, window.Handle),
1.589 + IntPtr.Zero);
1.590 +
1.591 + NativeMethods.PostMessage(
1.592 + new HandleRef(window, window.Handle), WM_NULL, 0, 0);
1.593 + return;
1.594 + }
1.595 +
1.596 + if (ContextMenuStrip != null)
1.597 + ContextMenuStrip.GetType().InvokeMember("ShowInTaskbar",
1.598 + BindingFlags.NonPublic | BindingFlags.InvokeMethod |
1.599 + BindingFlags.Instance, null, ContextMenuStrip,
1.600 + new Object[] { p.x, p.y });
1.601 + }
1.602 +
1.603 + private void UpdateNotifyIcon(bool showNotifyIcon)
1.604 + {
1.605 + if (DesignMode)
1.606 + return;
1.607 +
1.608 + lock (syncObj)
1.609 + {
1.610 + window.LockReference(showNotifyIcon);
1.611 +
1.612 + NativeMethods.NotifyIconData data = new NativeMethods.NotifyIconData();
1.613 + data.CallbackMessage = WM_TRAYMOUSEMESSAGE;
1.614 + data.Flags = NativeMethods.NotifyIconDataFlags.Message;
1.615 +
1.616 + if (showNotifyIcon && window.Handle == IntPtr.Zero)
1.617 + window.CreateHandle(new CreateParams());
1.618 +
1.619 + data.Window = window.Handle;
1.620 + data.ID = id;
1.621 +
1.622 + if (icon != null)
1.623 + {
1.624 + data.Flags |= NativeMethods.NotifyIconDataFlags.Icon;
1.625 + data.Icon = icon.Handle;
1.626 + }
1.627 +
1.628 + data.Flags |= NativeMethods.NotifyIconDataFlags.Tip;
1.629 + data.Tip = text;
1.630 +
1.631 + if (showNotifyIcon && icon != null)
1.632 + {
1.633 + if (!created)
1.634 + {
1.635 + int i = 0;
1.636 + do
1.637 + {
1.638 + created = NativeMethods.Shell_NotifyIcon(
1.639 + NativeMethods.NotifyIconMessage.Add, data);
1.640 + if (!created)
1.641 + {
1.642 + System.Threading.Thread.Sleep(200);
1.643 + i++;
1.644 + }
1.645 + } while (!created && i < 40);
1.646 + }
1.647 + else
1.648 + {
1.649 + NativeMethods.Shell_NotifyIcon(
1.650 + NativeMethods.NotifyIconMessage.Modify, data);
1.651 + }
1.652 + }
1.653 + else
1.654 + {
1.655 + if (created)
1.656 + {
1.657 + int i = 0;
1.658 + bool deleted = false;
1.659 + do
1.660 + {
1.661 + deleted = NativeMethods.Shell_NotifyIcon(
1.662 + NativeMethods.NotifyIconMessage.Delete, data);
1.663 + if (!deleted)
1.664 + {
1.665 + System.Threading.Thread.Sleep(200);
1.666 + i++;
1.667 + }
1.668 + } while (!deleted && i < 40);
1.669 + created = false;
1.670 + }
1.671 + }
1.672 + }
1.673 + }
1.674 +
1.675 + private void ProcessMouseDown(ref Message message, MouseButtons button,
1.676 + bool doubleClick)
1.677 + {
1.678 + if (doubleClick)
1.679 + {
1.680 + if (DoubleClick != null)
1.681 + DoubleClick(this, new MouseEventArgs(button, 2, 0, 0, 0));
1.682 +
1.683 + if (MouseDoubleClick != null)
1.684 + MouseDoubleClick(this, new MouseEventArgs(button, 2, 0, 0, 0));
1.685 +
1.686 + doubleClickDown = true;
1.687 + }
1.688 +
1.689 + if (MouseDown != null)
1.690 + MouseDown(this,
1.691 + new MouseEventArgs(button, doubleClick ? 2 : 1, 0, 0, 0));
1.692 + }
1.693 +
1.694 + private void ProcessMouseUp(ref Message message, MouseButtons button)
1.695 + {
1.696 + if (MouseUp != null)
1.697 + MouseUp(this, new MouseEventArgs(button, 0, 0, 0, 0));
1.698 +
1.699 + if (!doubleClickDown)
1.700 + {
1.701 + if (Click != null)
1.702 + Click(this, new MouseEventArgs(button, 0, 0, 0, 0));
1.703 +
1.704 + if (MouseClick != null)
1.705 + MouseClick(this, new MouseEventArgs(button, 0, 0, 0, 0));
1.706 + }
1.707 + doubleClickDown = false;
1.708 + }
1.709 +
1.710 + private void ProcessInitMenuPopup(ref Message message)
1.711 + {
1.712 + if (ContextMenu != null &&
1.713 + (bool)ContextMenu.GetType().InvokeMember("ProcessInitMenuPopup",
1.714 + BindingFlags.NonPublic | BindingFlags.InvokeMethod |
1.715 + BindingFlags.Instance, null, ContextMenu,
1.716 + new Object[] { message.WParam }))
1.717 + {
1.718 + return;
1.719 + }
1.720 + window.DefWndProc(ref message);
1.721 + }
1.722 +
1.723 + private void WndProc(ref Message message)
1.724 + {
1.725 + switch (message.Msg)
1.726 + {
1.727 + case WM_DESTROY:
1.728 + UpdateNotifyIcon(false);
1.729 + return;
1.730 +
1.731 + case WM_COMMAND:
1.732 + if (message.LParam != IntPtr.Zero)
1.733 + {
1.734 + window.DefWndProc(ref message);
1.735 + return;
1.736 + }
1.737 + commandDispatch.Invoke(null, new object[] {
1.738 + message.WParam.ToInt32() & 0xFFFF });
1.739 + return;
1.740 +
1.741 + case WM_INITMENUPOPUP:
1.742 + ProcessInitMenuPopup(ref message);
1.743 + return;
1.744 +
1.745 + case WM_TRAYMOUSEMESSAGE:
1.746 + switch ((int)message.LParam)
1.747 + {
1.748 + case WM_MOUSEMOVE:
1.749 + if (MouseMove != null)
1.750 + MouseMove(this,
1.751 + new MouseEventArgs(Control.MouseButtons, 0, 0, 0, 0));
1.752 + return;
1.753 +
1.754 + case WM_LBUTTONDOWN:
1.755 + ProcessMouseDown(ref message, MouseButtons.Left, false);
1.756 + return;
1.757 +
1.758 + case WM_LBUTTONUP:
1.759 + ProcessMouseUp(ref message, MouseButtons.Left);
1.760 + return;
1.761 +
1.762 + case WM_LBUTTONDBLCLK:
1.763 + ProcessMouseDown(ref message, MouseButtons.Left, true);
1.764 + return;
1.765 +
1.766 + case WM_RBUTTONDOWN:
1.767 + ProcessMouseDown(ref message, MouseButtons.Right, false);
1.768 + return;
1.769 +
1.770 + case WM_RBUTTONUP:
1.771 + if (ContextMenu != null || ContextMenuStrip != null)
1.772 + ShowContextMenu();
1.773 + ProcessMouseUp(ref message, MouseButtons.Right);
1.774 + return;
1.775 +
1.776 + case WM_RBUTTONDBLCLK:
1.777 + ProcessMouseDown(ref message, MouseButtons.Right, true);
1.778 + return;
1.779 +
1.780 + case WM_MBUTTONDOWN:
1.781 + ProcessMouseDown(ref message, MouseButtons.Middle, false);
1.782 + return;
1.783 +
1.784 + case WM_MBUTTONUP:
1.785 + ProcessMouseUp(ref message, MouseButtons.Middle);
1.786 + return;
1.787 +
1.788 + case WM_MBUTTONDBLCLK:
1.789 + ProcessMouseDown(ref message, MouseButtons.Middle, true);
1.790 + return;
1.791 +
1.792 + case NIN_BALLOONSHOW:
1.793 + if (BalloonTipShown != null)
1.794 + BalloonTipShown(this, EventArgs.Empty);
1.795 + return;
1.796 +
1.797 + case NIN_BALLOONHIDE:
1.798 + case NIN_BALLOONTIMEOUT:
1.799 + if (BalloonTipClosed != null)
1.800 + BalloonTipClosed(this, EventArgs.Empty);
1.801 + return;
1.802 +
1.803 + case NIN_BALLOONUSERCLICK:
1.804 + if (BalloonTipClicked != null)
1.805 + BalloonTipClicked(this, EventArgs.Empty);
1.806 + return;
1.807 +
1.808 + default:
1.809 + return;
1.810 + }
1.811 + }
1.812 +
1.813 + if (message.Msg == NotifyIconWindowsImplementation.WM_TASKBARCREATED)
1.814 + {
1.815 + lock (syncObj)
1.816 + {
1.817 + created = false;
1.818 + }
1.819 + UpdateNotifyIcon(visible);
1.820 + }
1.821 +
1.822 + window.DefWndProc(ref message);
1.823 + }
1.824 +
1.825 + private class NotifyIconNativeWindow : NativeWindow
1.826 + {
1.827 + private NotifyIconWindowsImplementation reference;
1.828 + private GCHandle referenceHandle;
1.829 +
1.830 + internal NotifyIconNativeWindow(NotifyIconWindowsImplementation component)
1.831 + {
1.832 + this.reference = component;
1.833 + }
1.834 +
1.835 + ~NotifyIconNativeWindow()
1.836 + {
1.837 + if (base.Handle != IntPtr.Zero)
1.838 + NativeMethods.PostMessage(
1.839 + new HandleRef(this, base.Handle), WM_CLOSE, 0, 0);
1.840 + }
1.841 +
1.842 + public void LockReference(bool locked)
1.843 + {
1.844 + if (locked)
1.845 + {
1.846 + if (!referenceHandle.IsAllocated)
1.847 + {
1.848 + referenceHandle = GCHandle.Alloc(reference, GCHandleType.Normal);
1.849 + return;
1.850 + }
1.851 + }
1.852 + else
1.853 + {
1.854 + if (referenceHandle.IsAllocated)
1.855 + referenceHandle.Free();
1.856 + }
1.857 + }
1.858 +
1.859 + protected override void OnThreadException(Exception e)
1.860 + {
1.861 + Application.OnThreadException(e);
1.862 + }
1.863 +
1.864 + protected override void WndProc(ref Message m)
1.865 + {
1.866 + reference.WndProc(ref m);
1.867 + }
1.868 + }
1.869 +
1.870 + private const int WM_NULL = 0x00;
1.871 + private const int WM_DESTROY = 0x02;
1.872 + private const int WM_CLOSE = 0x10;
1.873 + private const int WM_COMMAND = 0x111;
1.874 + private const int WM_INITMENUPOPUP = 0x117;
1.875 + private const int WM_MOUSEMOVE = 0x200;
1.876 + private const int WM_LBUTTONDOWN = 0x201;
1.877 + private const int WM_LBUTTONUP = 0x202;
1.878 + private const int WM_LBUTTONDBLCLK = 0x203;
1.879 + private const int WM_RBUTTONDOWN = 0x204;
1.880 + private const int WM_RBUTTONUP = 0x205;
1.881 + private const int WM_RBUTTONDBLCLK = 0x206;
1.882 + private const int WM_MBUTTONDOWN = 0x207;
1.883 + private const int WM_MBUTTONUP = 0x208;
1.884 + private const int WM_MBUTTONDBLCLK = 0x209;
1.885 + private const int WM_TRAYMOUSEMESSAGE = 0x800;
1.886 +
1.887 + private const int NIN_BALLOONSHOW = 0x402;
1.888 + private const int NIN_BALLOONHIDE = 0x403;
1.889 + private const int NIN_BALLOONTIMEOUT = 0x404;
1.890 + private const int NIN_BALLOONUSERCLICK = 0x405;
1.891 +
1.892 + private static int WM_TASKBARCREATED =
1.893 + NativeMethods.RegisterWindowMessage("TaskbarCreated");
1.894 +
1.895 + private static class NativeMethods
1.896 + {
1.897 + [DllImport("user32.dll", CharSet = CharSet.Auto)]
1.898 + public static extern IntPtr PostMessage(HandleRef hwnd, int msg,
1.899 + int wparam, int lparam);
1.900 +
1.901 + [DllImport("user32.dll", CharSet = CharSet.Auto)]
1.902 + public static extern int RegisterWindowMessage(string msg);
1.903 +
1.904 + [Flags]
1.905 + public enum NotifyIconDataFlags : int
1.906 + {
1.907 + Message = 0x1,
1.908 + Icon = 0x2,
1.909 + Tip = 0x4,
1.910 + State = 0x8,
1.911 + Info = 0x10
1.912 + }
1.913 +
1.914 + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
1.915 + public class NotifyIconData
1.916 + {
1.917 + private int Size = Marshal.SizeOf(typeof(NotifyIconData));
1.918 + public IntPtr Window;
1.919 + public int ID;
1.920 + public NotifyIconDataFlags Flags;
1.921 + public int CallbackMessage;
1.922 + public IntPtr Icon;
1.923 +
1.924 + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
1.925 + public string Tip;
1.926 +
1.927 + public int State;
1.928 + public int StateMask;
1.929 +
1.930 + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
1.931 + public string Info;
1.932 +
1.933 + public int TimeoutOrVersion;
1.934 +
1.935 + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
1.936 + public string InfoTitle;
1.937 +
1.938 + public int InfoFlags;
1.939 + }
1.940 +
1.941 + public enum NotifyIconMessage : int
1.942 + {
1.943 + Add = 0x0,
1.944 + Modify = 0x1,
1.945 + Delete = 0x2
1.946 + }
1.947 +
1.948 + [DllImport("shell32.dll", CharSet = CharSet.Auto)]
1.949 + [return: MarshalAs(UnmanagedType.Bool)]
1.950 + public static extern bool Shell_NotifyIcon(NotifyIconMessage message,
1.951 + NotifyIconData pnid);
1.952 +
1.953 + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
1.954 + public static extern bool TrackPopupMenuEx(HandleRef hmenu, int fuFlags,
1.955 + int x, int y, HandleRef hwnd, IntPtr tpm);
1.956 +
1.957 + [StructLayout(LayoutKind.Sequential)]
1.958 + public struct Point
1.959 + {
1.960 + public int x;
1.961 + public int y;
1.962 + }
1.963 +
1.964 + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
1.965 + public static extern bool GetCursorPos(ref Point point);
1.966 +
1.967 + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
1.968 + public static extern bool SetForegroundWindow(HandleRef hWnd);
1.969 + }
1.970 + }
1.971 + }
1.972 +}
1.973 \ No newline at end of file