Пример #1
0
 /// <summary>
 /// Create an animation for the zoomer, depending on if it's active or not.
 /// </summary>
 void InitializeZoomer(bool isOn)
 {
     if (isOn)
     {
         // Initialize the zoom with a invalid position
         zoomAnimator = new RectangleAnimator(Rectangle.Empty, new Rectangle(int.MaxValue, int.MaxValue, 0, 0), FramesForMillis(1000), EasingType.Quintic, EasingMode.EaseOut);
         VerifyZoomAnimation(cursorPos, false);
     }
     else if (zoomAnimator != null)
     {
         zoomAnimator.ChangeDestination(new Rectangle(Point.Empty, Size.Empty), FramesForMillis(1000));
     }
 }
Пример #2
0
 /// <summary>
 ///     Create an animation for the zoomer, depending on if it's active or not.
 /// </summary>
 private void InitializeZoomer(bool isOn)
 {
     if (isOn)
     {
         // Initialize the zoom with a invalid position
         _zoomAnimator = new RectangleAnimator(NativeRect.Empty, new NativeRect(int.MaxValue, int.MaxValue, NativeSize.Empty), FramesForMillis(1000), EasingTypes.Quintic, EasingModes.EaseOut);
         VerifyZoomAnimation(_cursorPos, false);
     }
     else
     {
         _zoomAnimator?.ChangeDestination(new NativeRect(NativePoint.Empty, NativeSize.Empty), FramesForMillis(1000));
     }
 }
Пример #3
0
        /// <summary>
        ///     Checks if the Zoom area can move there where it wants to go, change direction if not.
        /// </summary>
        /// <param name="pos">preferred destination location for the zoom area</param>
        /// <param name="allowZoomOverCaptureRect">
        ///     false to try to find a location which is neither out of screen bounds nor
        ///     intersects with the selected rectangle
        /// </param>
        private void VerifyZoomAnimation(NativePoint pos, bool allowZoomOverCaptureRect)
        {
            var screenBounds = DisplayInfo.GetBounds(MousePosition);

            // convert to be relative to top left corner of all screen bounds
            screenBounds = screenBounds.MoveTo(WindowCapture.GetLocationRelativeToScreenBounds(screenBounds.Location));
            var relativeZoomSize = Math.Min(screenBounds.Width, screenBounds.Height) / 5;

            // Make sure the final size is a plural of 4, this makes it look better
            relativeZoomSize = relativeZoomSize - relativeZoomSize % 4;
            var zoomSize   = new NativeSize(relativeZoomSize, relativeZoomSize);
            var zoomOffset = new NativePoint(20, 20);

            var targetRectangle = _zoomAnimator.Final.Offset(pos);

            if (screenBounds.Contains(targetRectangle) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(targetRectangle)))
            {
                return;
            }
            var destinationLocation = NativePoint.Empty;
            var tl = new NativeRect(pos.X - (zoomOffset.X + zoomSize.Width), pos.Y - (zoomOffset.Y + zoomSize.Height), zoomSize.Width, zoomSize.Height);
            var tr = new NativeRect(pos.X + zoomOffset.X, pos.Y - (zoomOffset.Y + zoomSize.Height), zoomSize.Width, zoomSize.Height);
            var bl = new NativeRect(pos.X - (zoomOffset.X + zoomSize.Width), pos.Y + zoomOffset.Y, zoomSize.Width, zoomSize.Height);
            var br = new NativeRect(pos.X + zoomOffset.X, pos.Y + zoomOffset.Y, zoomSize.Width, zoomSize.Height);

            if (screenBounds.Contains(br) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(br)))
            {
                destinationLocation = new NativePoint(zoomOffset.X, zoomOffset.Y);
            }
            else if (screenBounds.Contains(bl) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(bl)))
            {
                destinationLocation = new NativePoint(-zoomOffset.X - zoomSize.Width, zoomOffset.Y);
            }
            else if (screenBounds.Contains(tr) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(tr)))
            {
                destinationLocation = new NativePoint(zoomOffset.X, -zoomOffset.Y - zoomSize.Width);
            }
            else if (screenBounds.Contains(tl) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(tl)))
            {
                destinationLocation = new NativePoint(-zoomOffset.X - zoomSize.Width, -zoomOffset.Y - zoomSize.Width);
            }
            if (destinationLocation == NativePoint.Empty && !allowZoomOverCaptureRect)
            {
                VerifyZoomAnimation(pos, true);
            }
            else
            {
                _zoomAnimator.ChangeDestination(new NativeRect(destinationLocation, zoomSize));
            }
        }
