eternal_21
asked on
C# Windows Screen Capture
Okay, here is the problem: I have managed to get a screen capture and turn it into a bitmap, using only one API call (I don't know if this is significant, but I know I started with about 10...).
My question, is how I can get rid of this BitBlt API call?
[System.Runtime.InteropSer vices.DllI mport("gdi 32.dll")]
private static extern int BitBlt(int srchDC, int srcX, int srcY, int srcW, int srcH, int desthDC, int destX, int destY, int op);
private static System.Drawing.Bitmap CaptureScreen()
{
System.Drawing.Graphics displayGraphics = System.Drawing.Graphics.Fr omHwnd(Int Ptr.Zero);
using(displayGraphics)
{
System.Drawing.Rectangle screenBounds = System.Windows.Forms.Scree n.PrimaryS creen.Boun ds;
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(scre enBounds.W idth, screenBounds.Height, displayGraphics);
IntPtr displayHdc = displayGraphics.GetHdc();
try
{
System.Drawing.Graphics bitmapGraphics = System.Drawing.Graphics.Fr omImage(bi tmap);
using(bitmapGraphics)
{
IntPtr bitmapHdc = bitmapGraphics.GetHdc();
try
{
const int SRCCOPY = 13369376;
BitBlt(bitmapHdc.ToInt32() , 0, 0, screenBounds.Width, screenBounds.Height, displayHdc.ToInt32(), 0, 0, SRCCOPY);
return bitmap;
}
finally
{
bitmapGraphics.ReleaseHdc( bitmapHdc) ;
}
}
}
finally
{
displayGraphics.ReleaseHdc (displayHd c);
}
}
}
My question, is how I can get rid of this BitBlt API call?
[System.Runtime.InteropSer
private static extern int BitBlt(int srchDC, int srcX, int srcY, int srcW, int srcH, int desthDC, int destX, int destY, int op);
private static System.Drawing.Bitmap CaptureScreen()
{
System.Drawing.Graphics displayGraphics = System.Drawing.Graphics.Fr
using(displayGraphics)
{
System.Drawing.Rectangle screenBounds = System.Windows.Forms.Scree
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(scre
IntPtr displayHdc = displayGraphics.GetHdc();
try
{
System.Drawing.Graphics bitmapGraphics = System.Drawing.Graphics.Fr
using(bitmapGraphics)
{
IntPtr bitmapHdc = bitmapGraphics.GetHdc();
try
{
const int SRCCOPY = 13369376;
BitBlt(bitmapHdc.ToInt32()
return bitmap;
}
finally
{
bitmapGraphics.ReleaseHdc(
}
}
}
finally
{
displayGraphics.ReleaseHdc
}
}
}
ASKER
Okay.... if you like, modify YOUR function so that it does not require the BitBlt call.... I am trying to avoid making API calls.
i think in this case it's not possible to make a function like that without a single API function
ASKER
I though there might be some way (in unsafe code?) to copy data from one Graphics object to another.
This could also be a way: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_6qpj.asp
(But it's also unmanaged code - but behind most of the .net framework calls are PInvoke calls. Unfortuanetly they're not all wrapped by the framework)
(But it's also unmanaged code - but behind most of the .net framework calls are PInvoke calls. Unfortuanetly they're not all wrapped by the framework)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Tryout this...
Here's how to get the screen shot:
public virtual Image GetScreenShot()
{
Graphics graphics =null;;
Graphics graphics_new=null;
try
{
graphics = this.CreateGraphics();
Image screenShot_ = new Bitmap(this.ClientRectangl
graphics_new= Graphics.FromImage(screenS
IntPtr handle_1 = graphics.GetHdc();
IntPtr handle_2 =graphics_new.GetHdc();
BitBlt(handle_2, 0, 0, this.ClientRectangle.Width
graphics.ReleaseHdc(handle
graphics_new.ReleaseHdc(ha
return screenShot_;
}
finally
{
if(null!=graphics) graphics.Dispose();
if(null!=graphics_new) graphics_new.Dispose();
}
}
Need this:
[System.Runtime.InteropSer
private static extern bool BitBlt(
IntPtr hdcDest,
int nXDest,
int nYDest,
int nWidth,
int nHeight,
IntPtr hdcSrc,
int nXSrc,
int nYSrc,
System.Int32 dwRop
);
Once you have you image, save away...
R.K