Introduction
I am working on a desktop sharing type application in C#. First problem that I encountered was that there was not much in C# to capture the desktop image. After a bit of research I came to know that I shall have to use the Win32 APIs to provide this functionality to my application. I made following three classes to perform this job.
PlatformInvokeGDI32:
All the GDI32.dll APIs being used in this application are placed in this class.
PlatformInvokeUSER32:
All the User32.dll APIs have been placed in this class.
CaptureScreen:
In this class I have provided a simple static function GetDesktopImage
that captures the screen image using the APIs given in PlatformInvokeGDI32
and PlatformInvokeUSER32
and returns it as a bitmap.
You can very easily place these classes in your C# application. Just copy and paste following code in your C# project without changing any thing at all. If you want to use accompanying source files, you can add the CaptureScreen
namespace in your project or just change the CaptureScreen
namespace in these classes with your project namespace and that's all.
The beautiful source code
public class PlatformInvokeGDI32
{
#region Class Variables
public const int SRCCOPY = 13369376;
#endregion
#region Class Functions<br>
[DllImport("gdi32.dll",EntryPoint="DeleteDC")]
public static extern IntPtr DeleteDC(IntPtr hDc);
[DllImport("gdi32.dll",EntryPoint="DeleteObject")]
public static extern IntPtr DeleteObject(IntPtr hDc);
[DllImport("gdi32.dll",EntryPoint="BitBlt")]
public static extern bool BitBlt(IntPtr hdcDest,int xDest,
int yDest,int wDest,int hDest,IntPtr hdcSource,
int xSrc,int ySrc,int RasterOp);
[DllImport ("gdi32.dll",EntryPoint="CreateCompatibleBitmap")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc,
int nWidth, int nHeight);
[DllImport ("gdi32.dll",EntryPoint="CreateCompatibleDC")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport ("gdi32.dll",EntryPoint="SelectObject")]
public static extern IntPtr SelectObject(IntPtr hdc,IntPtr bmp);
#endregion
#region Public Constructor
}
public class PlatformInvokeUSER32
{
#region Class Variables
public const int SM_CXSCREEN=0;
public const int SM_CYSCREEN=1;
#endregion
#region Class Functions
[DllImport("user32.dll", EntryPoint="GetDesktopWindow")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll",EntryPoint="GetDC")]
public static extern IntPtr GetDC(IntPtr ptr);
[DllImport("user32.dll",EntryPoint="GetSystemMetrics")]
public static extern int GetSystemMetrics(int abc);
[DllImport("user32.dll",EntryPoint="GetWindowDC")]
public static extern IntPtr GetWindowDC(Int32 ptr);
[DllImport("user32.dll",EntryPoint="ReleaseDC")]
public static extern IntPtr ReleaseDC(IntPtr hWnd,IntPtr hDc);
#endregion
}
public class CaptureScreen
{
#region Class Variable Declaration
protected static IntPtr m_HBitmap;
#endregion
public class CaptureScreen
{
#region Public Class Functions
public static Bitmap GetDesktopImage()
{
SIZE size;
IntPtr hBitmap;
IntPtr hDC = PlatformInvokeUSER32.GetDC
(PlatformInvokeUSER32.GetDesktopWindow());
IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC);
size.cx = PlatformInvokeUSER32.GetSystemMetrics
(PlatformInvokeUSER32.SM_CXSCREEN);
size.cy = PlatformInvokeUSER32.GetSystemMetrics
(PlatformInvokeUSER32.SM_CYSCREEN);
hBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap
(hDC, size.cx, size.cy);
if (hBitmap!=IntPtr.Zero)
{
IntPtr hOld = (IntPtr) PlatformInvokeGDI32.SelectObject
(hMemDC, hBitmap);
PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0,size.cx,size.cy, hDC,
0, 0,PlatformInvokeGDI32.SRCCOPY);
PlatformInvokeGDI32.SelectObject(hMemDC, hOld);
PlatformInvokeGDI32.DeleteDC(hMemDC);
PlatformInvokeUSER32.ReleaseDC(PlatformInvokeUSER32.
GetDesktopWindow(), hDC);
Bitmap bmp = System.Drawing.Image.FromHbitmap(hBitmap);
PlatformInvokeGDI32.DeleteObject(hBitmap);
GC.Collect();
return bmp;
}
return null;
}
#endregion
}
public struct SIZE
{
public int cx;
public int cy;
}
Conclusion
The demo application with this code shows the use of these classes. Its a very simple windows application in which there is a simple form having a menu and a picture box control. Capture Screen menu item of menu is used to capture the screen and assign to the image property of picture box control. I hope you like this code. I have commented each line of this code to make it self explanatory. If there is still something confusing for you, please let me know. Good Luck!