Пример #4
0
        /// <summary>
        /// Checks if the Zoom area can move there where it wants to go, change direction if not.
        /// </summary>
        /// <param name="pos">preferred destination location for the zoom area</param>
        /// <param name="allowZoomOverCaptureRect">false to try to find a location which is neither out of screen bounds nor intersects with the selected rectangle</param>
        private void VerifyZoomAnimation(Point pos, bool allowZoomOverCaptureRect)
        {
            Rectangle screenBounds = Screen.GetBounds(MousePosition);

            // convert to be relative to top left corner of all screen bounds
            screenBounds.Location = WindowCapture.GetLocationRelativeToScreenBounds(screenBounds.Location);
            int relativeZoomSize = Math.Min(screenBounds.Width, screenBounds.Height) / 5;

            // Make sure the final size is a plural of 4, this makes it look better
            relativeZoomSize = relativeZoomSize - relativeZoomSize % 4;
            Size  zoomSize   = new Size(relativeZoomSize, relativeZoomSize);
            Point zoomOffset = new Point(20, 20);

            Rectangle targetRectangle = _zoomAnimator.Final;

            targetRectangle.Offset(pos);
            if (!screenBounds.Contains(targetRectangle) || (!allowZoomOverCaptureRect && _captureRect.IntersectsWith(targetRectangle)))
            {
                Point     destinationLocation = Point.Empty;
                Rectangle tl = new Rectangle(pos.X - (zoomOffset.X + zoomSize.Width), pos.Y - (zoomOffset.Y + zoomSize.Height), zoomSize.Width, zoomSize.Height);
                Rectangle tr = new Rectangle(pos.X + zoomOffset.X, pos.Y - (zoomOffset.Y + zoomSize.Height), zoomSize.Width, zoomSize.Height);
                Rectangle bl = new Rectangle(pos.X - (zoomOffset.X + zoomSize.Width), pos.Y + zoomOffset.Y, zoomSize.Width, zoomSize.Height);
                Rectangle br = new Rectangle(pos.X + zoomOffset.X, pos.Y + zoomOffset.Y, zoomSize.Width, zoomSize.Height);
                if (screenBounds.Contains(br) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(br)))
                {
                    destinationLocation = new Point(zoomOffset.X, zoomOffset.Y);
                }
                else if (screenBounds.Contains(bl) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(bl)))
                {
                    destinationLocation = new Point(-zoomOffset.X - zoomSize.Width, zoomOffset.Y);
                }
                else if (screenBounds.Contains(tr) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(tr)))
                {
                    destinationLocation = new Point(zoomOffset.X, -zoomOffset.Y - zoomSize.Width);
                }
                else if (screenBounds.Contains(tl) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(tl)))
                {
                    destinationLocation = new Point(-zoomOffset.X - zoomSize.Width, -zoomOffset.Y - zoomSize.Width);
                }
                if (destinationLocation == Point.Empty && !allowZoomOverCaptureRect)
                {
                    VerifyZoomAnimation(pos, true);
                }
                else
                {
                    _zoomAnimator.ChangeDestination(new Rectangle(destinationLocation, zoomSize));
                }
            }
        }
Пример #5
0
        /// <summary>
        ///     Create an animation for the zoomer, depending on if it's active or not.
        /// </summary>
        private void InitializeZoomer(bool isOn)
        {
            if (isOn)
            {
                var screenBounds = DisplayInfo.GetBounds(MousePosition);
                var zoomerSize   = CalculateZoomSize(screenBounds);

                var initialPosition = new NativePoint(20, 20);
                // Initialize the zoom with an initial position
                _zoomAnimator = new RectangleAnimator(new NativeRect(initialPosition, NativeSize.Empty), new NativeRect(initialPosition, zoomerSize), FramesForMillis(1000), EasingTypes.Quintic, EasingModes.EaseOut);
                VerifyZoomAnimation(_cursorPos, false);
            }
            else
            {
                _zoomAnimator?.ChangeDestination(new NativeRect(NativePoint.Empty, NativeSize.Empty), FramesForMillis(1000));
            }
        }
Пример #6
0
        /// <summary>
        ///     Checks if the Zoom area can move there where it wants to go, change direction if not.
        /// </summary>
        /// <param name="pos">preferred destination location for the zoom area</param>
        /// <param name="allowZoomOverCaptureRect">
        ///     false to try to find a location which is neither out of screen bounds nor
        ///     intersects with the selected rectangle
        /// </param>
        private void VerifyZoomAnimation(NativePoint pos, bool allowZoomOverCaptureRect)
        {
            var screenBounds = DisplayInfo.GetBounds(MousePosition);
            var zoomSize     = CalculateZoomSize(screenBounds);
            var zoomOffset   = new NativePoint(20, 20);

            var targetRectangle = _zoomAnimator.Final.Offset(pos);

            if (screenBounds.Contains(targetRectangle) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(targetRectangle)))
            {
                return;
            }
            var destinationLocation = NativePoint.Empty;
            var tl = new NativeRect(pos.X - (zoomOffset.X + zoomSize.Width), pos.Y - (zoomOffset.Y + zoomSize.Height), zoomSize.Width, zoomSize.Height);
            var tr = new NativeRect(pos.X + zoomOffset.X, pos.Y - (zoomOffset.Y + zoomSize.Height), zoomSize.Width, zoomSize.Height);
            var bl = new NativeRect(pos.X - (zoomOffset.X + zoomSize.Width), pos.Y + zoomOffset.Y, zoomSize.Width, zoomSize.Height);
            var br = new NativeRect(pos.X + zoomOffset.X, pos.Y + zoomOffset.Y, zoomSize.Width, zoomSize.Height);

            if (screenBounds.Contains(br) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(br)))
            {
                destinationLocation = new NativePoint(zoomOffset.X, zoomOffset.Y);
            }
            else if (screenBounds.Contains(bl) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(bl)))
            {
                destinationLocation = new NativePoint(-zoomOffset.X - zoomSize.Width, zoomOffset.Y);
            }
            else if (screenBounds.Contains(tr) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(tr)))
            {
                destinationLocation = new NativePoint(zoomOffset.X, -zoomOffset.Y - zoomSize.Width);
            }
            else if (screenBounds.Contains(tl) && (allowZoomOverCaptureRect || !_captureRect.IntersectsWith(tl)))
            {
                destinationLocation = new NativePoint(-zoomOffset.X - zoomSize.Width, -zoomOffset.Y - zoomSize.Width);
            }
            if (destinationLocation == NativePoint.Empty && !allowZoomOverCaptureRect)
            {
                VerifyZoomAnimation(pos, true);
            }
            else
            {
                _zoomAnimator.ChangeDestination(new NativeRect(destinationLocation, zoomSize));
            }
        }
