예제 #1
0
        private static Bitmap CaptureCursor(ref int x, ref int y)
        {
            Bitmap bmp;
            IntPtr hicon;

            User32.CURSORINFO ci = new User32.CURSORINFO();
            User32.ICONINFO   icInfo;
            ci.cbSize = Marshal.SizeOf(ci);
            if (User32.GetCursorInfo(out ci))
            {
                if (ci.flags == 1)
                {
                    hicon = User32.CopyIcon(ci.hCursor);
                    if (User32.GetIconInfo(hicon, out icInfo))
                    {
                        x = ci.ptScreenPos.x - ((int)icInfo.xHotspot);
                        y = ci.ptScreenPos.y - ((int)icInfo.yHotspot);

                        Icon ic = Icon.FromHandle(hicon);
                        bmp = ic.ToBitmap();
                        return(bmp);
                    }
                }
            }

            return(null);
        }
예제 #2
0
        /// <inheritdoc />
        public override void Draw(Graphics g)
        {
            CURSORINFO cursorInfo;

            cursorInfo.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
            if (User32.GetCursorInfo(out cursorInfo))
            {
                if (cursorInfo.flags == CursorState.CURSOR_SHOWING)
                {
                    // We need to get the icon to get the "Hotspot" (aka offset)
                    var hicon = User32.CopyIcon(cursorInfo.hCursor);
                    if (hicon != IntPtr.Zero)
                    {
                        if (User32.GetIconInfo(hicon, out var iconInfo))
                        {
                            // Calculate the positions, relative to the bounds of the image relative to the desktop.
                            var x = cursorInfo.ptScreenPos.X - DesktopBounds.Left;
                            var y = cursorInfo.ptScreenPos.Y - DesktopBounds.Top;
                            User32.DrawIconEx(g.GetHdc(), x - iconInfo.xHotspot, y - iconInfo.yHotspot, cursorInfo.hCursor, 0, 0, 0, IntPtr.Zero, 0x0003);
                            g.ReleaseHdc();
                        }
                        Gdi32.DeleteObject(iconInfo.hbmColor);
                        Gdi32.DeleteObject(iconInfo.hbmMask);
                    }
                    User32.DestroyIcon(hicon);
                }
                Gdi32.DeleteObject(cursorInfo.hCursor);
            }
        }
예제 #3
0
        public static Bitmap CaptureCursor(ref int x, ref int y)
        {
            CursorInfo ci;

            if (!User32.GetCursorInfo(out ci))
            {
                return(null);
            }

            if (ci.flags != User32.CURSOR_SHOWING)
            {
                return(null);
            }

            var hicon = User32.CopyIcon(ci.hCursor);

            IconInfo icInfo;

            if (!User32.GetIconInfo(hicon, out icInfo))
            {
                return(null);
            }

            x = ci.ptScreenPos.X - icInfo.xHotspot;
            y = ci.ptScreenPos.Y - icInfo.yHotspot;

            return(Icon.FromHandle(hicon).ToBitmap());
        }
예제 #4
0
        private static Bitmap CaptureScreen(int theX, int theY, int theWidth, int theHeight)
        {
            var aBitmap   = new Bitmap(theWidth, theHeight, PixelFormat.Format24bppRgb);
            var aGraphics = Graphics.FromImage(aBitmap);

            try
            {
                aGraphics.CopyFromScreen(theX, theY, 0, 0, aBitmap.Size, CopyPixelOperation.SourceCopy);

                User32.CURSORINFO aCursorInfo;
                aCursorInfo.cbSize = Marshal.SizeOf(typeof(User32.CURSORINFO));

                if (User32.GetCursorInfo(out aCursorInfo))
                {
                    // if the cursor is showing draw it on the screen shot
                    if (aCursorInfo.flags == User32.CURSOR_SHOWING)
                    {
                        // we need to get hotspot so we can draw the cursor in the correct position
                        var             aIconPointer = User32.CopyIcon(aCursorInfo.hCursor);
                        User32.ICONINFO aIconInfo;

                        if (User32.GetIconInfo(aIconPointer, out aIconInfo))
                        {
                            // calculate the correct position of the cursor
                            var aIconX = aCursorInfo.ptScreenPos.x - ((int)aIconInfo.xHotspot);
                            var aIconY = aCursorInfo.ptScreenPos.y - ((int)aIconInfo.yHotspot);

                            // draw the cursor icon on top of the captured screen image
                            User32.DrawIcon(aGraphics.GetHdc(), aIconX, aIconY, aCursorInfo.hCursor);

                            Gdi32.DeleteObject(aIconInfo.hbmMask);
                            Gdi32.DeleteObject(aIconInfo.hbmColor);
                            aGraphics.ReleaseHdc();
                        }

                        User32.DestroyIcon(aIconPointer);
                    }
                }
            }
            finally
            {
                aGraphics.Dispose();

                GC.Collect();
            }

            return(aBitmap);
        }
