Ejemplo n.º 1
0
        public static void GetLocationPre7Prepare()
        {
            // Get a screenshot of the notification area...
            Rectangle _notifyAreaRect = NotifyArea.GetRectangle();
            Size      _notifyAreaSize = _notifyAreaRect.Size;

            using (Bitmap notifyAreaBitmap = GetNotifyAreaScreenshot())
            {
                // Something gone wrong? Give up.
                if (notifyAreaBitmap == null)
                {
                    return;
                }

                // Determine a good spot...
                if (_notifyAreaSize.Width > _notifyAreaSize.Height)
                {
                    s_nearColor = notifyAreaBitmap.GetPixel(_notifyAreaSize.Width - 3, _notifyAreaSize.Height / 2);
                }
                else
                {
                    s_nearColor = notifyAreaBitmap.GetPixel(_notifyAreaSize.Width / 2, _notifyAreaSize.Height - 3);
                }

                // And now we have our base colour!
                s_nearColorSet = true;
            }
        }
Ejemplo n.º 2
0
 public Point GetLocation(int accuracy)
 {
     if (OperatingSystem.GteWindows7)
     {
         return(NotifyArea.GetNotifyIconRectangle(NotifyIcon).Location);
     }
     else
     {
         return(GetLocationPre7(accuracy));
     }
 }
Ejemplo n.º 3
0
        private static Bitmap GetNotifyAreaScreenshot()
        {
            Rectangle _notifyAreaRect   = NotifyArea.GetRectangle();
            Bitmap    _notifyAreaBitmap = new Bitmap(_notifyAreaRect.Width, _notifyAreaRect.Height);

            using (Graphics _notifyAreaGraphics = Graphics.FromImage(_notifyAreaBitmap))
            {
                try
                {
                    _notifyAreaGraphics.CopyFromScreen(_notifyAreaRect.X, _notifyAreaRect.Y, 0, 0, _notifyAreaRect.Size);
                }
                catch (Win32Exception)
                {
                    return(null);
                }
            }

            return(_notifyAreaBitmap);
        }
Ejemplo n.º 4
0
        private void Init()
        {
            // Does the owner have an icon set?
            if (m_owner.NotifyIcon.Icon == null)
            {
                throw new InvalidOperationException(
                          "SuperNotifyIcon: Dropping cannot be initialised without an icon set!");
            }

            // When the mouse is close
            MouseHook.MouseMove += MouseHook_MouseMove;

            // Cancel the drop refreshing below if we do an actual click on the NotifyIcon
            m_owner.NotifyIcon.MouseUp += (sender, e) => { m_mouseWasInNotifyArea = false; };

            // Refresh the drop position if we click in the notification area on Windows 7; we might've moved an icon!
            if (OperatingSystem.GteWindows7)
            {
                MouseHook.MouseDown += (sender, e) =>
                {
                    m_mouseWasInNotifyArea = MouseInNotifyArea();

                    // Shall we cancel, then?
                    if (e.Button != MouseButtons.Left)
                    {
                        m_mouseWasInNotifyArea = false;
                    }
                };
                MouseHook.MouseUp += (sender, e) =>
                {
                    if (MouseInNotifyArea() && m_mouseWasInNotifyArea)
                    {
                        // We should wait for the icon to settle in before doing anything
                        Timer _wait = new Timer();
                        _wait.Tick += (sender2, e2) =>
                        {
                            if (m_mouseWasInNotifyArea)
                            {
                                ShowDrop();
                            }
                            m_mouseWasInNotifyArea = false;
                            _wait.Dispose();
                        };
                        _wait.Interval = 200;
                        _wait.Start();
                    }
                };
            }

            // Refresh the drop position if the size of the notification area changes
            Size  _notifyAreaLastSize = NotifyArea.GetRectangle().Size;
            Timer _notifyAreaTimer    = new Timer();

            _notifyAreaTimer.Tick += (sender, e) =>
            {
                if (NotifyArea.GetRectangle().Size != _notifyAreaLastSize)
                {
                    _notifyAreaLastSize = NotifyArea.GetRectangle().Size;
                    ShowDrop();
                }
            };
            _notifyAreaTimer.Interval = 1000;
            _notifyAreaTimer.Start();

            // Is the drop even in the right place at all?
            int   _unsuccessfulRefreshes = 0;
            Timer _dropPlaceTimer        = new Timer();

            _dropPlaceTimer.Tick += (sender, e) =>
            {
                if (!NotifyArea.GetRectangle().Contains(new Point(Location.X + 2, Location.Y + 2)))
                {
                    ShowDrop();
                    _unsuccessfulRefreshes++;

                    // Don't keep refreshing every second if we can't find our icon!
                    if (_unsuccessfulRefreshes >= 3)
                    {
                        _dropPlaceTimer.Interval = _unsuccessfulRefreshes * 1000;
                    }
                }
                else
                {
                    _unsuccessfulRefreshes   = 0;
                    _dropPlaceTimer.Interval = 1000;
                }
            };
            _dropPlaceTimer.Interval = 1000;
            _dropPlaceTimer.Start();

            // Okay... still no success? Let's fall back to the mouse timer...
            //// TODO_ See whether this should only be run on WinXP/Vista systems and whether this should
            //// run even if we have a valid drop position
            MouseHoldTimed _mouseHold = new MouseHoldTimed(500);

            _mouseHold.MouseDown += (sender, e) =>
            {
                if (e.Button != MouseButtons.Left || OwnApplicationActive() ||
                    m_lastNotifyIconPoint != new Point(-1, -1))
                {
                    _mouseHold.Cancel();
                }
            };
            _mouseHold.MouseHoldTimeout += (sender, e) =>
            {
                if (m_lastNotifyIconPoint == new Point(-1, -1))
                {
                    ShowDrop();
                }
            };
        }
