對非頂端視窗截圖

來源:互聯網
上載者:User
如何截取非前端表單的

首先說一下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
   );

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.