0

I'm developing a windows application in which i want to take screenshot of the whole window. For that i have written the following code:

Imports System.IO


Public Class ScreenCapture

    Public Sub GetJPG()
        Dim dt As DateTime = DateTime.Now
        Dim cdt As String = ""
        cdt = dt.ToString("dd MM yyyy HH:mm:ss")
        cdt = cdt.Replace(":", "_")
        cdt = cdt.Replace(" ", "_")

        Dim ScreenSize = SystemInformation.PrimaryMonitorSize

        Dim width As Integer = ScreenSize.Width
        Dim height As Integer = ScreenSize.Height

        Dim dir As DirectoryInfo = New DirectoryInfo("Screenshots")
        If Not dir.Exists Then dir = Directory.CreateDirectory(dir.FullName)
        Dim path As String = AppDomain.CurrentDomain.BaseDirectory

        Dim bitmap = New System.Drawing.Bitmap(ScreenSize.Width, ScreenSize.Height)
        Dim g = Graphics.FromImage(bitmap)
        g.CopyFromScreen(New Point(0, 0), New Point(0, 0), ScreenSize)
        g.Flush()

        Dim newbitmap = New System.Drawing.Bitmap(bitmap, width, height)

        Dim gr As Graphics = Graphics.FromImage(bitmap)
        gr.DrawImage(newbitmap, New Rectangle(0, 0, width, height), New Rectangle(0, 0, bitmap.Width, bitmap.Height), GraphicsUnit.Pixel)

        newbitmap.Save(path & "Screenshots\" & cdt & ".jpg", System.Drawing.Imaging.ImageFormat.Png)

    End Sub
End Class

When i run a wpf application and in background keep this screencapture app running. It takes screenshot of the window in the background of the wpf application. I want the screenshot of the current view which is there on the monitor.

Please help me.

Farhan Mukadam
  • 470
  • 9
  • 25
  • Sorry what is the question here ? – TheKingDave Sep 18 '13 at 11:13
  • @TheKingDave I have a wpf application which runs in fullscreen mode. the taskbar is also hidden when the wpf app is running. My goal is to take screenshot of this running wpf application every 10 secs. But the code above takes screenshot of the window in background to the wpf application whereas it should take screenshot of the running wpf application. – Farhan Mukadam Sep 18 '13 at 11:20
  • Else,you may also try this..http://stackoverflow.com/questions/3422262/take-a-screenshot-with-selenium-webdriver – vysakh Sep 18 '13 at 11:51

4 Answers4

1

This may help you..

using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;

namespace Cluster2
{
public class screen
{
    public void Main()
    {

        CaptureScreenToFile("C:\\temp1.gif", ImageFormat.Gif);
    }

    /// <summary>
    /// Creates an Image object containing a screen shot of the entire desktop
    /// </summary>
    /// <returns></returns>
    public Image CaptureScreen()
    {
        return CaptureWindow(User32.GetDesktopWindow());
    }

    /// <summary>
    /// Creates an Image object containing a screen shot of a specific window
    /// </summary>
    /// <param name="handle">The handle to the window. (In windows forms, this is obtained by the Handle property)</param>
    /// <returns></returns>
    public Image CaptureWindow(IntPtr handle)
    {
        // get the hDC of the target window
        IntPtr hdcSrc = User32.GetWindowDC(handle);
        // get the size
        User32.RECT windowRect = new User32.RECT();
        User32.GetWindowRect(handle, ref windowRect);
        int width = windowRect.right - windowRect.left;
        int height = windowRect.bottom - windowRect.top;
        // create a device context we can copy to
        IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
        // create a bitmap we can copy it to,
        // using GetDeviceCaps to get the width/height
        IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
        // select the bitmap object
        IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
        // bitblt over
        GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
        // restore selection
        GDI32.SelectObject(hdcDest, hOld);
        // clean up 
        GDI32.DeleteDC(hdcDest);
        User32.ReleaseDC(handle, hdcSrc);

        // get a .NET image object for it
        Image img = Image.FromHbitmap(hBitmap);
        // free up the Bitmap object
        GDI32.DeleteObject(hBitmap);

        return img;
    }

    /// <summary>
    /// Captures a screen shot of a specific window, and saves it to a file
    /// </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>
    /// Captures a screen shot of the entire desktop, and saves it to a file
    /// </summary>
    /// <param name="filename"></param>
    /// <param name="format"></param>
    public void CaptureScreenToFile(string filename, ImageFormat format)
    {
        Image img = CaptureScreen();
        img.Save(filename, format);
    }

    /// <summary>
    /// Helper class containing Gdi32 API functions
    /// </summary>
    private class GDI32
    {

        public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter

        [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>
    /// Helper class containing User32 API functions
    /// </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);

    }

}
}

It will take the screenshot of the entire window that you focus presently..Also, if you are using it as a seperate file like screen.cs then you should include the below function in your main cs file.

public class sshot : screen
{
    public void shot()
    {
        CaptureScreenToFile("C:\\Logs\\Screenshot" + DateTime.Now.ToString("ddMMyyyy") + ".jpg", System.Drawing.Imaging.ImageFormat.Png);
    }
}

Now call the function at the situation where you need to get screenshot..

 sshot ob = new sshot();     
 ob.shot();
vysakh
  • 266
  • 2
  • 4
  • 19
  • There is no error. Its take screen shot of the window in background. Not the window that is currently running on screen. – Farhan Mukadam Sep 18 '13 at 11:22
  • see my edited answer..it works fine for me..is the window that you want to capture is minimised or in another monitor? – vysakh Sep 18 '13 at 11:24
  • See my comment on the question. It perfectly describes my problem. – Farhan Mukadam Sep 18 '13 at 11:28
  • then it should work...it works fine for me...can you please try me how did you try this? – vysakh Sep 18 '13 at 11:29
  • First i run this screencapture application. Minimize it. Then i run the exe of my WPF application which runs in fullscreen, hiding the taskbar. After closing my wpf application when i see the images of the screenshots taken. The images are of windows that are there in background of the running WPF application. – Farhan Mukadam Sep 18 '13 at 11:32
  • But may i ask you one thing..how these both apps are linked? – vysakh Sep 18 '13 at 11:36
  • they are not linked. Both are independent. I m making this screencapture app to take screenshot every 10 seconds of my desktop. – Farhan Mukadam Sep 18 '13 at 11:56
  • Could you please try my comment which I put down your question? – vysakh Sep 18 '13 at 11:58
1

Try with this:

[StructLayout(LayoutKind.Sequential)]
struct RECT
{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

[DllImport(ExternDll.User32)]
public static extern IntPtr GetForegroundWindow();

[DllImport(ExternDll.User32, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(
    IntPtr hWnd,
    out RECT lpRect);

public static Rectangle GetWindowRect() // get bounds of active window
{
    RECT rect;

    GetWindowRect(GetForegroundWindow(), out rect);

    return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
}

public static Bitmap GetScreenshot(Rectangle rect) // pass the result of GetWindowRect
{
    var screenshot = new Bitmap(rect.Width, rect.Height, PixelFormat.Format24bppRgb);

    using (var graphics = Graphics.FromImage(screenshot))
    {
        graphics.CopyFromScreen(rect.Location, Point.Empty, rect.Size);
    }

    return screenshot;
}

All this get a screenshot of the active windows.

Some links:

RECT structure GetForegroundWindow function and GetWindowRect function.

Alessandro D'Andria
  • 8,663
  • 2
  • 36
  • 32
1

Can you try below class.

public class ScreenShot
{
    public static void CaptureAndSave(int x, int y, int width, int height, string imagePath)
    {
        Bitmap myImage = ScreenShot.Capture(x, y, width, height);
        myImage.Save(imagePath, ImageFormat.Png);
    }

    private static Bitmap Capture(int x, int y, int width, int height)
    {            
        Bitmap screenShotBMP = new Bitmap(width, height, PixelFormat.Format32bppArgb);

        Graphics screenShotGraphics = Graphics.FromImage(screenShotBMP);

        screenShotGraphics.CopyFromScreen(new Point(x, y), Point.Empty, new Size(width, height), CopyPixelOperation.SourceCopy);
        screenShotGraphics.Dispose();

        return screenShotBMP;
    }
}

How to call

ScreenShot.CaptureAndSave(0, 0, ScreenSize.Width, ScreenSize.Height, @"D:\Capture.png");
RonakThakkar
  • 903
  • 5
  • 7
1

Take a look at this: How to: Create a Bitmap from a Visual should be the easiest to get a image from a WPF Visual.

David Sdot
  • 2,343
  • 1
  • 20
  • 26