Ejemplo n.º 5
0
 private static bool MouseInNotifyArea()
 {
     return(NotifyArea.GetRectangle().Contains(Cursor.Position));
 }
Ejemplo n.º 6
0
        public Point GetLocationPre7(int accuracy)
        {
            // Got something fullscreen running? Of course we can't find our icon!
            if (FullScreen.Detect())
            {
                return(new Point(-1, -1));
            }

            // The accuracy can't be below 0!
            if (accuracy < 0)
            {
                throw new ArgumentOutOfRangeException("accuracy", "The accuracy value provided can't be negative!");
            }

            // The notification area
            Rectangle _notifyAreaRect = NotifyArea.GetRectangle();

            // Invalid size? Don't bother doing anything.
            if (_notifyAreaRect.Width < 1 || _notifyAreaRect.Height < 1)
            {
                return(new Point(-1, -1));
            }

            // Back up the NotifyIcon's icon so we can reset it later on
            Icon _notifyIconIcon = NotifyIcon.Icon;

            // Have we got a colour we could base the find pixel off?
            if (!s_nearColorSet)
            {
                GetLocationPre7Prepare();
            }

            List <int> _colMatchIndexes = new List <int>();
            Point      _last            = new Point(-1, -1);
            int        _hits            = 0;
            int        _hitsMax         = accuracy + 1;

            // Our wonderful loop
            for (int _attempt = 0; _attempt < 5 && _hits < _hitsMax; _attempt++)
            {
                // Set the notify icon thingy to a random colour
                Random _random   = new Random();
                int    _rgbRange = 32;
                Color  _col;

                if (s_nearColorSet)
                {
                    _col = Color.FromArgb(
                        SafeColourVal(s_nearColor.R + _random.Next(_rgbRange) - 8),
                        SafeColourVal(s_nearColor.G + _random.Next(_rgbRange) - 8),
                        SafeColourVal(s_nearColor.B + _random.Next(_rgbRange) - 8));
                }
                else
                {
                    _col = Color.FromArgb(
                        SafeColourVal(255 - _random.Next(_rgbRange)),
                        SafeColourVal(255 - _random.Next(_rgbRange)),
                        SafeColourVal(255 - _random.Next(_rgbRange)));
                }

                // Set the find colour...
                SetFindColour(_col);

                // Take a screenshot...
                Color[] _taskbarPixels;

                using (Bitmap _notifyAreaBitmap = GetNotifyAreaScreenshot())
                {
                    // If something goes wrong, let's just assume we don't know where we should be
                    if (_notifyAreaBitmap == null)
                    {
                        return(new Point(-1, -1));
                    }

                    // We can reset the NotifyIcon now, and then...
                    NotifyIcon.Icon = _notifyIconIcon;

                    // Grab the pixels of the taskbar using my very own Pfz-derived bitmap to pixel array awesomeness
                    _taskbarPixels = BitmapToPixelArray.From(_notifyAreaBitmap);
                }

                // Get every occurence of our lovely colour next to something the same...
                bool _colMatched    = false;
                int  _colMatchIndex = -1;
                int  _colAttempt    = 0; // this determines whether we -1 any of the RGB

                while (true)
                {
                    Color _col2    = Color.FromArgb(0, 0, 0);
                    int   _colMod1 = (_colAttempt % 8) < 4 ? 0 : -1;
                    int   _colMod2 = (_colAttempt % 8) < 4 ? -1 : 0;

                    switch (_colAttempt % 4)
                    {
                    case 0:
                        _col2 = Color.FromArgb(SafeColourVal(_col.R + _colMod1), SafeColourVal(_col.G + _colMod1),
                                               SafeColourVal(_col.B + _colMod1));
                        break;

                    case 1:
                        _col2 = Color.FromArgb(SafeColourVal(_col.R + _colMod1), SafeColourVal(_col.G + _colMod1),
                                               SafeColourVal(_col.B + _colMod2));
                        break;

                    case 2:
                        _col2 = Color.FromArgb(SafeColourVal(_col.R + _colMod1), SafeColourVal(_col.G + _colMod2),
                                               SafeColourVal(_col.B + _colMod1));
                        break;

                    case 3:
                        _col2 = Color.FromArgb(SafeColourVal(_col.R + _colMod1), SafeColourVal(_col.G + _colMod2),
                                               SafeColourVal(_col.B + _colMod2));
                        break;
                    }

                    _colAttempt++;

                    _colMatchIndex = Array.FindIndex(_taskbarPixels, _colMatchIndex + 1, c => { return(c == _col2); });

                    if (_colMatchIndex == -1)
                    {
                        if (_colAttempt < 8)
                        {
                            continue;
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        if (_taskbarPixels[_colMatchIndex + 1] == _col2)
                        {
                            _colMatched = true;
                            break;
                        }
                    }
                }

                if (_colMatched)
                {
                    _hits++;
                    _last.X = _colMatchIndex % _notifyAreaRect.Width;
                    _last.Y = _colMatchIndex / _notifyAreaRect.Width; // Integer rounding is always downwards
                }
                else
                {
                    _hits   = 0;
                    _last.X = -1;
                    _last.Y = -1;
                }
            }

            // Don't forget, our current values are relative to the notification area and are at the bottom right of the icon!
            Point _location = new Point(_last.X, _last.Y);

            if (_location != new Point(-1, -1))
            {
                _location = new Point(_notifyAreaRect.X + (_last.X - 16), _notifyAreaRect.Y + (_last.Y - 14));
            }

            // And so we return the value now!
            return(_location);
        }