예제 #5
0
        /// <summary>
        /// This method will capture the current Cursor by using User32 Code
        /// </summary>
        /// <returns>A Capture Object with the Mouse Cursor information in it.</returns>
        public static ICapture CaptureCursor(ICapture capture)
        {
            LOG.Debug("Capturing the mouse cursor.");
            if (capture == null)
            {
                capture = new Capture();
            }
            int        x, y;
            CursorInfo cursorInfo = new CursorInfo();
            IconInfo   iconInfo;

            cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);
            if (User32.GetCursorInfo(out cursorInfo))
            {
                if (cursorInfo.flags == User32.CURSOR_SHOWING)
                {
                    using (SafeIconHandle safeIcon = User32.CopyIcon(cursorInfo.hCursor))
                    {
                        if (User32.GetIconInfo(safeIcon, out iconInfo))
                        {
                            Point cursorLocation = GetCursorLocation();
                            // Allign cursor location to Bitmap coordinates (instead of Screen coordinates)
                            x = cursorLocation.X - iconInfo.xHotspot - capture.ScreenBounds.X;
                            y = cursorLocation.Y - iconInfo.yHotspot - capture.ScreenBounds.Y;
                            // Set the location
                            capture.CursorLocation = new Point(x, y);

                            using (Icon icon = Icon.FromHandle(safeIcon.DangerousGetHandle()))
                            {
                                capture.Cursor = icon;
                            }

                            if (iconInfo.hbmMask != IntPtr.Zero)
                            {
                                DeleteObject(iconInfo.hbmMask);
                            }
                            if (iconInfo.hbmColor != IntPtr.Zero)
                            {
                                DeleteObject(iconInfo.hbmColor);
                            }
                        }
                    }
                }
            }
            return(capture);
        }
예제 #6
0
        static IntPtr GetIcon(Func <Point, Point> Transform, out Point Location)
        {
            Location = Point.Empty;

            var cursorInfo = new CursorInfo {
                cbSize = Marshal.SizeOf <CursorInfo>()
            };

            if (!User32.GetCursorInfo(ref cursorInfo))
            {
                return(IntPtr.Zero);
            }

            if (cursorInfo.flags != CursorShowing)
            {
                return(IntPtr.Zero);
            }

            var hIcon = User32.CopyIcon(cursorInfo.hCursor);

            if (hIcon == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }

            if (!User32.GetIconInfo(hIcon, out var icInfo))
            {
                return(IntPtr.Zero);
            }

            var hotspot = new Point(icInfo.xHotspot, icInfo.yHotspot);

            Location = new Point(cursorInfo.ptScreenPos.X - hotspot.X,
                                 cursorInfo.ptScreenPos.Y - hotspot.Y);

            if (Transform != null)
            {
                Location = Transform(Location);
            }

            Gdi32.DeleteObject(icInfo.hbmColor);
            Gdi32.DeleteObject(icInfo.hbmMask);

            return(hIcon);
        }
예제 #7
0
        public static List <Bitmap> ObtenerFotoPantallasConCursor()
        {
            List <Bitmap> fotosPantallas = new List <Bitmap>();

            foreach (System.Windows.Forms.Screen screen in System.Windows.Forms.Screen.AllScreens)
            {
                var bitmap = new Bitmap(screen.Bounds.Width, screen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    g.CopyFromScreen(screen.Bounds.X, screen.Bounds.Y, 0, 0, screen.Bounds.Size, CopyPixelOperation.SourceCopy);

                    User32.CURSORINFO cursorInfo;
                    cursorInfo.cbSize = Marshal.SizeOf(typeof(User32.CURSORINFO));

                    if (User32.GetCursorInfo(out cursorInfo))
                    {
                        // if the cursor is showing draw it on the screen shot
                        if (cursorInfo.flags == User32.CURSOR_SHOWING)
                        {
                            // we need to get hotspot so we can draw the cursor in the correct position
                            var             iconPointer = User32.CopyIcon(cursorInfo.hCursor);
                            User32.ICONINFO iconInfo;
                            int             iconX, iconY;

                            if (User32.GetIconInfo(iconPointer, out iconInfo))
                            {
                                // calculate the correct position of the cursor
                                iconX = cursorInfo.ptScreenPos.x - ((int)iconInfo.xHotspot);
                                iconY = cursorInfo.ptScreenPos.y - ((int)iconInfo.yHotspot);

                                // draw the cursor icon on top of the captured screen image
                                User32.DrawIcon(g.GetHdc(), iconX, iconY, cursorInfo.hCursor);

                                // release the handle created by call to g.GetHdc()
                                g.ReleaseHdc();
                            }
                        }
                    }
                }
                fotosPantallas.Add(bitmap);
            }
            return(fotosPantallas);
        }
