For a very long time ago, in one of my projects, I needed to capture the screenshot which must have to support both full screen capturing and specific regional capturing.

Also I need to paste that captured image back to the screen programmatically. At that moment I solved my problem by using some WinApi methods in the user32.dll and gdi32.dll. Here I want to share that code with you.

To use this code;
Use CaptureScreen() method to capture whole screen;
Use CatureRegion(Region) to capture only the given region of the screen;
Use PasteToScreen(Bitmap, Region) method to paste any image to the given region on to the screen.

public class NativeMethods
{
    //
    // Takes a screenshot of full screen
    //Return the Bitmap of the Screen 
    public static Bitmap CaptureScreen() 
    { 
        return CaptureRegion(null); 
    } 
    // Takes a Screen Shot of the given rectangle.
    //Rectangle area which we try to get the screen shot. 
    // Return the Bitmap of the screen defined rectangle. 
    public static Bitmap CaptureRegion(Rectangle rct) 
    {
        return CaptureRegion(new Region(rct)); 
    } 

    /// Takes a screen shot of the given region.
    ///Region that which we try to get the picture of it. 
    /// Returns the Bitmap of the given region. 
    /// Bitmap Size will be equal to the GetBounds() of the Region. 
    /// Any other points that they are not in the region and 
    /// which are in the Bounds will be as Color.Transparent. 
    public static Bitmap CaptureRegion(Region rgn) 
    { 
        IntPtr hSDc, hMDc; IntPtr hBtm, hOldBtm; 
        Size imgSize = Size.Empty; 
        int xCoor = 0, yCoor = 0; 

        if (rgn == null) 
        { 
            hSDc = CreateDC("DISPLAY", string.Empty,string.Empty, string.Empty); 
            hMDc = CreateCompatibleDC(hSDc); 
            imgSize = new Size(GetDeviceCaps(hSDc, 8), GetDeviceCaps(hSDc, 10)); 
            GraphicsPath p = new GraphicsPath(); 
            p.AddRectangle(new Rectangle(0, 0, imgSize.Width, imgSize.Height)); 
            rgn = new Region(p); 
        } else 
        { 
            hSDc = GetDC(IntPtr.Zero); 
            SelectClipRgn(hSDc, rgn.GetHrgn(Graphics.FromHdc(hSDc))); 
            hMDc = CreateCompatibleDC(hSDc); 
            RECT myBox = new RECT(); 
            GetClipBox(hSDc, ref myBox); 
            imgSize = new Size(myBox.Width, myBox.Height); 
            xCoor = myBox.left; yCoor = myBox.top; 
        } 
        hBtm = CreateCompatibleBitmap(hSDc, imgSize.Width, imgSize.Height);
        hOldBtm = SelectObject(hMDc, hBtm); 
        BitBlt(hMDc, 0, 0, imgSize.Width, imgSize.Height, hSDc, xCoor, yCoor, RasterOperations.SRCCOPY); 
        hBtm = SelectObject(hMDc, hOldBtm);
        DeleteDC(hSDc); DeleteDC(hMDc); 
        Bitmap bmp = Bitmap.FromHbitmap(hBtm);
        RectangleF rct = rgn.GetBounds(Graphics.FromImage(bmp)); 
        RectangleF[] rcts = rgn.GetRegionScans(new Matrix()); 

        for (int i = 0; i < rcts.Length; i++) 
        { 
            rcts[i].X -= rct.X; 
            rcts[i].Y -= rct.Y;
        } 
        for (int x = 0; x < bmp.Width; x++)     
        {
            for (int y = 0; y < bmp.Height; y++) 
            { 
                bool isIn = IsInRectangles(rcts, (float)x, (float)y); 
                if (!isIn) 
                    bmp.SetPixel(x, y, Color.Transparent); 
            } 
        } 
    DeleteObject(hBtm); 
    return bmp; 
}

   /// Checks that is in region.
   public static bool IsInRegion(Region rgn, Point pt) 
   { 
       RectangleF[] rcts = rgn.GetRegionScans(new Matrix()); 
       return IsInRectangles(rcts, pt); 
   }

   public static bool IsInRectangles(RectangleF[] rcts, Point pt) 
   { 
       return IsInRectangles(rcts, (float)pt.X, (float)pt.Y); 
   } 

