zoukankan      html  css  js  c++  java
  • 对非顶端窗口截图

    如何截取非前端窗体的截图

    首先说一下PrintWindow这个API的使用

           public static Bitmap GetWindowCapture(IntPtr hWnd)
            {
                IntPtr hscrdc = GetWindowDC(hWnd);
                RECT windowRect = new RECT();
                GetWindowRect(hWnd, ref windowRect);
                int width = windowRect.right - windowRect.left;
                int height = windowRect.bottom - windowRect.top;

                IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, width, height);
                IntPtr hmemdc = CreateCompatibleDC(hscrdc);
                SelectObject(hmemdc, hbitmap);
                PrintWindow(hWnd, hmemdc, 0);
                Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
                DeleteDC(hscrdc);//删除用过的对象
                DeleteDC(hmemdc);//删除用过的对象
                return bmp;
            }

            [DllImport("user32.dll")]
            public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);

            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateDC(
             string lpszDriver,         // driver name驱动名
             string lpszDevice,         // device name设备名
             string lpszOutput,         // not used; should be NULL
             IntPtr lpInitData   // optional printer data
             );
            [DllImport("gdi32.dll")]
            public static extern int BitBlt(
             IntPtr hdcDest, // handle to destination DC目标设备的句柄
             int nXDest,   // x-coord of destination upper-left corner目标对象的左上角的X坐标
             int nYDest,   // y-coord of destination upper-left corner目标对象的左上角的Y坐标
             int nWidth,   // width of destination rectangle目标对象的矩形宽度
             int nHeight, // height of destination rectangle目标对象的矩形长度
             IntPtr hdcSrc,   // handle to source DC源设备的句柄
             int nXSrc,    // x-coordinate of source upper-left corner源对象的左上角的X坐标
             int nYSrc,    // y-coordinate of source upper-left corner源对象的左上角的Y坐标
             UInt32 dwRop   // raster operation code光栅的操作值
             );

            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleDC(
             IntPtr hdc // handle to DC
             );

            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleBitmap(
             IntPtr hdc,         // handle to DC
             int nWidth,      // width of bitmap, in pixels
             int nHeight      // height of bitmap, in pixels
             );

            [DllImport("gdi32.dll")]
            public static extern IntPtr SelectObject(
             IntPtr hdc,           // handle to DC
             IntPtr hgdiobj    // handle to object
             );

            [DllImport("gdi32.dll")]
            public static extern int DeleteDC(
             IntPtr hdc           // handle to DC
             );

            [DllImport("user32.dll")]
            public static extern bool PrintWindow(
             IntPtr hwnd,                // Window to copy,Handle to the window that will be copied.
             IntPtr hdcBlt,              // HDC to print into,Handle to the device context.
             UInt32 nFlags               // Optional flags,Specifies the drawing options. It can be one of the following values.
             );

            [DllImport("user32.dll")]
            public static extern IntPtr GetWindowDC(
             IntPtr hwnd
             );

    很遗憾,上面的确可以截取非前端窗体的截图,但是非GDI的程序是无法截图的比如DirectX

    下面说一下BitBlt这个API的使用

        /// <summary>
        /// 提供全屏和指定窗口的截图 以及保存为文件的类
        /// </summary>
        public class ScreenCapture
        {
            /// <summary>
            /// 全屏截图
            /// </summary>
            /// <returns></returns>
            public Image CaptureScreen()
            {
                return CaptureWindow(User32.GetDesktopWindow());
            }
            /// <summary>
            /// 指定窗口截图
            /// </summary>
            /// <param name="handle">窗口句柄. (在windows应用程序中, 从Handle属性获得)</param>
            /// <returns></returns>
            public Image CaptureWindow(IntPtr handle)
            {
                IntPtr hdcSrc = User32.GetWindowDC(handle);
                User32.RECT windowRect = new User32.RECT();
                User32.GetWindowRect(handle, ref windowRect);
                int width = windowRect.right - windowRect.left;
                int height = windowRect.bottom - windowRect.top;
                IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
                IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
                IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
                GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
                GDI32.SelectObject(hdcDest, hOld);
                GDI32.DeleteDC(hdcDest);
                User32.ReleaseDC(handle, hdcSrc);
                Image img = Image.FromHbitmap(hBitmap);
                GDI32.DeleteObject(hBitmap);
                return img;
            }
            /// <summary>
            /// 指定窗口截图 保存为图片文件
            /// </summary>
            /// <param name="handle"></param>
            /// <param name="filename"></param>
            /// <param name="format"></param>
            public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)
            {
                Image img = CaptureWindow(handle);
                img.Save(filename, format);
            }
            /// <summary>
            /// 全屏截图 保存为文件
            /// </summary>
            /// <param name="filename"></param>
            /// <param name="format"></param>
            public void CaptureScreenToFile(string filename, ImageFormat format)
            {
                Image img = CaptureScreen();
                img.Save(filename, format);
            }

            /// <summary>
            /// 辅助类 定义 Gdi32 API 函数
            /// </summary>
            private class GDI32
            {

                public const int SRCCOPY = 0x00CC0020;
                [DllImport("gdi32.dll")]
                public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
                    int nWidth, int nHeight, IntPtr hObjectSource,
                    int nXSrc, int nYSrc, int dwRop);
                [DllImport("gdi32.dll")]
                public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
                    int nHeight);
                [DllImport("gdi32.dll")]
                public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
                [DllImport("gdi32.dll")]
                public static extern bool DeleteDC(IntPtr hDC);
                [DllImport("gdi32.dll")]
                public static extern bool DeleteObject(IntPtr hObject);
                [DllImport("gdi32.dll")]
                public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
            }

            /// <summary>
            /// 辅助类 定义User32 API函数
            /// </summary>
            private class User32
            {
                [StructLayout(LayoutKind.Sequential)]
                public struct RECT
                {
                    public int left;
                    public int top;
                    public int right;
                    public int bottom;
                }
                [DllImport("user32.dll")]
                public static extern IntPtr GetDesktopWindow();
                [DllImport("user32.dll")]
                public static extern IntPtr GetWindowDC(IntPtr hWnd);
                [DllImport("user32.dll")]
                public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
                [DllImport("user32.dll")]
                public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
            }
        }

    上面的类 使用了BitBlt这个API 可以截取GDI或者非GDI图形 只不过,非前端窗体图形不能截获...

    下面说一下不使用API 最简单的全屏截图方案

            public static Bitmap CopyPrimaryScreen()
            {
                Screen s = Screen.PrimaryScreen;
                Rectangle r = s.Bounds;
                int w = r.Width;
                int h = r.Height;
                Bitmap bmp = new Bitmap(w, h);
                Graphics g = Graphics.FromImage(bmp);
                g.CopyFromScreen
                (
                new Point(0, 0),
                new Point(0, 0),
                new Size(w, h)
                );
                return bmp;
            }

    最后,试试下面这个办法:

    只要窗体的visable为true,即使它在屏幕的外面也可以抓到图。如果为false,就是一张黑图了,赫赫。
     
    public static Bitmap GetWindow(IntPtr hWnd)
      {
       IntPtr hscrdc = GetWindowDC(hWnd);
       Control control = Control.FromHandle(hWnd);
       IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, control.Width, control.Height);
       IntPtr hmemdc = CreateCompatibleDC(hscrdc);
       SelectObject(hmemdc, hbitmap);
       PrintWindow(hWnd, hmemdc, 0);
       Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
       DeleteDC(hscrdc);//删除用过的对象
       DeleteDC(hmemdc);//删除用过的对象
       return bmp;
      }

    API声明

    [DllImport("gdi32.dll")]
      public static extern IntPtr CreateDC(
       string lpszDriver,        // driver name驱动名
       string lpszDevice,        // device name设备名
       string lpszOutput,        // not used; should be NULL
       IntPtr lpInitData  // optional printer data
       );
      [DllImport("gdi32.dll")]
      public static extern int BitBlt(
       IntPtr hdcDest, // handle to destination DC目标设备的句柄
       int nXDest,  // x-coord of destination upper-left corner目标对象的左上角的X坐标
       int nYDest,  // y-coord of destination upper-left corner目标对象的左上角的Y坐标
       int nWidth,  // width of destination rectangle目标对象的矩形宽度
       int nHeight, // height of destination rectangle目标对象的矩形长度
       IntPtr hdcSrc,  // handle to source DC源设备的句柄
       int nXSrc,   // x-coordinate of source upper-left corner源对象的左上角的X坐标
       int nYSrc,   // y-coordinate of source upper-left corner源对象的左上角的Y坐标
       UInt32 dwRop  // raster operation code光栅的操作值
       );

      [DllImport("gdi32.dll")]
      public static extern IntPtr CreateCompatibleDC(
       IntPtr hdc // handle to DC
       );

      [DllImport("gdi32.dll")]
      public static extern IntPtr CreateCompatibleBitmap(
       IntPtr hdc,        // handle to DC
       int nWidth,     // width of bitmap, in pixels
       int nHeight     // height of bitmap, in pixels
       );

      [DllImport("gdi32.dll")]
      public static extern IntPtr SelectObject(
       IntPtr hdc,          // handle to DC
       IntPtr hgdiobj   // handle to object
       );

      [DllImport("gdi32.dll")]
      public static extern int DeleteDC(
       IntPtr hdc          // handle to DC
       );

      [DllImport("user32.dll")]
      public static extern bool PrintWindow(
       IntPtr hwnd,               // Window to copy,Handle to the window that will be copied.
       IntPtr  hdcBlt,             // HDC to print into,Handle to the device context.
       UInt32 nFlags              // Optional flags,Specifies the drawing options. It can be one of the following values.
       );

      [DllImport("user32.dll")]
      public static extern IntPtr GetWindowDC(
       IntPtr hwnd
       );

  • 相关阅读:
    《花好月圆夜》
    关于Url重写
    三大WEB服务器对比分析(apache ,lighttpd,nginx)
    APC 和 Memcache 有什么区别,哪个更好效率更高?
    URL优化不仅仅是静态化重写URL
    php中的静态变量和动态变量的区别框架加载变量时运用
    msicuu.exe (msizap.exe),程序的作用
    显示器接口针脚定义(Dsub15)
    图文教程:DIY全屏开机LOGO详解
    ASP.NET中的媒体播放
  • 原文地址:https://www.cnblogs.com/love2wllw/p/1818660.html
Copyright © 2011-2022 走看看