aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Experiments/Tango.RemoteDesktop/Tango.ScreenCapture/BitBltScreenCapture.cs
blob: bd238638712dea37b002e1b107dbb7a04d4ca949 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Tango.ScreenCapture
{
    public class BitBltScreenCapture : IScreenCaptureMethod
    {
        #region Win32 API Screen shot calls

        // Win32 API calls necessary to support screen capture
        [DllImport("gdi32", EntryPoint = "BitBlt", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern int BitBlt(int hDestDC, int x, int y, int nWidth, int nHeight, int hSrcDC, int xSrc,
                                         int ySrc, int dwRop);

        [DllImport("user32", EntryPoint = "GetDC", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern int GetDC(int hwnd);

        [DllImport("user32", EntryPoint = "ReleaseDC", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern int ReleaseDC(int hwnd, int hdc);

        #endregion

        public Bitmap GetDesktopBitmap(CaptureRegion region)
        {
            const int SRCCOPY = 13369376;

            Bitmap bitmap = new Bitmap(region.Width, region.Height);

            using (Graphics g = Graphics.FromImage(bitmap))
            {
                // Get a device context to the windows desktop and our destination  bitmaps
                int hdcSrc = GetDC(0);
                IntPtr hdcDest = g.GetHdc();

                // Copy what is on the desktop to the bitmap
                BitBlt(hdcDest.ToInt32(), 0, 0, region.Width, region.Height, hdcSrc, 0, 0, SRCCOPY);

                // Release device contexts
                g.ReleaseHdc(hdcDest);
                ReleaseDC(0, hdcSrc);
            }

            return bitmap;
        }

        public void Dispose()
        {
            //Do nothing.
        }
    }
}
an>graphPolygon; protected int updateCounter; #endregion #region Cross Thread Fields protected GraphController _graphController; protected int _maxPoints; protected double _scaleFactor; protected Brush _stroke; protected Brush _fill; #endregion #region Properties /// <summary> /// Gets or sets the graph strokes color. /// </summary> public Brush Stroke { get { return (Brush)GetValue(StrokeProperty); } set { SetValue(StrokeProperty, value); } } public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register("Stroke", typeof(Brush), typeof(RealTimeGraphExReachLineScroll), new PropertyMetadata(Brushes.Black, new PropertyChangedCallback(CrossModelChanged))); /// <summary> /// Gets or sets the graph fill color. /// </summary> public Brush Fill { get { return (Brush)GetValue(FillProperty); } set { SetValue(FillProperty, value); } } public static readonly DependencyProperty FillProperty = DependencyProperty.Register("Fill", typeof(Brush), typeof(RealTimeGraphExReachLineScroll), new PropertyMetadata(null, new PropertyChangedCallback(CrossModelChanged))); /// <summary> /// Gets or sets the polygon used to render the graph. /// </summary> public Polygon Polygon { get { return (Polygon)GetValue(PolygonProperty); } set { SetValue(PolygonProperty, value); } } public static readonly DependencyProperty PolygonProperty = DependencyProperty.Register("Polygon", typeof(Polygon), typeof(RealTimeGraphExReachLineScroll), new PropertyMetadata(null, new PropertyChangedCallback(PolygonChanged))); private static void PolygonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = d as RealTimeGraphExReachLineScroll; if (control.Polygon != null) { control.gridLinesAndImageWrapperGrid.Children.Remove(control.Polygon); control.gridLinesAndImageWrapperGrid.Children.Add(control.Polygon); } } /// <summary> /// Gets or sets the IDataSeries used to push data points to the graph. /// </summary> public GraphController Controller { get { return (GraphController)GetValue(ControllerProperty); } set { SetValue(ControllerProperty, value); } } public static readonly DependencyProperty ControllerProperty = DependencyProperty.Register("Controller", typeof(GraphController), typeof(RealTimeGraphExReachLineScroll), new PropertyMetadata(null, new PropertyChangedCallback(GraphControllerChanged))); private static void GraphControllerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = d as RealTimeGraphExReachLineScroll; if (control.Controller != null) { control.Controller.RegisterMethods(control.ClearGraph, control.StartPushThread, control.SetPaused,control.ChangeRenderMode,null); control._graphController = control.Controller; } } #endregion #region Constructors public RealTimeGraphExReachLineScroll() : base() { graphPolygon = new ConcurrentpointsList(); } #endregion #region Override Methods protected override void Initialize() { base.Initialize(); if (Polygon == null) { Polygon = new System.Windows.Shapes.Polygon() { Tag = "Default" }; } gridLinesAndImageWrapperGrid.Children.Remove(img); if (!gridLinesAndImageWrapperGrid.Children.Contains(Polygon)) { gridLinesAndImageWrapperGrid.Children.Add(Polygon); } } protected override void OnSizeChanged(object sender, SizeChangedEventArgs e) { OnSetCrossThreadFields(); } protected override void OnSetCrossThreadFields() { base.OnSetCrossThreadFields(); this.Dispatcher.Invoke(() => { _maxPoints = MaxPoints; _scaleFactor = _width / _maxPoints; _graphController = Controller; _stroke = Stroke; _fill = Fill; if (Polygon.Tag != null && Polygon.Tag.ToString() == "Default") { Polygon.Fill = Fill; Polygon.Stroke = Stroke; } if (_graphController != null && _graphController.dataSeries != null && _graphController.dataSeries.useFillandStroke) { Polygon.Fill = _graphController.dataSeries.fill; Polygon.Stroke = _graphController.dataSeries.stroke; } if (this.GetType() == typeof(RealTimeGraphExReachLineScroll) || this.GetType() == typeof(RealTimeGraphExReachLineErase)) { Polygon.Margin = new Thickness(-2, 1, -2, 0); } }, DispatcherPriority.Send); } protected override void OnClearGraph() { base.OnClearGraph(); _graphController.dataSeries.ClearPoints(); graphPolygon.Clear(); this.Dispatcher.Invoke(() => { Polygon.Points.Clear(); }); } protected internal override void OnRenderGraph() { if (_graphController != null && _graphController.dataSeries.Points != null && _graphController.dataSeries.Points.Count > 0 && _width > 1 && _height > 1) { var points = _graphController.dataSeries.Points.GetAndClearAllPoints(); if (!_isPaused) { for (int i = 0; i < points.Count; i++) { double value = points[i]; graphPolygon.Add(value); xValueCounter += _scaleFactor; } if (graphPolygon.Count > _maxPoints + 1) { xValueCounter -= (_scaleFactor * (graphPolygon.Count - (_maxPoints + 1))); graphPolygon.RemoveFromStart(graphPolygon.Count - (_maxPoints + 1)); } } updateCounter++; if (updateCounter >= 1 && !_isPaused) { updateCounter = 0; if (!_disableRendering) { OnDrawVisuals(); } } } } protected override void OnZoomingComplete(Point transformOrigin, double scaleX, double scaleY) { base.OnZoomingComplete(transformOrigin, scaleX, scaleY); if (IsPaused) { OnDrawVisuals(); } } #endregion #region Virtual Methods /// <summary> /// Calculate the scaling factor for the current graph width. /// </summary> /// <returns></returns> protected virtual double GetPolygonScaleFactor() { return (_width + 3) / (graphPolygon.Count - 1); } /// <summary> /// Draw the actual polygon on the image. /// </summary> /// <param name="bmp"></param> protected virtual void OnDrawVisuals() { double scale = GetPolygonScaleFactor(); this.Dispatcher.Invoke(() => { Polygon.Points = new PointCollection(graphPolygon.ToReachPolygonPointsFill(_width, _height, scale, ConvertYToImageYFliped)); }, DispatcherPriority.Send); } #endregion } }