예제 #8
0
        private Bitmap CaptureImage()
        {
            Bitmap b = new Bitmap(Width, Height - 23, quality);

            using (Graphics g = Graphics.FromImage(b))
            {
                g.CopyFromScreen(Left, Top, 0, 0, new Size(Width, Height - 23), CopyPixelOperation.SourceCopy);
                User32.CURSORINFO cursorInfo;
                cursorInfo.cbSize = Marshal.SizeOf(typeof(User32.CURSORINFO));

                if (User32.GetCursorInfo(out cursorInfo))
                {
                    // if the cursor is showing draw it on the screen shot
                    if (cursorInfo.flags == User32.CURSOR_SHOWING)
                    {
                        // we need to get hotspot so we can draw the cursor in the correct position
                        var             iconPointer = User32.CopyIcon(cursorInfo.hCursor);
                        User32.ICONINFO iconInfo;
                        int             iconX, iconY;

                        if (User32.GetIconInfo(iconPointer, out iconInfo))
                        {
                            // calculate the correct position of the cursor
                            iconX = cursorInfo.ptScreenPos.x - ((int)iconInfo.xHotspot) - this.Left;
                            iconY = cursorInfo.ptScreenPos.y - ((int)iconInfo.yHotspot) - this.Top;

                            // draw the cursor icon on top of the captured screen image
                            User32.DrawIcon(g.GetHdc(), iconX, iconY, cursorInfo.hCursor);

                            // release the handle created by call to g.GetHdc()
                            g.ReleaseHdc();
                        }
                    }
                }
            }
            return(b);
        }
예제 #9
0
    private void FallbackCursorCapture(FrameInfo frame)
    {
        //if (_justStarted && (CursorShapeBuffer?.Length ?? 0) == 0)
        {
            //_justStarted = false;

            //https://stackoverflow.com/a/6374151/1735672
            //Bitmap struct, is used to get the cursor shape when SharpDX fails to do so.
            var infoHeader = new BitmapInfoHeader();
            infoHeader.biSize         = (uint)Marshal.SizeOf(infoHeader);
            infoHeader.biBitCount     = 32;
            infoHeader.biClrUsed      = 0;
            infoHeader.biClrImportant = 0;
            infoHeader.biCompression  = 0;
            infoHeader.biHeight       = -Height; //Negative, so the Y-axis will be positioned correctly.
            infoHeader.biWidth        = Width;
            infoHeader.biPlanes       = 1;

            try
            {
                var cursorInfo = new CursorInfo();
                cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);

                if (!User32.GetCursorInfo(out cursorInfo))
                {
                    return;
                }

                if (cursorInfo.flags == Native.Constants.CursorShowing)
                {
                    var hicon = User32.CopyIcon(cursorInfo.hCursor);

                    if (hicon != IntPtr.Zero)
                    {
                        if (User32.GetIconInfo(hicon, out var iconInfo))
                        {
                            frame.CursorX = cursorInfo.ptScreenPos.X - Left;
                            frame.CursorY = cursorInfo.ptScreenPos.Y - Top;

                            var bitmap      = new Bitmap();
                            var hndl        = GCHandle.Alloc(bitmap, GCHandleType.Pinned);
                            var ptrToBitmap = hndl.AddrOfPinnedObject();
                            Gdi32.GetObject(iconInfo.hbmColor, Marshal.SizeOf <Bitmap>(), ptrToBitmap);
                            bitmap = Marshal.PtrToStructure <Bitmap>(ptrToBitmap);
                            hndl.Free();

                            //https://microsoft.public.vc.mfc.narkive.com/H1CZeqUk/how-can-i-get-bitmapinfo-object-from-bitmap-or-hbitmap
                            infoHeader.biHeight   = bitmap.bmHeight;
                            infoHeader.biWidth    = bitmap.bmWidth;
                            infoHeader.biBitCount = (ushort)bitmap.bmBitsPixel;

                            var w = (bitmap.bmWidth * bitmap.bmBitsPixel + 31) / 8;
                            CursorShapeBuffer = new byte[w * bitmap.bmHeight];

                            var windowDeviceContext = User32.GetWindowDC(IntPtr.Zero);
                            var compatibleBitmap    = Gdi32.CreateCompatibleBitmap(windowDeviceContext, Width, Height);

                            Gdi32.GetDIBits(windowDeviceContext, compatibleBitmap, 0, (uint)infoHeader.biHeight, CursorShapeBuffer, ref infoHeader, DibColorModes.RgbColors);

                            //CursorShapeInfo = new OutputDuplicatePointerShapeInformation();
                            //CursorShapeInfo.Type = (int)OutputDuplicatePointerShapeType.Color;
                            //CursorShapeInfo.Width = bitmap.bmWidth;
                            //CursorShapeInfo.Height = bitmap.bmHeight;
                            //CursorShapeInfo.Pitch = w;
                            //CursorShapeInfo.HotSpot = new RawPoint(0, 0);

                            //if (frame.CursorX > 0 && frame.CursorY > 0)
                            //    Native.DrawIconEx(_compatibleDeviceContext, frame.CursorX - iconInfo.xHotspot, frame.CursorY - iconInfo.yHotspot, cursorInfo.hCursor, 0, 0, 0, IntPtr.Zero, 0x0003);

                            //Native.SelectObject(CompatibleDeviceContext, OldBitmap);
                            //Native.DeleteObject(compatibleBitmap);
                            //Native.DeleteDC(CompatibleDeviceContext);
                            //Native.ReleaseDC(IntPtr.Zero, windowDeviceContext);
                        }

                        Gdi32.DeleteObject(iconInfo.hbmColor);
                        Gdi32.DeleteObject(iconInfo.hbmMask);
                    }

                    User32.DestroyIcon(hicon);
                }

                Gdi32.DeleteObject(cursorInfo.hCursor);
            }
            catch (Exception e)
            {
                LogWriter.Log(e, "Impossible to get the cursor");
            }
        }
    }
예제 #10
0
        /// <summary>
        /// Captures the cursor as bitmap and returns the bitmap and the position on screen of the cursor.
        /// </summary>
        public static Bitmap CaptureCursor(ref Point position)
        {
            var cursorInfo = new CURSORINFO();

            cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);
            if (!User32.GetCursorInfo(out cursorInfo))
            {
                return(null);
            }

            if (cursorInfo.flags != CursorState.CURSOR_SHOWING)
            {
                return(null);
            }

            var hicon = User32.CopyIcon(cursorInfo.hCursor);

            if (hicon == IntPtr.Zero)
            {
                return(null);
            }

            if (!User32.GetIconInfo(hicon, out var iconInfo))
            {
                return(null);
            }

            // Calculate the position respecting the hotspot offset
            position.X = cursorInfo.ptScreenPos.X - iconInfo.xHotspot;
            position.Y = cursorInfo.ptScreenPos.Y - iconInfo.yHotspot;

            using (var maskBitmap = Image.FromHbitmap(iconInfo.hbmMask))
            {
                // Special handling for monchome icons
                if (maskBitmap.Height == maskBitmap.Width * 2)
                {
                    var cursor = new Bitmap(maskBitmap.Width, maskBitmap.Width, PixelFormat.Format32bppArgb);
                    var black  = Color.FromArgb(255, 0, 0, 0);       //cannot compare Color.Black because of different names
                    var white  = Color.FromArgb(255, 255, 255, 255); //cannot compare Color.White because of different names
                    for (var y = 0; y < maskBitmap.Width; y++)
                    {
                        for (var x = 0; x < maskBitmap.Width; x++)
                        {
                            var maskPixel   = maskBitmap.GetPixel(x, y);
                            var cursorPixel = maskBitmap.GetPixel(x, y + maskBitmap.Width);
                            if (maskPixel == white && cursorPixel == black)
                            {
                                cursor.SetPixel(x, y, Color.Transparent);
                            }
                            else if (maskPixel == black)
                            {
                                cursor.SetPixel(x, y, cursorPixel);
                            }
                            else
                            {
                                cursor.SetPixel(x, y, cursorPixel == black ? white : black);
                            }
                        }
                    }
                    return(cursor);
                }
            }

            // Just return the icon converted to a bitmap
            var icon = Icon.FromHandle(hicon);

            return(icon.ToBitmap());
        }
예제 #11
0
    public override int CaptureWithCursor(FrameInfo frame)
    {
        try
        {
            //var success = Native.BitBlt(CompatibleDeviceContext, 0, 0, Width, Height, WindowDeviceContext, Left, Top, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
            var success = Gdi32.StretchBlt(CompatibleDeviceContext, 0, 0, StartWidth, StartHeight, WindowDeviceContext, Left, Top, Width, Height, PixelOperations);

            if (!success)
            {
                return(FrameCount);
            }

            #region Cursor

            try
            {
                var cursorInfo = new CursorInfo();
                cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);

                if (User32.GetCursorInfo(out cursorInfo))
                {
                    if (cursorInfo.flags == Native.Constants.CursorShowing)
                    {
                        var hicon = User32.CopyIcon(cursorInfo.hCursor);

                        if (hicon != IntPtr.Zero)
                        {
                            if (User32.GetIconInfo(hicon, out var iconInfo))
                            {
                                frame.CursorX = cursorInfo.ptScreenPos.X - Left;
                                frame.CursorY = cursorInfo.ptScreenPos.Y - Top;

                                //(int)(SystemParameters.CursorHeight * Scale)
                                //(int)(SystemParameters.CursorHeight * Scale)

                                var ok = User32.DrawIconEx(CompatibleDeviceContext, frame.CursorX - iconInfo.xHotspot, frame.CursorY - iconInfo.yHotspot, cursorInfo.hCursor, 0, 0, CursorStep, IntPtr.Zero, 0x0003);

                                if (!ok)
                                {
                                    CursorStep = 0;
                                    User32.DrawIconEx(CompatibleDeviceContext, frame.CursorX - iconInfo.xHotspot, frame.CursorY - iconInfo.yHotspot, cursorInfo.hCursor, 0, 0, CursorStep, IntPtr.Zero, 0x0003);
                                }
                                else
                                {
                                    CursorStep++;
                                }
                            }

                            Gdi32.DeleteObject(iconInfo.hbmColor);
                            Gdi32.DeleteObject(iconInfo.hbmMask);
                        }

                        User32.DestroyIcon(hicon);
                    }

                    Gdi32.DeleteObject(cursorInfo.hCursor);
                }
            }
            catch (Exception)
            {
                //LogWriter.Log(e, "Impossible to get the cursor");
            }

            #endregion

            //Set frame details.
            FrameCount++;
            frame.Path  = $"{Project.FullPath}{FrameCount}.png";
            frame.Delay = FrameRate.GetMilliseconds();
            frame.Image = Image.FromHbitmap(CompatibleBitmap);

            if (IsAcceptingFrames)
            {
                BlockingCollection.Add(frame);
            }
        }
        catch (Exception)
        {
            //LogWriter.Log(ex, "Impossible to get the screenshot of the screen");
        }

        return(FrameCount);
    }
예제 #12
0
        static void GetIcon(Func <Point, Point> Transform, out Bitmap Icon, out Point Location)
        {
            Icon     = null;
            Location = Point.Empty;

            // ReSharper disable once RedundantAssignment
            // ReSharper disable once InlineOutVariableDeclaration
            var cursorInfo = new CursorInfo {
                cbSize = Marshal.SizeOf <CursorInfo>()
            };

            if (!User32.GetCursorInfo(out cursorInfo))
            {
                return;
            }

            if (cursorInfo.flags != CursorShowing)
            {
                return;
            }

            Point hotspot;

            if (Cursors.ContainsKey(cursorInfo.hCursor))
            {
                var tuple = Cursors[cursorInfo.hCursor];

                Icon    = tuple.Item1;
                hotspot = tuple.Item2;
            }
            else
            {
                var hIcon = User32.CopyIcon(cursorInfo.hCursor);

                if (hIcon == IntPtr.Zero)
                {
                    return;
                }

                if (!User32.GetIconInfo(hIcon, out var icInfo))
                {
                    return;
                }

                Icon    = System.Drawing.Icon.FromHandle(hIcon).ToBitmap();
                hotspot = new Point(icInfo.xHotspot, icInfo.yHotspot);

                Cursors.Add(cursorInfo.hCursor, Tuple.Create(Icon, hotspot));

                User32.DestroyIcon(hIcon);

                Gdi32.DeleteObject(icInfo.hbmColor);
                Gdi32.DeleteObject(icInfo.hbmMask);
            }

            Location = new Point(cursorInfo.ptScreenPos.X - hotspot.X,
                                 cursorInfo.ptScreenPos.Y - hotspot.Y);

            if (Transform != null)
            {
                Location = Transform(Location);
            }
        }
예제 #13
0
        public static System.Drawing.Bitmap CaptureImageCursor(ref System.Windows.Point point, double scale)
        {
            try
            {
                var cursorInfo = new CursorInfo();
                cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);

                if (!User32.GetCursorInfo(out cursorInfo))
                {
                    return(null);
                }

                if (cursorInfo.flags != Constants.CursorShowing)
                {
                    return(null);
                }

                var hicon = User32.CopyIcon(cursorInfo.hCursor);
                if (hicon == IntPtr.Zero)
                {
                    return(null);
                }

                if (!User32.GetIconInfo(hicon, out var iconInfo))
                {
                    Gdi32.DeleteObject(hicon);
                    return(null);
                }

                point.X = cursorInfo.ptScreenPos.X - iconInfo.xHotspot;
                point.Y = cursorInfo.ptScreenPos.Y - iconInfo.yHotspot;

                using (var maskBitmap = Image.FromHbitmap(iconInfo.hbmMask))
                {
                    //Is this a monochrome cursor?
                    if (maskBitmap.Height == maskBitmap.Width * 2 && iconInfo.hbmColor == IntPtr.Zero)
                    {
                        var final     = new System.Drawing.Bitmap(maskBitmap.Width, maskBitmap.Width);
                        var hDesktop  = User32.GetDesktopWindow();
                        var dcDesktop = User32.GetWindowDC(hDesktop);

                        using (var resultGraphics = Graphics.FromImage(final))
                        {
                            var resultHdc = resultGraphics.GetHdc();
                            var offsetX   = (int)((point.X + 3) * scale);
                            var offsetY   = (int)((point.Y + 3) * scale);

                            Gdi32.BitBlt(resultHdc, 0, 0, final.Width, final.Height, dcDesktop, offsetX, offsetY, CopyPixelOperations.SourceCopy);
                            User32.DrawIconEx(resultHdc, 0, 0, cursorInfo.hCursor, 0, 0, 0, IntPtr.Zero, 0x0003);

                            //TODO: I have to try removing the background of this cursor capture.
                            //Gdi32.BitBlt(resultHdc, 0, 0, final.Width, final.Height, dcDesktop, (int)point.X + 3, (int)point.Y + 3, CopyPixelOperations.SourceErase);

                            //Original, ignores the screen as background.
                            //Gdi32.BitBlt(resultHdc, 0, 0, resultBitmap.Width, resultBitmap.Height, maskHdc, 0, resultBitmap.Height, CopyPixelOperations.SourceCopy); //SourceCopy
                            //Gdi32.BitBlt(resultHdc, 0, 0, resultBitmap.Width, resultBitmap.Height, maskHdc, 0, 0, CopyPixelOperations.PatInvert); //SourceInvert

                            resultGraphics.ReleaseHdc(resultHdc);
                            User32.ReleaseDC(hDesktop, dcDesktop);
                        }

                        Gdi32.DeleteObject(iconInfo.hbmMask);
                        Gdi32.DeleteDC(dcDesktop);

                        return(final);
                    }

                    Gdi32.DeleteObject(iconInfo.hbmColor);
                    Gdi32.DeleteObject(iconInfo.hbmMask);
                    Gdi32.DeleteObject(hicon);
                }

                var icon = Icon.FromHandle(hicon);
                return(icon.ToBitmap());
            }
            catch (Exception ex)
            {
                LogWriter.Log(ex, "Impossible to get the cursor.");
            }

            return(null);
        }