Пример #7
0
        /// <summary>
        ///     update the frame, this only invalidates
        /// </summary>
        protected override void Animate()
        {
            var lastPos = _cursorPos;

            _cursorPos = _mouseMovePos;

            if (SelectedCaptureWindow != null && lastPos.Equals(_cursorPos) && !IsAnimating(_zoomAnimator) && !IsAnimating(_windowAnimator))
            {
                return;
            }

            var lastWindow     = SelectedCaptureWindow;
            var horizontalMove = false;
            var verticalMove   = false;

            if (lastPos.X != _cursorPos.X)
            {
                horizontalMove = true;
            }
            if (lastPos.Y != _cursorPos.Y)
            {
                verticalMove = true;
            }

            if (UsedCaptureMode == CaptureMode.Region && _mouseDown)
            {
                _captureRect = new NativeRect(_cursorPos.X, _cursorPos.Y, _mX - _cursorPos.X, _mY - _cursorPos.Y).Normalize();
            }

            // Iterate over the found windows and check if the current location is inside a window
            var cursorPosition = Cursor.Position;

            SelectedCaptureWindow = null;


            // Store the top window
            IInteropWindow selectedTopWindow = null;

            foreach (var window in _windows)
            {
                if (window.Handle == Handle)
                {
                    // Ignore us
                    continue;
                }
                if (!window.GetInfo().Bounds.Contains(cursorPosition))
                {
                    continue;
                }

                selectedTopWindow     = window;
                SelectedCaptureWindow = window;

                // Only go over the children if we are in window mode
                if (CaptureMode.Window != UsedCaptureMode)
                {
                    break;
                }

                // Find the child window which is under the mouse
                // Start with the parent, drill down
                var selectedChildWindow = window;
                // TODO: Limit the levels we go down?
                do
                {
                    // Drill down, via the ZOrder
                    var tmpChildWindow = selectedChildWindow
                                         .GetZOrderedChildren()
                                         .FirstOrDefault(interopWindow => interopWindow.GetInfo().Bounds.Contains(cursorPosition));

                    if (tmpChildWindow == null)
                    {
                        break;
                    }
                    selectedChildWindow = tmpChildWindow;
                } while (true);

                // Assign the found child window
                SelectedCaptureWindow = selectedChildWindow;

                break;
            }

            // Test if something changed
            if (SelectedCaptureWindow != null && !SelectedCaptureWindow.Equals(lastWindow))
            {
                _capture.CaptureDetails.Title = selectedTopWindow.Text;
                _capture.CaptureDetails.AddMetaData("windowtitle", selectedTopWindow.Text);
                if (UsedCaptureMode == CaptureMode.Window)
                {
                    // Recreate the WindowScroller, if this is enabled, so we can detect if we can scroll
                    if (Conf.IsScrollingCaptureEnabled)
                    {
                        WindowScroller = SelectedCaptureWindow.GetWindowScroller(ScrollBarTypes.Vertical);
                        if (WindowScroller == null)
                        {
                            foreach (var interopWindow in SelectedCaptureWindow.GetChildren())
                            {
                                interopWindow.Dump();
                            }

                            WindowScroller = SelectedCaptureWindow.GetChildren().Select(child => child.GetWindowScroller(ScrollBarTypes.Vertical)).FirstOrDefault(scroller => scroller != null);
                        }
                    }

                    // We store the bound of the selected (child) window
                    // If it's maximized we take the client-bounds, otherwise we have parts we should not copy.
                    if (SelectedCaptureWindow.IsMaximized())
                    {
                        _captureRect = SelectedCaptureWindow.GetInfo().ClientBounds;
                    }
                    else
                    {
                        _captureRect = SelectedCaptureWindow.GetInfo().Bounds;
                    }

                    // Make sure the bounds fit to it's parent, some windows are bigger than their parent
                    // But only for non popups
                    if (!SelectedCaptureWindow.GetInfo().Style.HasFlag(WindowStyleFlags.WS_POPUP))
                    {
                        var parent = SelectedCaptureWindow.GetParent();
                        while (parent != IntPtr.Zero)
                        {
                            var parentWindow = InteropWindowFactory.CreateFor(parent);
                            _captureRect = _captureRect.Intersect(parentWindow.GetInfo().Bounds);
                            parent       = parentWindow.GetParent();
                        }
                    }

                    // As the ClientRectangle is in screen coordinates and not in bitmap coordinates, we need to correct.
                    _captureRect = _captureRect.Offset(-_capture.ScreenBounds.Location.X, -_capture.ScreenBounds.Location.Y);
                }
            }

            NativeRectFloat invalidateRectangle;

            if (_mouseDown && UsedCaptureMode != CaptureMode.Window)
            {
                var x1 = Math.Min(_mX, lastPos.X);
                var x2 = Math.Max(_mX, lastPos.X);
                var y1 = Math.Min(_mY, lastPos.Y);
                var y2 = Math.Max(_mY, lastPos.Y);
                x1 = Math.Min(x1, _cursorPos.X);
                x2 = Math.Max(x2, _cursorPos.X);
                y1 = Math.Min(y1, _cursorPos.Y);
                y2 = Math.Max(y2, _cursorPos.Y);

                // Safety correction
                x2 += 2;
                y2 += 2;

                // Here we correct for text-size

                // Calculate the size
                var textForWidth  = Math.Max(Math.Abs(_mX - _cursorPos.X), Math.Abs(_mX - lastPos.X));
                var textForHeight = Math.Max(Math.Abs(_mY - _cursorPos.Y), Math.Abs(_mY - lastPos.Y));

                using (var rulerFont = new Font(FontFamily.GenericSansSerif, 8))
                {
                    var textWidth = TextRenderer.MeasureText(textForWidth.ToString(CultureInfo.InvariantCulture), rulerFont);
                    x1 -= textWidth.Width + 15;

                    var textHeight = TextRenderer.MeasureText(textForHeight.ToString(CultureInfo.InvariantCulture), rulerFont);
                    y1 -= textHeight.Height + 10;
                }
                invalidateRectangle = new Rectangle(x1, y1, x2 - x1, y2 - y1);
                Invalidate(invalidateRectangle);
            }
            else if (UsedCaptureMode != CaptureMode.Window)
            {
                var allScreenBounds = WindowCapture.GetScreenBounds();

                allScreenBounds = allScreenBounds.MoveTo(WindowCapture.GetLocationRelativeToScreenBounds(allScreenBounds.Location));
                if (verticalMove)
                {
                    // Before
                    invalidateRectangle = new NativeRect(allScreenBounds.Left, lastPos.Y - 2, Width + 2, 45).Normalize();
                    Invalidate(invalidateRectangle);
                    // After
                    invalidateRectangle = new NativeRect(allScreenBounds.Left, _cursorPos.Y - 2, Width + 2, 45).Normalize();
                    Invalidate(invalidateRectangle);
                }
                if (horizontalMove)
                {
                    // Before
                    invalidateRectangle = new NativeRect(lastPos.X - 2, allScreenBounds.Top, 75, Height + 2).Normalize();
                    Invalidate(invalidateRectangle);
                    // After
                    invalidateRectangle = new NativeRect(_cursorPos.X - 2, allScreenBounds.Top, 75, Height + 2).Normalize();
                    Invalidate(invalidateRectangle);
                }
            }
            else if (SelectedCaptureWindow != null && !SelectedCaptureWindow.Equals(lastWindow))
            {
                // Window changed, animate from current to newly selected window
                _windowAnimator.ChangeDestination(_captureRect, FramesForMillis(700));
            }
            // always animate the Window area through to the last frame, so we see the fade-in/out untill the end
            // Using a safety "offset" to make sure the text is invalidated too
            const int safetySize = 30;

            // Check if the animation needs to be drawn
            if (IsAnimating(_windowAnimator))
            {
                invalidateRectangle = _windowAnimator.Current.Inflate(safetySize, safetySize);
                Invalidate(invalidateRectangle);
                invalidateRectangle = _windowAnimator.Next().Inflate(safetySize, safetySize);
                Invalidate(invalidateRectangle);
                // Check if this was the last of the windows animations in the normal region capture.
                if (UsedCaptureMode != CaptureMode.Window && !IsAnimating(_windowAnimator))
                {
                    Invalidate();
                }
            }

            if (_zoomAnimator != null && (IsAnimating(_zoomAnimator) || UsedCaptureMode != CaptureMode.Window))
            {
                // Make sure we invalidate the old zoom area
                invalidateRectangle = _zoomAnimator.Current.Offset(lastPos);
                Invalidate(invalidateRectangle);
                // Only verify if we are really showing the zoom, not the outgoing animation
                if (Conf.ZoomerEnabled && UsedCaptureMode != CaptureMode.Window)
                {
                    VerifyZoomAnimation(_cursorPos, false);
                }
                // The following logic is not needed, next always returns the current if there are no frames left
                // but it makes more sense if we want to change something in the logic
                invalidateRectangle = IsAnimating(_zoomAnimator) ? _zoomAnimator.Next() : _zoomAnimator.Current;
                Invalidate(invalidateRectangle.Offset(_cursorPos));
            }
            // Force update "now"
            Update();
        }
Пример #8
0
        /// <summary>
        ///     Handle the key down event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CaptureFormKeyDown(object sender, KeyEventArgs e)
        {
            var step = _isCtrlPressed ? 10 : 1;

            switch (e.KeyCode)
            {
            case Keys.Up:
                Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y - step);
                break;

            case Keys.Down:
                Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y + step);
                break;

            case Keys.Left:
                Cursor.Position = new Point(Cursor.Position.X - step, Cursor.Position.Y);
                break;

            case Keys.Right:
                Cursor.Position = new Point(Cursor.Position.X + step, Cursor.Position.Y);
                break;

            case Keys.ShiftKey:
                // Fixmode
                if (_fixMode == FixMode.None)
                {
                    _fixMode = FixMode.Initiated;
                }
                break;

            case Keys.ControlKey:
                _isCtrlPressed = true;
                break;

            case Keys.Escape:
                // Cancel
                DialogResult = DialogResult.Cancel;
                break;

            case Keys.M:
                // Toggle mouse cursor
                _capture.CursorVisible = !_capture.CursorVisible;
                Invalidate();
                break;

            //// TODO: Enable when the screen capture code works reliable
            //case Keys.V:
            //	// Video
            //	if (capture.CaptureDetails.CaptureMode != CaptureMode.Video) {
            //		capture.CaptureDetails.CaptureMode = CaptureMode.Video;
            //	} else {
            //		capture.CaptureDetails.CaptureMode = captureMode;
            //	}
            //	Invalidate();
            //	break;
            case Keys.Z:
                if (UsedCaptureMode == CaptureMode.Region)
                {
                    // Toggle zoom
                    Conf.ZoomerEnabled = !Conf.ZoomerEnabled;
                    InitializeZoomer(Conf.ZoomerEnabled);
                    Invalidate();
                }
                break;

            case Keys.D:
                if (UsedCaptureMode == CaptureMode.Window)
                {
                    // Toggle debug
                    _showDebugInfo = !_showDebugInfo;
                    Invalidate();
                }
                break;

            case Keys.Space:
                // Toggle capture mode
                switch (UsedCaptureMode)
                {
                case CaptureMode.Region:
                    // Set the window capture mode
                    UsedCaptureMode = CaptureMode.Window;
                    // "Fade out" Zoom
                    InitializeZoomer(false);
                    // "Fade in" window
                    _windowAnimator = new RectangleAnimator(new NativeRect(_cursorPos, NativeSize.Empty), _captureRect, FramesForMillis(700), EasingTypes.Quintic, EasingModes.EaseOut);
                    _captureRect    = Rectangle.Empty;
                    Invalidate();
                    break;

                case CaptureMode.Window:
                    // Set the region capture mode
                    UsedCaptureMode = CaptureMode.Region;
                    // "Fade out" window
                    _windowAnimator.ChangeDestination(new NativeRect(_cursorPos, NativeSize.Empty), FramesForMillis(700));
                    // Fade in zoom
                    InitializeZoomer(Conf.ZoomerEnabled);
                    _captureRect = Rectangle.Empty;
                    Invalidate();
                    break;
                }
                SelectedCaptureWindow = null;
                OnMouseMove(this, new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0));
                break;

            case Keys.Return:
                // Confirm
                if (UsedCaptureMode == CaptureMode.Window)
                {
                    DialogResult = DialogResult.OK;
                }
                else if (!_mouseDown)
                {
                    StartSelecting();
                }
                else
                {
                    FinishSelecting();
                }
                break;

            case Keys.F:
                ToFront = !ToFront;
                TopMost = !TopMost;
                break;
            }
        }
Пример #9
0
        /// <summary>
        /// update the frame, this only invalidates
        /// </summary>
        protected override void Animate()
        {
            Point lastPos = cursorPos.Clone();

            cursorPos = mouseMovePos.Clone();

            if (selectedCaptureWindow != null && lastPos.Equals(cursorPos) && !isAnimating(zoomAnimator) && !isAnimating(windowAnimator))
            {
                return;
            }

            Rectangle     lastCaptureRect = new Rectangle(captureRect.Location, captureRect.Size);
            WindowDetails lastWindow      = selectedCaptureWindow;
            bool          horizontalMove  = false;
            bool          verticalMove    = false;

            if (lastPos.X != cursorPos.X)
            {
                horizontalMove = true;
            }
            if (lastPos.Y != cursorPos.Y)
            {
                verticalMove = true;
            }

            if (captureMode == CaptureMode.Region && mouseDown)
            {
                captureRect = GuiRectangle.GetGuiRectangle(cursorPos.X, cursorPos.Y, mX - cursorPos.X, mY - cursorPos.Y);
            }

            // Iterate over the found windows and check if the current location is inside a window
            Point cursorPosition = Cursor.Position;

            selectedCaptureWindow = null;
            lock (windows) {
                foreach (WindowDetails window in windows)
                {
                    if (window.Contains(cursorPosition))
                    {
                        // Only go over the children if we are in window mode
                        if (CaptureMode.Window == captureMode)
                        {
                            selectedCaptureWindow = window.FindChildUnderPoint(cursorPosition);
                        }
                        else
                        {
                            selectedCaptureWindow = window;
                        }
                        break;
                    }
                }
            }

            if (selectedCaptureWindow != null && !selectedCaptureWindow.Equals(lastWindow))
            {
                capture.CaptureDetails.Title = selectedCaptureWindow.Text;
                capture.CaptureDetails.AddMetaData("windowtitle", selectedCaptureWindow.Text);
                if (captureMode == CaptureMode.Window)
                {
                    // Here we want to capture the window which is under the mouse
                    captureRect = selectedCaptureWindow.WindowRectangle;
                    // As the ClientRectangle is not in Bitmap coordinates, we need to correct.
                    captureRect.Offset(-capture.ScreenBounds.Location.X, -capture.ScreenBounds.Location.Y);
                }
            }

            Rectangle invalidateRectangle = Rectangle.Empty;

            if (mouseDown && (captureMode != CaptureMode.Window))
            {
                int x1 = Math.Min(mX, lastPos.X);
                int x2 = Math.Max(mX, lastPos.X);
                int y1 = Math.Min(mY, lastPos.Y);
                int y2 = Math.Max(mY, lastPos.Y);
                x1 = Math.Min(x1, cursorPos.X);
                x2 = Math.Max(x2, cursorPos.X);
                y1 = Math.Min(y1, cursorPos.Y);
                y2 = Math.Max(y2, cursorPos.Y);

                // Safety correction
                x2 += 2;
                y2 += 2;

                // Here we correct for text-size

                // Calculate the size
                int textForWidth  = Math.Max(Math.Abs(mX - cursorPos.X), Math.Abs(mX - lastPos.X));
                int textForHeight = Math.Max(Math.Abs(mY - cursorPos.Y), Math.Abs(mY - lastPos.Y));

                using (Font rulerFont = new Font(FontFamily.GenericSansSerif, 8)) {
                    Size measureWidth = TextRenderer.MeasureText(textForWidth.ToString(), rulerFont);
                    x1 -= measureWidth.Width + 15;

                    Size measureHeight = TextRenderer.MeasureText(textForHeight.ToString(), rulerFont);
                    y1 -= measureWidth.Height + 10;
                }
                invalidateRectangle = new Rectangle(x1, y1, x2 - x1, y2 - y1);
                Invalidate(invalidateRectangle);
            }
            else if (captureMode != CaptureMode.Window)
            {
                if (!isTerminalServerSession)
                {
                    Rectangle allScreenBounds = WindowCapture.GetScreenBounds();
                    allScreenBounds.Location = WindowCapture.GetLocationRelativeToScreenBounds(allScreenBounds.Location);
                    if (verticalMove)
                    {
                        // Before
                        invalidateRectangle = GuiRectangle.GetGuiRectangle(allScreenBounds.Left, lastPos.Y - 2, this.Width + 2, 45);
                        Invalidate(invalidateRectangle);
                        // After
                        invalidateRectangle = GuiRectangle.GetGuiRectangle(allScreenBounds.Left, cursorPos.Y - 2, this.Width + 2, 45);
                        Invalidate(invalidateRectangle);
                    }
                    if (horizontalMove)
                    {
                        // Before
                        invalidateRectangle = GuiRectangle.GetGuiRectangle(lastPos.X - 2, allScreenBounds.Top, 75, this.Height + 2);
                        Invalidate(invalidateRectangle);
                        // After
                        invalidateRectangle = GuiRectangle.GetGuiRectangle(cursorPos.X - 2, allScreenBounds.Top, 75, this.Height + 2);
                        Invalidate(invalidateRectangle);
                    }
                }
            }
            else
            {
                if (selectedCaptureWindow != null && !selectedCaptureWindow.Equals(lastWindow))
                {
                    // Window changes, make new animation from current to target
                    windowAnimator.ChangeDestination(captureRect, FramesForMillis(700));
                }
            }
            // always animate the Window area through to the last frame, so we see the fade-in/out untill the end
            // Using a safety "offset" to make sure the text is invalidated too
            const int SAFETY_SIZE = 30;

            // Check if the
            if (isAnimating(windowAnimator))
            {
                invalidateRectangle = windowAnimator.Current;
                invalidateRectangle.Inflate(SAFETY_SIZE, SAFETY_SIZE);
                Invalidate(invalidateRectangle);
                invalidateRectangle = windowAnimator.Next();
                invalidateRectangle.Inflate(SAFETY_SIZE, SAFETY_SIZE);
                Invalidate(invalidateRectangle);
                // Check if this was the last of the windows animations in the normal region capture.
                if (captureMode != CaptureMode.Window && !isAnimating(windowAnimator))
                {
                    Invalidate();
                }
            }

            if (zoomAnimator != null && (isAnimating(zoomAnimator) || captureMode != CaptureMode.Window))
            {
                // Make sure we invalidate the old zoom area
                invalidateRectangle = zoomAnimator.Current;
                invalidateRectangle.Offset(lastPos);
                Invalidate(invalidateRectangle);
                // Only verify if we are really showing the zoom, not the outgoing animation
                if (conf.ZoomerEnabled && captureMode != CaptureMode.Window)
                {
                    VerifyZoomAnimation(cursorPos, false);
                }
                // The following logic is not needed, next always returns the current if there are no frames left
                // but it makes more sense if we want to change something in the logic
                if (isAnimating(zoomAnimator))
                {
                    invalidateRectangle = zoomAnimator.Next();
                }
                else
                {
                    invalidateRectangle = zoomAnimator.Current;
                }
                invalidateRectangle.Offset(cursorPos);
                Invalidate(invalidateRectangle);
            }
            // Force update "now"
            Update();
        }
Пример #10
0
        /// <summary>
        /// Handle the key down event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void CaptureFormKeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
            case Keys.Up:
                Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y - 1);
                break;

            case Keys.Down:
                Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y + 1);
                break;

            case Keys.Left:
                Cursor.Position = new Point(Cursor.Position.X - 1, Cursor.Position.Y);
                break;

            case Keys.Right:
                Cursor.Position = new Point(Cursor.Position.X + 1, Cursor.Position.Y);
                break;

            case Keys.ShiftKey:
                // Fixmode
                if (fixMode == FixMode.None)
                {
                    fixMode = FixMode.Initiated;
                    return;
                }
                break;

            case Keys.Escape:
                // Cancel
                DialogResult = DialogResult.Cancel;
                break;

            case Keys.M:
                // Toggle mouse cursor
                capture.CursorVisible = !capture.CursorVisible;
                Invalidate();
                break;

            //// TODO: Enable when the screen capture code works reliable
            //case Keys.V:
            //	// Video
            //	if (capture.CaptureDetails.CaptureMode != CaptureMode.Video) {
            //		capture.CaptureDetails.CaptureMode = CaptureMode.Video;
            //	} else {
            //		capture.CaptureDetails.CaptureMode = captureMode;
            //	}
            //	Invalidate();
            //	break;
            case Keys.Z:
                if (captureMode == CaptureMode.Region)
                {
                    // Toggle zoom
                    conf.ZoomerEnabled = !conf.ZoomerEnabled;
                    InitializeZoomer(conf.ZoomerEnabled);
                    Invalidate();
                }
                break;

            case Keys.Space:
                // Toggle capture mode
                switch (captureMode)
                {
                case CaptureMode.Region:
                    // Set the window capture mode
                    captureMode = CaptureMode.Window;
                    // "Fade out" Zoom
                    InitializeZoomer(false);
                    // "Fade in" window
                    windowAnimator = new RectangleAnimator(new Rectangle(cursorPos, Size.Empty), captureRect, FramesForMillis(700), EasingType.Quintic, EasingMode.EaseOut);
                    captureRect    = Rectangle.Empty;
                    Invalidate();
                    break;

                case CaptureMode.Window:
                    // Set the region capture mode
                    captureMode = CaptureMode.Region;
                    // "Fade out" window
                    windowAnimator.ChangeDestination(new Rectangle(cursorPos, Size.Empty), FramesForMillis(700));
                    // Fade in zoom
                    InitializeZoomer(conf.ZoomerEnabled);
                    captureRect = Rectangle.Empty;
                    Invalidate();
                    break;
                }
                selectedCaptureWindow = null;
                OnMouseMove(this, new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0));
                break;

            case Keys.Return:
                // Confirm
                if (captureMode == CaptureMode.Window)
                {
                    DialogResult = DialogResult.OK;
                }
                break;
            }
        }
Пример #11
0
		/// <summary>
		/// Handle the key down event
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		void CaptureFormKeyDown(object sender, KeyEventArgs e) {
			int step = _isCtrlPressed ? 10 : 1;

			switch (e.KeyCode) {
				case Keys.Up:
					Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y - step);
					break;
				case Keys.Down:
					Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y + step);
					break;
				case Keys.Left:
					Cursor.Position = new Point(Cursor.Position.X - step, Cursor.Position.Y);
					break;
				case Keys.Right:
					Cursor.Position = new Point(Cursor.Position.X + step, Cursor.Position.Y);
					break;
				case Keys.ShiftKey:
					// Fixmode
					if (_fixMode == FixMode.None) {
						_fixMode = FixMode.Initiated;
					}
					break;
				case Keys.ControlKey:
					_isCtrlPressed = true;
					break;
				case Keys.Escape:
					// Cancel
					DialogResult = DialogResult.Cancel;
					break;
				case Keys.M:
					// Toggle mouse cursor
					_capture.CursorVisible = !_capture.CursorVisible;
					Invalidate();
					break;
				//// TODO: Enable when the screen capture code works reliable
				//case Keys.V:
				//	// Video
				//	if (capture.CaptureDetails.CaptureMode != CaptureMode.Video) {
				//		capture.CaptureDetails.CaptureMode = CaptureMode.Video;
				//	} else {
				//		capture.CaptureDetails.CaptureMode = captureMode;
				//	}
				//	Invalidate();
				//	break;
				case Keys.Z:
					if (_captureMode == CaptureMode.Region) {
						// Toggle zoom
						Conf.ZoomerEnabled = !Conf.ZoomerEnabled;
						InitializeZoomer(Conf.ZoomerEnabled);
						Invalidate();
					}
					break;
				case Keys.Space:
					// Toggle capture mode
					switch (_captureMode) {
						case CaptureMode.Region:
							// Set the window capture mode
							_captureMode = CaptureMode.Window;
							// "Fade out" Zoom
							InitializeZoomer(false);
							// "Fade in" window
							_windowAnimator = new RectangleAnimator(new Rectangle(_cursorPos, Size.Empty), _captureRect, FramesForMillis(700), EasingType.Quintic, EasingMode.EaseOut);
							_captureRect = Rectangle.Empty;
							Invalidate();
							break;
						case CaptureMode.Window:
							// Set the region capture mode
							_captureMode = CaptureMode.Region;
							// "Fade out" window
							_windowAnimator.ChangeDestination(new Rectangle(_cursorPos, Size.Empty), FramesForMillis(700));
							// Fade in zoom
							InitializeZoomer(Conf.ZoomerEnabled);
							_captureRect = Rectangle.Empty;
							Invalidate();
							break;
					}
					_selectedCaptureWindow = null;
					OnMouseMove(this, new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0));
					break;
				case Keys.Return:
					// Confirm
					if (_captureMode == CaptureMode.Window) {
						DialogResult = DialogResult.OK;
					} else if (!_mouseDown) {
						HandleMouseDown();
					} else if (_mouseDown) {
						HandleMouseUp();
					}
					break;
			}
		}