   /// Checks that is Point in Rectangles (Scans of Region).
   public static bool IsInRectangles(RectangleF[] rcts, float x, float y) 
   { 
       for (int i = 0; i < rcts.Length; i++) 
       { 
           if (rcts[i].Contains(x, y)) 
           { 
               return true; 
           } 
       } 
       return false; 
   } 

   public unsafe static void PasteToScreen(Bitmap bmp, Region rgn) 
   { 
       if (bmp == null || rgn == null) 
           return; 

       IntPtr hDc = GetDC(IntPtr.Zero); 
       Graphics g = Graphics.FromHdc(hDc); 
       RectangleF rctF = rgn.GetBounds(Graphics.FromHdc(hDc)); 
       Rectangle rct = new Rectangle((int)rctF.X, (int)rctF.Y, (int)rctF.Width, (int)rctF.Height); 
       g.SetClip(rgn, CombineMode.Replace); 
       g.DrawImage((Image)bmp, rct);
       DeleteDC(hDc); g.Dispose(); 
   }

   // NATIVE METHODS 
   [DllImport("gdi32.dll")] 
   public static extern int BitBlt(IntPtr srchDC, int srcX, int srcY, int srcW, int srcH, 
                                   IntPtr desthDC, int destX, int destY, RasterOperations op); 

   [DllImport("gdi32.dll", CharSet = CharSet.Auto)] 
   public static extern IntPtr CreateDC(string lpDriverName, string lpDeviceName, 
                                        string lpOutput, string lpInitData); 

   [DllImport("gdi32.dll", CharSet = CharSet.Auto)] 
   public static extern IntPtr CreateCompatibleDC(IntPtr hDC); 

   [DllImport("gdi32.dll")] 
   public static extern int GetDeviceCaps(IntPtr hdc, int nIndex); 

   [DllImport("user32.dll", CharSet = CharSet.Auto)] 
   public static extern IntPtr GetDC(IntPtr hWnd); 

   [DllImport("gdi32.dll", CharSet = CharSet.Auto)] 
   public static extern int GetClipBox(IntPtr hDC, ref RECT rectBox); 

   [DllImport("gdi32.dll", CharSet = CharSet.Auto)] 
   public static extern int SelectClipRgn(IntPtr hDC, IntPtr hRgn); 

   [DllImport("gdi32.dll", CharSet = CharSet.Auto)] 
   public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight); 

   [DllImport("gdi32.dll", CharSet = CharSet.Auto)] 
   public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); 

   [DllImport("gdi32.dll", CharSet = CharSet.Auto)] 
   public static extern bool DeleteDC(IntPtr hDC); 

   [DllImport("gdi32.dll", CharSet = CharSet.Auto)] 
   public static extern IntPtr DeleteObject(IntPtr hObject); 

   [DllImport("user32.dll")] 
   public static extern IntPtr SetTimer(IntPtr hWnd, int nIDEvent, int uElapse, TimerProc lpTimerFunc); 

   public delegate void TimerProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); 

   [DllImport("user32.dll")] 
   public static extern bool KillTimer(IntPtr hwnd, int idEvent); 

   public enum RasterOperations : uint 
   { 
       SRCCOPY = 0x00CC0020, 
       SRCPAINT = 0x00EE0086, 
       SRCAND = 0x008800C6, 
       SRCINVERT = 0x00660046, 
       SRCERASE = 0x00440328, 
       NOTSRCCOPY = 0x00330008, 
       NOTSRCERASE = 0x001100A6, 
       MERGECOPY = 0x00C000CA, 
       MERGEPAINT = 0x00BB0226, 
       PATCOPY = 0x00F00021, 
       PATPAINT = 0x00FB0A09, 
       PATINVERT = 0x005A0049, 
       DSTINVERT = 0x00550009, 
       BLACKNESS = 0x00000042, 
       WHITENESS = 0x00FF0062 
   }

   [StructLayout(LayoutKind.Sequential)] 
   public struct RECT 
   { 
       public int left; 
       public int top; 
       public int right; 
       public int bottom; 
       public int Width 
       { 
           get { return right - left; } 
       } 
       public int Height 
       { 
           get { return bottom - top; } 
       } 
   } 
}
Share: