maandag 4 februari 2008

Screen capture in C#

Screenshots of screen captures kunnen in C# gemaakt worden met behulp van een aantal API calls. Hieronder een stukje voorbeeldcode:

public const int SRCCOPY = 13369376;

[DllImport("user32.dll", EntryPoint = "GetDC")]
public static extern IntPtr GetDC(IntPtr ptr);

[DllImport("User32.dll")]
public static extern IntPtr GetDesktopWindow();

[DllImport("GDI32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

[DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
public static extern int GetSystemMetrics(int abc);

[DllImport("GDI32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);

[DllImport("GDI32.dll")]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);

[DllImport("GDI32.dll")]
public static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);

[DllImport("GDI32.dll")]
public static extern bool DeleteDC(IntPtr hdc);

[DllImport("User32.dll")]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

[DllImport("GDI32.dll")]
public static extern bool DeleteObject(IntPtr hObject);


public static Bitmap CaptureScreen()
{
//In size variable we shall keep the size of the screen.
Point size = Point.Empty;

//Variable to keep the handle to bitmap.
IntPtr hBitmap;

//Here we get the handle to the desktop device context.
IntPtr hDC = GetDC(GetDesktopWindow());

//Here we make a compatible device context in memory for screen device context.
IntPtr hMemDC = CreateCompatibleDC(hDC);

//We pass SM_CXSCREEN constant to GetSystemMetrics to get the X coordinates of screen.
size.X = GetSystemMetrics(0);

//We pass SM_CYSCREEN constant to GetSystemMetrics to get the Y coordinates of screen.
size.Y = GetSystemMetrics(1);

//We create a compatible bitmap of screen size using screen device context.
hBitmap = CreateCompatibleBitmap(hDC, size.X, size.Y);

//As hBitmap is IntPtr we can not check it against null. For this purspose IntPtr.Zero is used.
if (hBitmap != IntPtr.Zero)
{
//Here we select the compatible bitmap in memeory device context and keeps the refrence to Old bitmap.
IntPtr hOld = (IntPtr)SelectObject(hMemDC, hBitmap);
//We copy the Bitmap to the memory device context.
BitBlt(hMemDC, 0, 0, size.X, size.Y, hDC, 0, 0, SRCCOPY);
//We select the old bitmap back to the memory device context.
SelectObject(hMemDC, hOld);
//We delete the memory device context.
DeleteDC(hMemDC);
//We release the screen device context.
ReleaseDC(GetDesktopWindow(), hDC);
//Image is created by Image bitmap handle and stored in local variable.
Bitmap bmp = Image.FromHbitmap(hBitmap);
//Release the memory to avoid memory leaks.
DeleteObject(hBitmap);
//This statement runs the garbage collector manually.
GC.Collect();
//Return the bitmap
return bmp;
}

//If hBitmap is null return null.
return null;
}

Geen opmerkingen: