/// <summary> /// Paint the actual visible parts /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnPaint(object sender, PaintEventArgs e) { var graphics = e.Graphics; var clipRectangle = e.ClipRectangle; graphics.DrawImageUnscaled(_capture.Bitmap, Point.Empty); // Only draw Cursor if it's (partly) visible if (_capture.Cursor != null && _capture.CursorVisible && clipRectangle.IntersectsWith(new Rectangle(_capture.CursorLocation, _capture.Cursor.Size))) { graphics.DrawIcon(_capture.Cursor, _capture.CursorLocation.X, _capture.CursorLocation.Y); } if (_mouseDown || UsedCaptureMode == CaptureMode.Window || IsAnimating(_windowAnimator)) { _captureRect = _captureRect.Intersect(new Rectangle(Point.Empty, _capture.ScreenBounds.Size)); // crop what is outside the screen var fixedRect = IsAnimating(_windowAnimator) ? _windowAnimator.Current : _captureRect; // If the _windowScroller != null, we can (most likely) capture the window with a scrolling technique if (WindowScroller != null && Equals(WindowScroller.ScrollBarWindow, SelectedCaptureWindow)) { graphics.FillRectangle(ScrollingOverlayBrush, fixedRect); } else { graphics.FillRectangle(GreenOverlayBrush, fixedRect); } graphics.DrawRectangle(OverlayPen, fixedRect); // rulers const int dist = 8; string captureWidth; string captureHeight; // The following fixes the very old incorrect size information bug if (UsedCaptureMode == CaptureMode.Window) { captureWidth = _captureRect.Width.ToString(CultureInfo.InvariantCulture); captureHeight = _captureRect.Height.ToString(CultureInfo.InvariantCulture); } else { captureWidth = (_captureRect.Width + 1).ToString(CultureInfo.InvariantCulture); captureHeight = (_captureRect.Height + 1).ToString(CultureInfo.InvariantCulture); } using (var rulerFont = new Font(FontFamily.GenericSansSerif, 8)) { var measureWidth = TextRenderer.MeasureText(captureWidth, rulerFont); var measureHeight = TextRenderer.MeasureText(captureHeight, rulerFont); var hSpace = measureWidth.Width + 3; var vSpace = measureHeight.Height + 3; Brush bgBrush = new SolidBrush(Color.FromArgb(200, 217, 240, 227)); var rulerPen = new Pen(Color.SeaGreen); // horizontal ruler if (fixedRect.Width > hSpace + 3) { using (var p = RoundedRectangle.Create2( fixedRect.X + (fixedRect.Width / 2 - hSpace / 2) + 3, fixedRect.Y - dist - 7, measureWidth.Width - 3, measureWidth.Height, 3)) { graphics.FillPath(bgBrush, p); graphics.DrawPath(rulerPen, p); graphics.DrawString(captureWidth, rulerFont, rulerPen.Brush, fixedRect.X + (fixedRect.Width / 2 - hSpace / 2) + 3, fixedRect.Y - dist - 7); graphics.DrawLine(rulerPen, fixedRect.X, fixedRect.Y - dist, fixedRect.X + (fixedRect.Width / 2 - hSpace / 2), fixedRect.Y - dist); graphics.DrawLine(rulerPen, fixedRect.X + fixedRect.Width / 2 + hSpace / 2, fixedRect.Y - dist, fixedRect.X + fixedRect.Width, fixedRect.Y - dist); graphics.DrawLine(rulerPen, fixedRect.X, fixedRect.Y - dist - 3, fixedRect.X, fixedRect.Y - dist + 3); graphics.DrawLine(rulerPen, fixedRect.X + fixedRect.Width, fixedRect.Y - dist - 3, fixedRect.X + fixedRect.Width, fixedRect.Y - dist + 3); } } // vertical ruler if (fixedRect.Height > vSpace + 3) { using (var p = RoundedRectangle.Create2( fixedRect.X - measureHeight.Width + 1, fixedRect.Y + (fixedRect.Height / 2 - vSpace / 2) + 2, measureHeight.Width - 3, measureHeight.Height - 1, 3)) { graphics.FillPath(bgBrush, p); graphics.DrawPath(rulerPen, p); graphics.DrawString(captureHeight, rulerFont, rulerPen.Brush, fixedRect.X - measureHeight.Width + 1, fixedRect.Y + (fixedRect.Height / 2 - vSpace / 2) + 2); graphics.DrawLine(rulerPen, fixedRect.X - dist, fixedRect.Y, fixedRect.X - dist, fixedRect.Y + (fixedRect.Height / 2 - vSpace / 2)); graphics.DrawLine(rulerPen, fixedRect.X - dist, fixedRect.Y + fixedRect.Height / 2 + vSpace / 2, fixedRect.X - dist, fixedRect.Y + fixedRect.Height); graphics.DrawLine(rulerPen, fixedRect.X - dist - 3, fixedRect.Y, fixedRect.X - dist + 3, fixedRect.Y); graphics.DrawLine(rulerPen, fixedRect.X - dist - 3, fixedRect.Y + fixedRect.Height, fixedRect.X - dist + 3, fixedRect.Y + fixedRect.Height); } } rulerPen.Dispose(); bgBrush.Dispose(); } // Display size of selected rectangle // Prepare the font and text. using (var sizeFont = new Font(FontFamily.GenericSansSerif, 12)) { // When capturing a Region we need to add 1 to the height/width for correction string sizeText; if (UsedCaptureMode == CaptureMode.Region) { // correct the GUI width to real width for the shown size sizeText = _captureRect.Width + 1 + " x " + (_captureRect.Height + 1); } else { sizeText = _captureRect.Width + " x " + _captureRect.Height; } // Calculate the scaled font size. var extent = graphics.MeasureString(sizeText, sizeFont); var hRatio = _captureRect.Height / (extent.Height * 2); var wRatio = _captureRect.Width / (extent.Width * 2); var ratio = hRatio < wRatio ? hRatio : wRatio; var newSize = sizeFont.Size * ratio; if (newSize >= 4) { // Only show if 4pt or larger. if (newSize > 20) { newSize = 20; } // Draw the size. using (var newSizeFont = new Font(FontFamily.GenericSansSerif, newSize, FontStyle.Bold)) { var sizeLocation = new PointF(fixedRect.X + _captureRect.Width / 2 - extent.Width / 2, fixedRect.Y + _captureRect.Height / 2 - newSizeFont.GetHeight() / 2); graphics.DrawString(sizeText, newSizeFont, Brushes.LightSeaGreen, sizeLocation); if (_showDebugInfo && SelectedCaptureWindow != null) { using (var process = Process.GetProcessById(SelectedCaptureWindow.GetProcessId())) { string title = $"#{SelectedCaptureWindow.Handle.ToInt64():X} - {(SelectedCaptureWindow.Text.Length > 0 ? SelectedCaptureWindow.Text : process.ProcessName)}"; var debugLocation = new PointF(fixedRect.X, fixedRect.Y); graphics.DrawString(title, sizeFont, Brushes.DarkOrange, debugLocation); } } } } } } else { using (var pen = new Pen(Color.LightSeaGreen)) { pen.DashStyle = DashStyle.Dot; var screenBounds = _capture.ScreenBounds; graphics.DrawLine(pen, _cursorPos.X, screenBounds.Y, _cursorPos.X, screenBounds.Height); graphics.DrawLine(pen, screenBounds.X, _cursorPos.Y, screenBounds.Width, _cursorPos.Y); } var xy = _cursorPos.X + " x " + _cursorPos.Y; using (var f = new Font(FontFamily.GenericSansSerif, 8)) { var xySize = TextRenderer.MeasureText(xy, f); using (var gp = RoundedRectangle.Create2(_cursorPos.X + 5, _cursorPos.Y + 5, xySize.Width - 3, xySize.Height, 3)) { using (Brush bgBrush = new SolidBrush(Color.FromArgb(200, 217, 240, 227))) { graphics.FillPath(bgBrush, gp); } using (var pen = new Pen(Color.SeaGreen)) { graphics.DrawPath(pen, gp); var coordinatePosition = new Point(_cursorPos.X + 5, _cursorPos.Y + 5); graphics.DrawString(xy, f, pen.Brush, coordinatePosition); } } } } // Zoom if (_zoomAnimator == null || (!IsAnimating(_zoomAnimator) && UsedCaptureMode == CaptureMode.Window)) { return; } const int zoomSourceWidth = 25; const int zoomSourceHeight = 25; var sourceRectangle = new NativeRect(_cursorPos.X - zoomSourceWidth / 2, _cursorPos.Y - zoomSourceHeight / 2, zoomSourceWidth, zoomSourceHeight); var destinationRectangle = _zoomAnimator.Current.Offset(_cursorPos); DrawZoom(graphics, sourceRectangle, destinationRectangle); }
/// <summary> /// Paint the actual visible parts /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void OnPaint(object sender, PaintEventArgs e) { Graphics graphics = e.Graphics; Rectangle clipRectangle = e.ClipRectangle; //graphics.BitBlt((Bitmap)buffer, Point.Empty); graphics.DrawImageUnscaled(_capture.Image, Point.Empty); // Only draw Cursor if it's (partly) visible if (_capture.Cursor != null && _capture.CursorVisible && clipRectangle.IntersectsWith(new Rectangle(_capture.CursorLocation, _capture.Cursor.Size))) { graphics.DrawIcon(_capture.Cursor, _capture.CursorLocation.X, _capture.CursorLocation.Y); } if (_mouseDown || _captureMode == CaptureMode.Window || isAnimating(_windowAnimator)) { _captureRect.Intersect(new Rectangle(Point.Empty, _capture.ScreenBounds.Size)); // crop what is outside the screen Rectangle fixedRect; //if (captureMode == CaptureMode.Window) { if (isAnimating(_windowAnimator)) { // Use the animator fixedRect = _windowAnimator.Current; } else { fixedRect = _captureRect; } // TODO: enable when the screen capture code works reliable //if (capture.CaptureDetails.CaptureMode == CaptureMode.Video) { // graphics.FillRectangle(RedOverlayBrush, fixedRect); //} else { graphics.FillRectangle(GreenOverlayBrush, fixedRect); //} graphics.DrawRectangle(OverlayPen, fixedRect); // rulers const int dist = 8; string captureWidth; string captureHeight; // The following fixes the very old incorrect size information bug if (_captureMode == CaptureMode.Window) { captureWidth = _captureRect.Width.ToString(CultureInfo.InvariantCulture); captureHeight = _captureRect.Height.ToString(CultureInfo.InvariantCulture); } else { captureWidth = (_captureRect.Width + 1).ToString(CultureInfo.InvariantCulture); captureHeight = (_captureRect.Height + 1).ToString(CultureInfo.InvariantCulture); } using (Font rulerFont = new Font(FontFamily.GenericSansSerif, 8)) { Size measureWidth = TextRenderer.MeasureText(captureWidth, rulerFont); Size measureHeight = TextRenderer.MeasureText(captureHeight, rulerFont); int hSpace = measureWidth.Width + 3; int vSpace = measureHeight.Height + 3; Brush bgBrush = new SolidBrush(Color.FromArgb(200, 217, 240, 227)); Pen rulerPen = new Pen(Color.SeaGreen); // horizontal ruler if (fixedRect.Width > hSpace + 3) { using (GraphicsPath p = RoundedRectangle.Create2( fixedRect.X + (fixedRect.Width / 2 - hSpace / 2) + 3, fixedRect.Y - dist - 7, measureWidth.Width - 3, measureWidth.Height, 3)) { graphics.FillPath(bgBrush, p); graphics.DrawPath(rulerPen, p); graphics.DrawString(captureWidth, rulerFont, rulerPen.Brush, fixedRect.X + (fixedRect.Width / 2 - hSpace / 2) + 3, fixedRect.Y - dist - 7); graphics.DrawLine(rulerPen, fixedRect.X, fixedRect.Y - dist, fixedRect.X + (fixedRect.Width / 2 - hSpace / 2), fixedRect.Y - dist); graphics.DrawLine(rulerPen, fixedRect.X + (fixedRect.Width / 2 + hSpace / 2), fixedRect.Y - dist, fixedRect.X + fixedRect.Width, fixedRect.Y - dist); graphics.DrawLine(rulerPen, fixedRect.X, fixedRect.Y - dist - 3, fixedRect.X, fixedRect.Y - dist + 3); graphics.DrawLine(rulerPen, fixedRect.X + fixedRect.Width, fixedRect.Y - dist - 3, fixedRect.X + fixedRect.Width, fixedRect.Y - dist + 3); } } // vertical ruler if (fixedRect.Height > vSpace + 3) { using (GraphicsPath p = RoundedRectangle.Create2( fixedRect.X - measureHeight.Width + 1, fixedRect.Y + (fixedRect.Height / 2 - vSpace / 2) + 2, measureHeight.Width - 3, measureHeight.Height - 1, 3)) { graphics.FillPath(bgBrush, p); graphics.DrawPath(rulerPen, p); graphics.DrawString(captureHeight, rulerFont, rulerPen.Brush, fixedRect.X - measureHeight.Width + 1, fixedRect.Y + (fixedRect.Height / 2 - vSpace / 2) + 2); graphics.DrawLine(rulerPen, fixedRect.X - dist, fixedRect.Y, fixedRect.X - dist, fixedRect.Y + (fixedRect.Height / 2 - vSpace / 2)); graphics.DrawLine(rulerPen, fixedRect.X - dist, fixedRect.Y + (fixedRect.Height / 2 + vSpace / 2), fixedRect.X - dist, fixedRect.Y + fixedRect.Height); graphics.DrawLine(rulerPen, fixedRect.X - dist - 3, fixedRect.Y, fixedRect.X - dist + 3, fixedRect.Y); graphics.DrawLine(rulerPen, fixedRect.X - dist - 3, fixedRect.Y + fixedRect.Height, fixedRect.X - dist + 3, fixedRect.Y + fixedRect.Height); } } rulerPen.Dispose(); bgBrush.Dispose(); } // Display size of selected rectangle // Prepare the font and text. using (Font sizeFont = new Font(FontFamily.GenericSansSerif, 12)) { // When capturing a Region we need to add 1 to the height/width for correction string sizeText; if (_captureMode == CaptureMode.Region) { // correct the GUI width to real width for the shown size sizeText = (_captureRect.Width + 1) + " x " + (_captureRect.Height + 1); } else { sizeText = _captureRect.Width + " x " + _captureRect.Height; } // Calculate the scaled font size. SizeF extent = graphics.MeasureString(sizeText, sizeFont); float hRatio = _captureRect.Height / (extent.Height * 2); float wRatio = _captureRect.Width / (extent.Width * 2); float ratio = (hRatio < wRatio ? hRatio : wRatio); float newSize = sizeFont.Size * ratio; if (newSize >= 4) { // Only show if 4pt or larger. if (newSize > 20) { newSize = 20; } // Draw the size. using (Font newSizeFont = new Font(FontFamily.GenericSansSerif, newSize, FontStyle.Bold)) { PointF sizeLocation = new PointF(fixedRect.X + (_captureRect.Width / 2) - (extent.Width / 2), fixedRect.Y + (_captureRect.Height / 2) - (newSizeFont.GetHeight() / 2)); graphics.DrawString(sizeText, newSizeFont, Brushes.LightSeaGreen, sizeLocation); } } } } else { if (!isTerminalServerSession) { using (Pen pen = new Pen(Color.LightSeaGreen)) { pen.DashStyle = DashStyle.Dot; Rectangle screenBounds = _capture.ScreenBounds; graphics.DrawLine(pen, _cursorPos.X, screenBounds.Y, _cursorPos.X, screenBounds.Height); graphics.DrawLine(pen, screenBounds.X, _cursorPos.Y, screenBounds.Width, _cursorPos.Y); } string xy = _cursorPos.X + " x " + _cursorPos.Y; using (Font f = new Font(FontFamily.GenericSansSerif, 8)) { Size xySize = TextRenderer.MeasureText(xy, f); using (GraphicsPath gp = RoundedRectangle.Create2(_cursorPos.X + 5, _cursorPos.Y + 5, xySize.Width - 3, xySize.Height, 3)) { using (Brush bgBrush = new SolidBrush(Color.FromArgb(200, 217, 240, 227))) { graphics.FillPath(bgBrush, gp); } using (Pen pen = new Pen(Color.SeaGreen)) { graphics.DrawPath(pen, gp); Point coordinatePosition = new Point(_cursorPos.X + 5, _cursorPos.Y + 5); graphics.DrawString(xy, f, pen.Brush, coordinatePosition); } } } } } // Zoom if (_zoomAnimator != null && (isAnimating(_zoomAnimator) || _captureMode != CaptureMode.Window)) { const int zoomSourceWidth = 25; const int zoomSourceHeight = 25; Rectangle sourceRectangle = new Rectangle(_cursorPos.X - (zoomSourceWidth / 2), _cursorPos.Y - (zoomSourceHeight / 2), zoomSourceWidth, zoomSourceHeight); Rectangle destinationRectangle = _zoomAnimator.Current; destinationRectangle.Offset(_cursorPos); DrawZoom(graphics, sourceRectangle, destinationRectangle); } }