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