예제 #14
0
    public override int CaptureWithCursor(FrameInfo frame)
    {
        try
        {
            //var success = Native.BitBlt(CompatibleDeviceContext, 0, 0, Width, Height, WindowDeviceContext, Left, Top, Native.CopyPixelOperation.SourceCopy | Native.CopyPixelOperation.CaptureBlt);
            var success = Gdi32.StretchBlt(CompatibleDeviceContext, 0, 0, StartWidth, StartHeight, WindowDeviceContext, Left, Top, Width, Height, CopyPixelOperations.SourceCopy | CopyPixelOperations.CaptureBlt);

            if (!success)
            {
                return(FrameCount);
            }

            #region Cursor

            try
            {
                var cursorInfo = new CursorInfo();
                cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);

                if (User32.GetCursorInfo(out cursorInfo))
                {
                    if (cursorInfo.flags == Native.Constants.CursorShowing)
                    {
                        var hicon = User32.CopyIcon(cursorInfo.hCursor);

                        if (hicon != IntPtr.Zero)
                        {
                            if (User32.GetIconInfo(hicon, out var iconInfo))
                            {
                                frame.CursorX = cursorInfo.ptScreenPos.X - Left;
                                frame.CursorY = cursorInfo.ptScreenPos.Y - Top;

                                //If the cursor rate needs to be precisely captured.
                                //https://source.winehq.org/source/dlls/user32/cursoricon.c#2325
                                //int rate = 0, num = 0;
                                //var ok1 = Native.GetCursorFrameInfo(cursorInfo.hCursor, IntPtr.Zero, 17, ref rate, ref num);

                                //CursorStep
                                var ok = User32.DrawIconEx(CompatibleDeviceContext, frame.CursorX - iconInfo.xHotspot, frame.CursorY - iconInfo.yHotspot, cursorInfo.hCursor, 0, 0, CursorStep, IntPtr.Zero, 0x0003);

                                if (!ok)
                                {
                                    CursorStep = 0;
                                    User32.DrawIconEx(CompatibleDeviceContext, frame.CursorX - iconInfo.xHotspot, frame.CursorY - iconInfo.yHotspot, cursorInfo.hCursor, 0, 0, CursorStep, IntPtr.Zero, 0x0003);
                                }
                                else
                                {
                                    CursorStep++;
                                }

                                //Set to fix all alpha bits back to 255.
                                //frame.RemoveAnyTransparency = iconInfo.hbmMask != IntPtr.Zero;
                            }

                            Gdi32.DeleteObject(iconInfo.hbmColor);
                            Gdi32.DeleteObject(iconInfo.hbmMask);
                        }

                        User32.DestroyIcon(hicon);
                    }

                    Gdi32.DeleteObject(cursorInfo.hCursor);
                }
            }
            catch (Exception e)
            {
                //LogWriter.Log(e, "Impossible to get the cursor");
            }

            #endregion

            //Set frame details.
            FrameCount++;
            frame.Path       = $"{Project.FullPath}{FrameCount}.png";
            frame.Delay      = FrameRate.GetMilliseconds();
            frame.DataLength = _byteLength;
            frame.Data       = new byte[_byteLength];

            if (Gdi32.GetDIBits(WindowDeviceContext, CompatibleBitmap, 0, (uint)StartHeight, frame.Data, ref _infoHeader, DibColorModes.RgbColors) == 0)
            {
                frame.FrameSkipped = true;
            }

            if (IsAcceptingFrames)
            {
                BlockingCollection.Add(frame);
            }
        }
        catch (Exception e)
        {
            //LogWriter.Log(ex, "Impossible to get the screenshot of the screen");
        }

        return(FrameCount);
    }
