zoukankan      html  css  js  c++  java
  • C# 全屏坐标及区域坐标获取。自定义光标及系统光标描边捕捉显示。

       最近手头工作比较轻松了一点就继续研究和完善之前的录屏软件,使用AForge最大的问题在于:最原始的只能够录全屏,而自定义的录屏需要更改非常多的细节:like follows:

    1、需要支持区域化录屏;

    2、需要支持麦克风录音,并且混音在视频中,同步;

    3、需要支持系统声音录取、并且需要混音在视频中,同步;

    4、需要支持捕获光标,并且自定义颜色、描边,最重要的是你需要在区域录屏的时候支持坐标位置更新(相对比较难);

       前面3个已经在前面的文章介绍了,这里不再赘述。着重列出第4点的内容以及如何解决。如果正在研究录屏这块的朋友们,千万别去copy那什么网上有限制时间录制和收费的录制,特别是有些很恶心的还发表长篇大论写的如何如何实现(的确技术不可否认是实现了),其实最后还是要你付费才能完全使用,就问你恶不恶心!

       好了,废话不多说,我们来一一解决;

    首先获取系统光标有两种方式,第一种是直接通过系统API进行获取光标,这个是完全记录系统光标在做什么。随着系统光标变化而变化的。这边有用到的是几个类:

    第一种方式:【CursorHelper.cs】、【GDIStuff.cs】、【Win32Stuff.cs】相对复杂一些;我就在代码中直接显示就好了,不需要引用任何其他的东西;

        /// <summary>
        ///     The rt global cursor.
        /// </summary>
        public class CursorHelper
        {
            #region Constants
    
            /// <summary>
            ///     The curso r_ showing.
            /// </summary>
            private const int CURSOR_SHOWING = 1;
    
            #endregion
    
            #region Public Methods and Operators
    
            /// <summary>
            /// The capture cursor.
            /// </summary>
            /// <param name="x">
            /// The x.
            /// </param>
            /// <param name="y">
            /// The y.
            /// </param>
            /// <returns>
            /// The <see cref="Bitmap"/>.
            /// </returns>
            public static Bitmap CaptureCursor(ref int x, ref int y)
            {
                Win32Stuff.CURSORINFO cursorInfo = new Win32Stuff.CURSORINFO();
                cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);
                if (!Win32Stuff.GetCursorInfo(out cursorInfo))
                {
                    return null;
                }
    
                if (cursorInfo.flags != Win32Stuff.CURSOR_SHOWING)
                {
                    return null;
                }
    
                IntPtr hicon = Win32Stuff.CopyIcon(cursorInfo.hCursor);
                if (hicon == IntPtr.Zero)
                {
                    return null;
                }
    
                Win32Stuff.ICONINFO iconInfo;
                if (!Win32Stuff.GetIconInfo(hicon, out iconInfo))
                {
                    return null;
                }
    
                x = cursorInfo.ptScreenPos.x - ((int)iconInfo.xHotspot);
                y = cursorInfo.ptScreenPos.y - ((int)iconInfo.yHotspot);
    
                using (Bitmap maskBitmap = Bitmap.FromHbitmap(iconInfo.hbmMask))
                {
                    // Is this a monochrome cursor?
                    if (maskBitmap.Height == maskBitmap.Width * 2)
                    {
                        Bitmap resultBitmap = new Bitmap(maskBitmap.Width, maskBitmap.Width);
    
                        using (Graphics desktopGraphics = Graphics.FromHwnd(Win32Stuff.GetDesktopWindow()))
                        {
                            IntPtr desktopHdc = desktopGraphics.GetHdc();
    
                            IntPtr maskHdc = GDIStuff.CreateCompatibleDC(desktopHdc);
                            IntPtr oldPtr = GDIStuff.SelectObject(maskHdc, maskBitmap.GetHbitmap());
    
                            using (Graphics resultGraphics = Graphics.FromImage(resultBitmap))
                            {
                                IntPtr resultHdc = resultGraphics.GetHdc();
    
                                // These two operation will result in a black cursor over a white background.
                                // Later in the code, a call to MakeTransparent() will get rid of the white background.
                                GDIStuff.BitBlt(
                                    resultHdc,
                                    0,
                                    0,
                                    32,
                                    32,
                                    maskHdc,
                                    0,
                                    32,
                                    (int)GDIStuff.TernaryRasterOperations.SRCCOPY);
                                GDIStuff.BitBlt(
                                    resultHdc,
                                    0,
                                    0,
                                    32,
                                    32,
                                    maskHdc,
                                    0,
                                    0,
                                    (int)GDIStuff.TernaryRasterOperations.SRCINVERT);
    
                                resultGraphics.ReleaseHdc(resultHdc);
                                GDIStuff.DeleteDC(resultHdc);
                                GDIStuff.DeleteObject(resultHdc);
                            }
    
                            IntPtr newPtr = GDIStuff.SelectObject(maskHdc, oldPtr);
                            GDIStuff.DeleteObject(oldPtr);
                            GDIStuff.DeleteObject(newPtr);
                            GDIStuff.DeleteDC(maskHdc);
                            desktopGraphics.ReleaseHdc(desktopHdc);
                            GDIStuff.DeleteDC(desktopHdc);
                        }
                        
                        // Remove the white background from the BitBlt calls,
                        // resulting in a black cursor over a transparent background.
                        resultBitmap.MakeTransparent(Color.White);
                        return resultBitmap;
                    }
                }
    
                //// Delete the mask, if present.
                // if (iconInfo.hbmMask != IntPtr.Zero)
                // {
                // DeleteObject(iconInfo.hbmMask);
                // }
    
                //// Delete the color bitmap, if present.
                // if (iconInfo.hbmColor != IntPtr.Zero)
                // {
                // DeleteObject(iconInfo.hbmColor);
                // }
                using (Icon icon = Icon.FromHandle(hicon))
                {
                    return icon.ToBitmap();
                }
            }
    
            #endregion
    
            #region Methods
    
            /// <summary>
            /// The copy icon.
            /// </summary>
            /// <param name="hIcon">
            /// The h icon.
            /// </param>
            /// <returns>
            /// The <see cref="IntPtr"/>.
            /// </returns>
            [DllImport("user32.dll")]
            private static extern IntPtr CopyIcon(IntPtr hIcon);
    
            /// <summary>
            /// The delete object.
            /// </summary>
            /// <param name="hDc">
            /// The h dc.
            /// </param>
            /// <returns>
            /// The <see cref="IntPtr"/>.
            /// </returns>
            [DllImport("gdi32.dll")]
            private static extern IntPtr DeleteObject(IntPtr hDc);
    
            /// <summary>
            /// The destroy icon.
            /// </summary>
            /// <param name="hIcon">
            /// The h icon.
            /// </param>
            /// <returns>
            /// The <see cref="bool"/>.
            /// </returns>
            [DllImport("user32.dll")]
            private static extern bool DestroyIcon(IntPtr hIcon);
    
            /// <summary>
            /// The get cursor info.
            /// </summary>
            /// <param name="pci">
            /// The pci.
            /// </param>
            /// <returns>
            /// The <see cref="bool"/>.
            /// </returns>
            [DllImport("user32.dll")]
            private static extern bool GetCursorInfo(out CURSORINFO pci);
    
            /// <summary>
            ///     The get gdi handle count.
            /// </summary>
            /// <returns>
            ///     The <see cref="int" />.
            /// </returns>
            private static int GetGDIHandleCount()
            {
                return GetGuiResources(Process.GetCurrentProcess().Handle, 0);
            }
    
            /// <summary>
            /// The get gui resources.
            /// </summary>
            /// <param name="hProcess">
            /// The h process.
            /// </param>
            /// <param name="uiFlags">
            /// The ui flags.
            /// </param>
            /// <returns>
            /// The <see cref="int"/>.
            /// </returns>
            [DllImport("user32.dll")]
            private static extern int GetGuiResources(IntPtr hProcess, int uiFlags);
    
            /// <summary>
            /// The get icon info.
            /// </summary>
            /// <param name="hIcon">
            /// The h icon.
            /// </param>
            /// <param name="piconinfo">
            /// The piconinfo.
            /// </param>
            /// <returns>
            /// The <see cref="bool"/>.
            /// </returns>
            [DllImport("user32.dll")]
            private static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo);
    
            /// <summary>
            ///     The get user handle count.
            /// </summary>
            /// <returns>
            ///     The <see cref="int" />.
            /// </returns>
            private static int GetUserHandleCount()
            {
                return GetGuiResources(Process.GetCurrentProcess().Handle, 1);
            }
    
            /// <summary>
            /// The handle message.
            /// </summary>
            /// <param name="message">
            /// The message.
            /// </param>
            private static void HandleMessage(string message)
            {
                Debug.WriteLine("HC: " + message + ": GDI: " + GetGDIHandleCount() + ": User: " + GetUserHandleCount());
            }
    
            #endregion
    
            /// <summary>
            ///     The cursorinfo.
            /// </summary>
            [StructLayout(LayoutKind.Sequential)]
            private struct CURSORINFO
            {
                // Fields
                /// <summary>
                ///     The cb size.
                /// </summary>
                [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here."),
                SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
                public int cbSize;
    
                /// <summary>
                ///     The flags.
                /// </summary>
                [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here."),
                SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
                public int flags;
    
                /// <summary>
                ///     The h cursor.
                /// </summary>
                [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here."),
                SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
                public IntPtr hCursor;
    
                /// <summary>
                ///     The pt screen pos.
                /// </summary>
                [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here."),
                SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
                public POINT ptScreenPos;
            }
    
            /// <summary>
            ///     The iconinfo.
            /// </summary>
            [StructLayout(LayoutKind.Sequential)]
            private struct ICONINFO
            {
                // Fields
                /// <summary>
                ///     The f icon.
                /// </summary>
                public bool fIcon;
    
                /// <summary>
                ///     The x hotspot.
                /// </summary>
                public int xHotspot;
    
                /// <summary>
                ///     The y hotspot.
                /// </summary>
                public int yHotspot;
    
                // Handle of the icon’s bitmask bitmap.
                /// <summary>
                ///     The hbm mask.
                /// </summary>
                public IntPtr hbmMask;
    
                // Handle of the icon’s color bitmap. Optional for monochrome icons.
                /// <summary>
                ///     The hbm color.
                /// </summary>
                public IntPtr hbmColor;
            }
    
            /// <summary>
            ///     The point.
            /// </summary>
            [StructLayout(LayoutKind.Sequential)]
            private struct POINT
            {
                // Fields
                /// <summary>
                ///     The x.
                /// </summary>
                public int x;
    
                /// <summary>
                ///     The y.
                /// </summary>
                public int y;
            }
    
            ///// <summary>
            ///// The capture cursor.
            ///// </summary>
            ///// <param name="x">
            ///// The x.
            ///// </param>
            ///// <param name="y">
            ///// The y.
            ///// </param>
            ///// <returns>
            ///// The <see cref="Bitmap"/>.
            ///// </returns>
            // public static Bitmap CaptureCursor(ref int x, ref int y)
            // {
            // try
            // {
            // // Return value initially nothing
            // Bitmap bmp = null;
    
            // CURSORINFO curInfo = new CURSORINFO();
            // curInfo.cbSize = Marshal.SizeOf(curInfo);
    
            // // HandleMessage("Start")
            // if (GetCursorInfo(ref curInfo))
            // {
            // if (curInfo.flags == CURSOR_SHOWING)
            // {
            // IntPtr hicon = CopyIcon(curInfo.hCursor);
    
            // if (hicon != IntPtr.Zero)
            // {
            // ICONINFO icoInfo = default(ICONINFO);
            // if (GetIconInfo(hicon, ref icoInfo))
            // {
            // // Delete the mask, if present.
            // if (icoInfo.hbmMask != IntPtr.Zero)
            // {
            // DeleteObject(icoInfo.hbmMask);
            // }
    
            // // Delete the color bitmap, if present.
            // if (icoInfo.hbmColor != IntPtr.Zero)
            // {
            // DeleteObject(icoInfo.hbmColor);
            // }
    
            // x = curInfo.ptScreenPos.x - icoInfo.xHotspot;
            // y = curInfo.ptScreenPos.y - icoInfo.yHotspot;
            // }
    
            // Icon ic = Icon.FromHandle(hicon);
            // bmp = ic.ToBitmap();
    
            // // Must destroy the icon object we got from CopyIcon
            // DestroyIcon(hicon);
            // }
            // }
            // }
    
            // // HandleMessage("End")
            // return bmp;
            // }
            // catch
            // {
            // return null;
            // }
            // }
        }
    CursorHelper.cs
        /// <summary>
        ///     The gdi stuff.
        /// </summary>
        internal class GDIStuff
        {
            #region Constants
    
            /// <summary>
            ///     The srccopy.
            /// </summary>
            public const int SRCCOPY = 13369376;
    
            #endregion
    
            #region Enums
    
            /// <summary>
            ///     Specifies a raster-operation code. These codes define how the color data for the
            ///     source rectangle is to be combined with the color data for the destination
            ///     rectangle to achieve the final color.
            /// </summary>
            public enum TernaryRasterOperations
            {
                /// <summary>dest = source</summary>
                SRCCOPY = 0x00CC0020, 
    
                /// <summary>dest = source OR dest</summary>
                SRCPAINT = 0x00EE0086, 
    
                /// <summary>dest = source AND dest</summary>
                SRCAND = 0x008800C6, 
    
                /// <summary>dest = source XOR dest</summary>
                SRCINVERT = 0x00660046, 
    
                /// <summary>dest = source AND (NOT dest)</summary>
                SRCERASE = 0x00440328, 
    
                /// <summary>dest = (NOT source)</summary>
                NOTSRCCOPY = 0x00330008, 
    
                /// <summary>dest = (NOT src) AND (NOT dest)</summary>
                NOTSRCERASE = 0x001100A6, 
    
                /// <summary>dest = (source AND pattern)</summary>
                MERGECOPY = 0x00C000CA, 
    
                /// <summary>dest = (NOT source) OR dest</summary>
                MERGEPAINT = 0x00BB0226, 
    
                /// <summary>dest = pattern</summary>
                PATCOPY = 0x00F00021, 
    
                /// <summary>dest = DPSnoo</summary>
                PATPAINT = 0x00FB0A09, 
    
                /// <summary>dest = pattern XOR dest</summary>
                PATINVERT = 0x005A0049, 
    
                /// <summary>dest = (NOT dest)</summary>
                DSTINVERT = 0x00550009, 
    
                /// <summary>dest = BLACK</summary>
                BLACKNESS = 0x00000042, 
    
                /// <summary>dest = WHITE</summary>
                WHITENESS = 0x00FF0062, 
    
                /// <summary>
                ///     Capture window as seen on screen.  This includes layered windows
                ///     such as WPF windows with AllowsTransparency="true"
                /// </summary>
                CAPTUREBLT = 0x40000000
            }
    
            #endregion
    
            #region Public Methods and Operators
    
            /// <summary>
            /// The bit blt.
            /// </summary>
            /// <param name="hdcDest">
            /// The hdc dest.
            /// </param>
            /// <param name="xDest">
            /// The x dest.
            /// </param>
            /// <param name="yDest">
            /// The y dest.
            /// </param>
            /// <param name="wDest">
            /// The w dest.
            /// </param>
            /// <param name="hDest">
            /// The h dest.
            /// </param>
            /// <param name="hdcSource">
            /// The hdc source.
            /// </param>
            /// <param name="xSrc">
            /// The x src.
            /// </param>
            /// <param name="ySrc">
            /// The y src.
            /// </param>
            /// <param name="RasterOp">
            /// The raster op.
            /// </param>
            /// <returns>
            /// The <see cref="bool"/>.
            /// </returns>
            [DllImport("gdi32.dll", EntryPoint = "BitBlt")]
            [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here.")]
            [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:FieldNamesMustBeginWithLowerCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
            public static extern bool BitBlt(
                IntPtr hdcDest, 
                int xDest, 
                int yDest, 
                int wDest, 
                int hDest, 
                IntPtr hdcSource, 
                int xSrc, 
                int ySrc, 
                int RasterOp);
    
            /// <summary>
            /// The create compatible bitmap.
            /// </summary>
            /// <param name="hdc">
            /// The hdc.
            /// </param>
            /// <param name="nWidth">
            /// The n width.
            /// </param>
            /// <param name="nHeight">
            /// The n height.
            /// </param>
            /// <returns>
            /// The <see cref="IntPtr"/>.
            /// </returns>
            [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleBitmap")]
            [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here.")]
            public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
    
            /// <summary>
            /// The create compatible dc.
            /// </summary>
            /// <param name="hdc">
            /// The hdc.
            /// </param>
            /// <returns>
            /// The <see cref="IntPtr"/>.
            /// </returns>
            [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC")]
            public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
    
            /// <summary>
            /// The create dc.
            /// </summary>
            /// <param name="lpszDriver">
            /// The lpsz driver.
            /// </param>
            /// <param name="lpszDevice">
            /// The lpsz device.
            /// </param>
            /// <param name="lpszOutput">
            /// The lpsz output.
            /// </param>
            /// <param name="lpInitData">
            /// The lp init data.
            /// </param>
            /// <returns>
            /// The <see cref="IntPtr"/>.
            /// </returns>
            [DllImport("gdi32.dll", EntryPoint = "CreateDC")]
            public static extern IntPtr CreateDC(IntPtr lpszDriver, string lpszDevice, IntPtr lpszOutput, IntPtr lpInitData);
    
            /// <summary>
            /// The delete dc.
            /// </summary>
            /// <param name="hDc">
            /// The h dc.
            /// </param>
            /// <returns>
            /// The <see cref="IntPtr"/>.
            /// </returns>
            [DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
            public static extern IntPtr DeleteDC(IntPtr hDc);
    
            /// <summary>
            /// The delete object.
            /// </summary>
            /// <param name="hDc">
            /// The h dc.
            /// </param>
            /// <returns>
            /// The <see cref="IntPtr"/>.
            /// </returns>
            [DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
            public static extern IntPtr DeleteObject(IntPtr hDc);
    
            /// <summary>
            /// The select object.
            /// </summary>
            /// <param name="hdc">
            /// The hdc.
            /// </param>
            /// <param name="bmp">
            /// The bmp.
            /// </param>
            /// <returns>
            /// The <see cref="IntPtr"/>.
            /// </returns>
            [DllImport("gdi32.dll", EntryPoint = "SelectObject")]
            public static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
    
            #endregion
        }
    GDIStuff.cs
     /// <summary>
        ///     The win 32 stuff.
        /// </summary>
        internal class Win32Stuff
        {
            #region Constants
    
            /// <summary>
            ///     The curso r_ showing.
            /// </summary>
            public const int CURSOR_SHOWING = 0x00000001;
    
            /// <summary>
            ///     The s m_ cxscreen.
            /// </summary>
            public const int SM_CXSCREEN = 0;
    
            /// <summary>
            ///     The s m_ cyscreen.
            /// </summary>
            public const int SM_CYSCREEN = 1;
    
            #endregion
    
            #region Public Methods and Operators
    
            /// <summary>
            /// The copy icon.
            /// </summary>
            /// <param name="hIcon">
            /// The h icon.
            /// </param>
            /// <returns>
            /// The <see cref="IntPtr"/>.
            /// </returns>
            [DllImport("user32.dll", EntryPoint = "CopyIcon")]
            public static extern IntPtr CopyIcon(IntPtr hIcon);
    
            /// <summary>
            /// The get cursor info.
            /// </summary>
            /// <param name="pci">
            /// The pci.
            /// </param>
            /// <returns>
            /// The <see cref="bool"/>.
            /// </returns>
            [DllImport("user32.dll", EntryPoint = "GetCursorInfo")]
            public static extern bool GetCursorInfo(out CURSORINFO pci);
    
            /// <summary>
            /// The get dc.
            /// </summary>
            /// <param name="ptr">
            /// The ptr.
            /// </param>
            /// <returns>
            /// The <see cref="IntPtr"/>.
            /// </returns>
            [DllImport("user32.dll", EntryPoint = "GetDC")]
            public static extern IntPtr GetDC(IntPtr ptr);
    
            /// <summary>
            ///     The get desktop window.
            /// </summary>
            /// <returns>
            ///     The <see cref="IntPtr" />.
            /// </returns>
            [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
            public static extern IntPtr GetDesktopWindow();
    
            /// <summary>
            /// The get icon info.
            /// </summary>
            /// <param name="hIcon">
            /// The h icon.
            /// </param>
            /// <param name="piconinfo">
            /// The piconinfo.
            /// </param>
            /// <returns>
            /// The <see cref="bool"/>.
            /// </returns>
            [DllImport("user32.dll", EntryPoint = "GetIconInfo")]
            public static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo);
    
            /// <summary>
            /// The get system metrics.
            /// </summary>
            /// <param name="abc">
            /// The abc.
            /// </param>
            /// <returns>
            /// The <see cref="int"/>.
            /// </returns>
            [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
            public static extern int GetSystemMetrics(int abc);
    
            /// <summary>
            /// The get window dc.
            /// </summary>
            /// <param name="ptr">
            /// The ptr.
            /// </param>
            /// <returns>
            /// The <see cref="IntPtr"/>.
            /// </returns>
            [DllImport("user32.dll", EntryPoint = "GetWindowDC")]
            public static extern IntPtr GetWindowDC(int ptr);
    
            /// <summary>
            /// The release dc.
            /// </summary>
            /// <param name="hWnd">
            /// The h wnd.
            /// </param>
            /// <param name="hDc">
            /// The h dc.
            /// </param>
            /// <returns>
            /// The <see cref="IntPtr"/>.
            /// </returns>
            [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
            public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
    
            #endregion
    
            /// <summary>
            ///     The cursorinfo.
            /// </summary>
            [StructLayout(LayoutKind.Sequential)]
            public struct CURSORINFO
            {
                /// <summary>
                ///     The cb size.
                /// </summary>
                public int cbSize; // Specifies the size, in bytes, of the structure. 
    
                /// <summary>
                ///     The flags.
                /// </summary>
                public int flags; // Specifies the cursor state. This parameter can be one of the following values:
    
                /// <summary>
                ///     The h cursor.
                /// </summary>
                public IntPtr hCursor; // Handle to the cursor. 
    
                /// <summary>
                ///     The pt screen pos.
                /// </summary>
                public POINT ptScreenPos; // A POINT structure that receives the screen coordinates of the cursor. 
            }
    
            /// <summary>
            ///     The iconinfo.
            /// </summary>
            [StructLayout(LayoutKind.Sequential)]
            public struct ICONINFO
            {
                /// <summary>
                ///     The f icon.
                /// </summary>
                public bool fIcon;
    
                // Specifies whether this structure defines an icon or a cursor. A value of TRUE specifies 
    
                /// <summary>
                ///     The x hotspot.
                /// </summary>
                public int xHotspot;
    
                // Specifies the x-coordinate of a cursor's hot spot. If this structure defines an icon, the hot 
    
                /// <summary>
                ///     The y hotspot.
                /// </summary>
                public int yHotspot;
    
                // Specifies the y-coordinate of the cursor's hot spot. If this structure defines an icon, the hot 
    
                /// <summary>
                ///     The hbm mask.
                /// </summary>
                public IntPtr hbmMask;
    
                // (HBITMAP) Specifies the icon bitmask bitmap. If this structure defines a black and white icon, 
    
                /// <summary>
                ///     The hbm color.
                /// </summary>
                public IntPtr hbmColor; // (HBITMAP) Handle to the icon color bitmap. This member can be optional if this 
            }
    
            /// <summary>
            ///     The point.
            /// </summary>
            [StructLayout(LayoutKind.Sequential)]
            public struct POINT
            {
                /// <summary>
                ///     The x.
                /// </summary>
                public int x;
    
                /// <summary>
                ///     The y.
                /// </summary>
                public int y;
            }
        }
    Win32Stuff.cs

    OK,类已经铺垫好了,接下来就在你的视频捕获方法中放入:关键方法--CursorHelper.CaptureCursor(ref x,ref y);

     1                                        Graphics g = Graphics.FromImage(bitmap);//编辑原始视频帧
     2                                        g.SmoothingMode = SmoothingMode.AntiAlias;//设置鼠标质量
     3                                        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
     4                                        g.PixelOffsetMode = PixelOffsetMode.HighQuality;
     5                                        var x = _currentPoint.X;
     6                                        var y = _currentPoint.Y;
     7                                        var cursorBmp = CursorHelper.CaptureCursor(ref x, ref y);
     8                                        if (cursorBmp != null)
     9                                        {
    10                                            g.DrawImage(cursorBmp, _currentPoint);
    11                                        }
    12                                        cursorBmp.Dispose();

    **注释说明:其中_currentPoint 是相对于屏幕的坐标Point** 获取方法是--

     _currentPoint = System.Windows.Forms.Cursor.Position;//(大屏坐标)

    **注释说明:其中bitmap是当前获取的最原始的视频帧(不包含任何的例如光标-声音-什么锤子之类的哈哈哈)**,此类方法就是把原始视频帧重新编辑!

    第二种方式:相对简单一点,获取光标_currentPoint还是使用上面的方法,但是不同的地方是我要自定义光标icon,这个又有一点难点就是如何画怎么画;---项目中采用的是外圈描边,内边填充方式;

     1  SolidBrush myBrush = new SolidBrush(System.Drawing.Color.FromArgb(50, ColorTranslator.FromHtml("#你的填充颜色")));//设置透明度跟填充颜色
     2                                        System.Drawing.Pen p = new System.Drawing.Pen(ColorTranslator.FromHtml("#你的描边颜色"));//设置透明度跟描边颜色
     3                                        Graphics g = Graphics.FromImage(bitmap);//编辑原始视频帧
     4                                        g.SmoothingMode = SmoothingMode.AntiAlias;//设置鼠标质量
     5                                        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
     6                                        g.PixelOffsetMode = PixelOffsetMode.HighQuality;
     7                                        g.DrawEllipse(p, new Rectangle(_currentPoint.X - this.screenArea.Left, _currentPoint.Y - this.screenArea.Top, 25, 25));//描边
     8                                        g.FillEllipse(myBrush, new Rectangle(_currentPoint.X - this.screenArea.Left, _currentPoint.Y - this.screenArea.Top, 25, 25));//填充圆形区域
     9                                        myBrush.Dispose();
    10                                        p.Dispose();
    11                                        g.Flush();

    **注释:在上述这种方式中特别注意,原始的方法比如你是全屏录制则采用以下方式即可,还有自定义笔刷的画法,我想做完给大家分享。**

    1                                        g.DrawEllipse(p, new Rectangle(_currentPoint.X , _currentPoint.Y, 25, 25));//描边
    2                                        g.FillEllipse(myBrush, new Rectangle(_currentPoint.X , _currentPoint.Y, 25, 25));//填充圆形区域

    **注释:如果你的录屏方式也存在区域模式,那么就采用 当前光标位置X轴减去你录屏区域的左坐标,当前光标位置Y轴减去你录屏的顶坐标即可获取,这种方式自适应任何区域**

    以上是个人在完善时候研究的成果,在此希望把它们分享给更多正在研究的伙伴们,因为研究的时候的确遇到了非常多的问题,我希望这些文章能够给你们一些方向研究,加快你们的开发进度。

  • 相关阅读:
    金蝶软件常用基础SQL数据表
    改变cxgrid行字体颜色
    C#默认修饰符
    const和static
    怎么写动态游标
    Report Machine支持导出PDF
    C1TrueDBGrid注册码
    免费在线思维导图工具Mindv V1.1.0发布
    支持中文输入的免费的Silverlight Richtextbox
    云计算浅谈之一:云计算介绍
  • 原文地址:https://www.cnblogs.com/BarryJames/p/6950813.html
Copyright © 2011-2022 走看看