Пример #12
0
        /// <summary>
        /// update the frame, this only invalidates
        /// </summary>
        protected override void Animate()
        {
            Point lastPos = _cursorPos;

            _cursorPos = _mouseMovePos;

            if (_selectedCaptureWindow != null && lastPos.Equals(_cursorPos) && !IsAnimating(_zoomAnimator) && !IsAnimating(_windowAnimator))
            {
                return;
            }

            WindowDetails lastWindow     = _selectedCaptureWindow;
            bool          horizontalMove = false;
            bool          verticalMove   = false;

            if (lastPos.X != _cursorPos.X)
            {
                horizontalMove = true;
            }
            if (lastPos.Y != _cursorPos.Y)
            {
                verticalMove = true;
            }

            if (_captureMode == CaptureMode.Region && _mouseDown)
            {
                _captureRect = GuiRectangle.GetGuiRectangle(_cursorPos.X, _cursorPos.Y, _mX - _cursorPos.X, _mY - _cursorPos.Y);
            }

            // Iterate over the found windows and check if the current location is inside a window
            Point cursorPosition = Cursor.Position;

            _selectedCaptureWindow = null;
            lock (_windows) {
                foreach (var window in _windows)
                {
                    if (!window.Contains(cursorPosition))
                    {
                        continue;
                    }
                    // Only go over the children if we are in window mode
                    _selectedCaptureWindow = CaptureMode.Window == _captureMode?window.FindChildUnderPoint(cursorPosition) : window;

                    break;
                }
            }

            if (_selectedCaptureWindow != null && !_selectedCaptureWindow.Equals(lastWindow))
            {
                _capture.CaptureDetails.Title = _selectedCaptureWindow.Text;
                _capture.CaptureDetails.AddMetaData("windowtitle", _selectedCaptureWindow.Text);
                if (_captureMode == CaptureMode.Window)
                {
                    // Here we want to capture the window which is under the mouse
                    _captureRect = _selectedCaptureWindow.WindowRectangle;
                    // As the ClientRectangle is not in Bitmap coordinates, we need to correct.
                    _captureRect.Offset(-_capture.ScreenBounds.Location.X, -_capture.ScreenBounds.Location.Y);
                }
            }

            Rectangle invalidateRectangle;

            if (_mouseDown && (_captureMode != CaptureMode.Window))
            {
                int x1 = Math.Min(_mX, lastPos.X);
                int x2 = Math.Max(_mX, lastPos.X);
                int y1 = Math.Min(_mY, lastPos.Y);
                int y2 = Math.Max(_mY, lastPos.Y);
                x1 = Math.Min(x1, _cursorPos.X);
                x2 = Math.Max(x2, _cursorPos.X);
                y1 = Math.Min(y1, _cursorPos.Y);
                y2 = Math.Max(y2, _cursorPos.Y);

                // Safety correction
                x2 += 2;
                y2 += 2;

                // Here we correct for text-size

                // Calculate the size
                int textForWidth  = Math.Max(Math.Abs(_mX - _cursorPos.X), Math.Abs(_mX - lastPos.X));
                int textForHeight = Math.Max(Math.Abs(_mY - _cursorPos.Y), Math.Abs(_mY - lastPos.Y));

                using (Font rulerFont = new Font(FontFamily.GenericSansSerif, 8)) {
                    Size measureWidth = TextRenderer.MeasureText(textForWidth.ToString(CultureInfo.InvariantCulture), rulerFont);
                    x1 -= measureWidth.Width + 15;

                    Size measureHeight = TextRenderer.MeasureText(textForHeight.ToString(CultureInfo.InvariantCulture), rulerFont);
                    y1 -= measureHeight.Height + 10;
                }
                invalidateRectangle = new Rectangle(x1, y1, x2 - x1, y2 - y1);
                Invalidate(invalidateRectangle);
            }
            else if (_captureMode != CaptureMode.Window)
            {
                if (!IsTerminalServerSession)
                {
                    Rectangle allScreenBounds = WindowCapture.GetScreenBounds();
                    allScreenBounds.Location = WindowCapture.GetLocationRelativeToScreenBounds(allScreenBounds.Location);
                    if (verticalMove)
                    {
                        // Before
                        invalidateRectangle = GuiRectangle.GetGuiRectangle(allScreenBounds.Left, lastPos.Y - 2, Width + 2, 45);
                        Invalidate(invalidateRectangle);
                        // After
                        invalidateRectangle = GuiRectangle.GetGuiRectangle(allScreenBounds.Left, _cursorPos.Y - 2, Width + 2, 45);
                        Invalidate(invalidateRectangle);
                    }
                    if (horizontalMove)
                    {
                        // Before
                        invalidateRectangle = GuiRectangle.GetGuiRectangle(lastPos.X - 2, allScreenBounds.Top, 75, Height + 2);
                        Invalidate(invalidateRectangle);
                        // After
                        invalidateRectangle = GuiRectangle.GetGuiRectangle(_cursorPos.X - 2, allScreenBounds.Top, 75, Height + 2);
                        Invalidate(invalidateRectangle);
                    }
                }
            }
            else
            {
                if (_selectedCaptureWindow != null && !_selectedCaptureWindow.Equals(lastWindow))
                {
                    // Window changes, make new animation from current to target
                    _windowAnimator.ChangeDestination(_captureRect, FramesForMillis(700));
                }
            }
            // always animate the Window area through to the last frame, so we see the fade-in/out untill the end
            // Using a safety "offset" to make sure the text is invalidated too
            const int safetySize = 30;

            // Check if the animation needs to be drawn
            if (IsAnimating(_windowAnimator))
            {
                invalidateRectangle = _windowAnimator.Current;
                invalidateRectangle.Inflate(safetySize, safetySize);
                Invalidate(invalidateRectangle);
                invalidateRectangle = _windowAnimator.Next();
                invalidateRectangle.Inflate(safetySize, safetySize);
                Invalidate(invalidateRectangle);
                // Check if this was the last of the windows animations in the normal region capture.
                if (_captureMode != CaptureMode.Window && !IsAnimating(_windowAnimator))
                {
                    Invalidate();
                }
            }

            if (_zoomAnimator != null && (IsAnimating(_zoomAnimator) || _captureMode != CaptureMode.Window))
            {
                // Make sure we invalidate the old zoom area
                invalidateRectangle = _zoomAnimator.Current;
                invalidateRectangle.Offset(lastPos);
                Invalidate(invalidateRectangle);
                // Only verify if we are really showing the zoom, not the outgoing animation
                if (Conf.ZoomerEnabled && _captureMode != CaptureMode.Window)
                {
                    VerifyZoomAnimation(_cursorPos, false);
                }
                // The following logic is not needed, next always returns the current if there are no frames left
                // but it makes more sense if we want to change something in the logic
                invalidateRectangle = IsAnimating(_zoomAnimator) ? _zoomAnimator.Next() : _zoomAnimator.Current;
                invalidateRectangle.Offset(_cursorPos);
                Invalidate(invalidateRectangle);
            }
            // Force update "now"
            Update();
        }