예제 #15
0
        private static void draw_mouse_pointer(Bitmap screen_bitmap, Graphics graphics)
        {
            // Fill the cursor info struct
            var cursor_info = User32.GetCursorInfo();

            // Check if the cursor is visible
            if (cursor_info.flags != WinConst.CURSOR_SHOWING)
            {
                // it is not visible - do nothing
                return;
            }

            // Retrieve the icon being used for the cursor
            using (var icon_handle = User32.CopyIcon(cursor_info.hCursor))
            {
                var iconinfo = User32.GetIconInfo(icon_handle);

                int icon_left = cursor_info.ptScreenPos.x - iconinfo.xHotspot;
                int icon_top  = cursor_info.ptScreenPos.y - iconinfo.yHotspot;

                try
                {
                    using (var icon = Icon.FromHandle(icon_handle.DangerousGetHandle()))
                    {
                        if ((iconinfo.hbmColor != IntPtr.Zero))
                        {
                            // this is a "normal" bitmap so just draw the icon
                            graphics.DrawIcon(icon, icon_left, icon_top);
                        }
                        else if ((iconinfo.hbmColor == IntPtr.Zero) && (iconinfo.hbmMask != IntPtr.Zero))
                        {
                            // or draw the mask manually
                            using (var bmp_mask = Bitmap.FromHbitmap(iconinfo.hbmMask))
                            {
                                if (bmp_mask.Height != icon.Height * 2)
                                {
                                    throw new Exception("mask does not have expected height - should be twice the icon height");
                                }

                                var r2 = new Rectangle(icon_left, icon_top, icon.Width, icon.Height);
                                using (var bmp_temp = DrawingUtil.CopyBitmap(screen_bitmap, r2))
                                {
                                    for (int x = 0; x < icon.Width; x++)
                                    {
                                        for (int y = 0; y < icon.Height; y++)
                                        {
                                            var mask_color = bmp_mask.GetPixel(x, y);
                                            if (mask_color.R == 0)
                                            {
                                                var final_color = mask_color;
                                                bmp_temp.SetPixel(x, y, final_color);
                                            }
                                        }
                                    }


                                    for (int x = 0; x < icon.Width; x++)
                                    {
                                        for (int y = 0; y < icon.Height; y++)
                                        {
                                            var original_screen_color = bmp_temp.GetPixel(x, y);
                                            var mask_color            = bmp_mask.GetPixel(x, y + icon.Height);
                                            if (mask_color.R != 0)
                                            {
                                                int new_red     = original_screen_color.R ^ 0xff;
                                                int new_green   = original_screen_color.G ^ 0xff;
                                                int new_blue    = original_screen_color.B ^ 0xff;
                                                var final_color = System.Drawing.Color.FromArgb(new_red, new_green,
                                                                                                new_blue);
                                                bmp_temp.SetPixel(x, y, final_color);
                                            }
                                        }
                                    }

                                    graphics.DrawImage(bmp_temp, icon_left, icon_top);
                                }
                            }
                        }
                        else
                        {
                            throw new CaptureException("Unhandled case");
                        }
                    }
                }
                finally
                {
                    if (iconinfo.hbmColor != IntPtr.Zero)
                    {
                        Gdi32.DeleteObject(iconinfo.hbmColor);
                    }

                    if (iconinfo.hbmMask != IntPtr.Zero)
                    {
                        Gdi32.DeleteObject(iconinfo.hbmMask);
                    }
                }
            }
        }
예제 #16
0
        /// <summary>
        /// Draws this overlay.
        /// </summary>
        /// <param name="G">A <see cref="Graphics"/> object to draw upon.</param>
        /// <param name="Transform">Point Transform Function.</param>
        public static void Draw(Graphics G, Func <Point, Point> Transform = null)
        {
            // ReSharper disable once RedundantAssignment
            // ReSharper disable once InlineOutVariableDeclaration
            var cursorInfo = new CursorInfo {
                cbSize = Marshal.SizeOf <CursorInfo>()
            };

            if (!User32.GetCursorInfo(out cursorInfo))
            {
                return;
            }

            if (cursorInfo.flags != CursorShowing)
            {
                return;
            }

            Bitmap icon;
            Point  hotspot;

            if (Cursors.ContainsKey(cursorInfo.hCursor))
            {
                var tuple = Cursors[cursorInfo.hCursor];

                icon    = tuple.Item1;
                hotspot = tuple.Item2;
            }
            else
            {
                var hIcon = User32.CopyIcon(cursorInfo.hCursor);

                if (hIcon == IntPtr.Zero)
                {
                    return;
                }

                if (!User32.GetIconInfo(hIcon, out var icInfo))
                {
                    return;
                }

                icon    = Icon.FromHandle(hIcon).ToBitmap();
                hotspot = new Point(icInfo.xHotspot, icInfo.yHotspot);

                Cursors.Add(cursorInfo.hCursor, Tuple.Create(icon, hotspot));

                User32.DestroyIcon(hIcon);

                Gdi32.DeleteObject(icInfo.hbmColor);
                Gdi32.DeleteObject(icInfo.hbmMask);
            }

            var location = new Point(cursorInfo.ptScreenPos.X - hotspot.X,
                                     cursorInfo.ptScreenPos.Y - hotspot.Y);

            if (Transform != null)
            {
                location = Transform(location);
            }

            try
            {
                G.DrawImage(icon, new Rectangle(location, icon.Size));
            }
            catch (ArgumentException) { }
        }