[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

C# Windows Screen Capture

Posted on 2004-09-11
6
Medium Priority
?
1,049 Views
Last Modified: 2009-12-16
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.InteropServices.DllImport("gdi32.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.FromHwnd(IntPtr.Zero);
      using(displayGraphics)
      {
        System.Drawing.Rectangle screenBounds = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
        System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(screenBounds.Width, screenBounds.Height, displayGraphics);
         
        IntPtr displayHdc = displayGraphics.GetHdc();
        try
        {
          System.Drawing.Graphics bitmapGraphics = System.Drawing.Graphics.FromImage(bitmap);
          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(displayHdc);
        }
      }
    }
0
Comment
Question by:eternal_21
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 23

Expert Comment

by:rama_krishna580
ID: 12036786
Hi,

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.ClientRectangle.Width, this.ClientRectangle.Height, graphics);
     graphics_new= Graphics.FromImage(screenShot_);
     IntPtr handle_1 = graphics.GetHdc();
     IntPtr handle_2 =graphics_new.GetHdc();
     BitBlt(handle_2, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, handle_1, 0, 0, 13369376);
     graphics.ReleaseHdc(handle_1);
     graphics_new.ReleaseHdc(handle_2);
     return screenShot_;
     }
     finally
     {
     if(null!=graphics) graphics.Dispose();
     if(null!=graphics_new) graphics_new.Dispose();
     }
}

Need this:
          [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
          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
0
 
LVL 10

Author Comment

by:eternal_21
ID: 12037220
Okay.... if you like, modify YOUR function so that it does not require the BitBlt call.... I am trying to avoid making API calls.
0
 
LVL 1

Expert Comment

by:roflkind
ID: 12042324
i think in this case it's not possible to make a function like that without a single API function
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 10

Author Comment

by:eternal_21
ID: 12044801
I though there might be some way (in unsafe code?) to copy data from one Graphics object to another.
0
 
LVL 10

Expert Comment

by:ptmcomp
ID: 12047514
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)
0
 
LVL 10

Accepted Solution

by:
ptmcomp earned 2000 total points
ID: 12091215
           private void button1_Click(object sender, System.EventArgs e)
            {
                  Control control = this;

                  using (Graphics wndGraphics = control.CreateGraphics())
                  {
                        Size size = control.DisplayRectangle.Size;
                        Bitmap bitmap = new Bitmap(size.Width, size.Height, wndGraphics);
                        using (Graphics bmpGraphics = Graphics.FromImage(bitmap))
                        {
                              PaintRecursive(Point.Empty, control, bmpGraphics, size);
                        }
                        bitmap.Save(@"c:\test.bmp", ImageFormat.Bmp);
                  }
            }

            private void PaintRecursive(Point location, Control control, Graphics graphics, Size size)
            {
                  graphics.ResetTransform();
                  graphics.Transform = new Matrix(1,0,0,1,location.X, location.Y);

                  InvokePaintBackground(control, new PaintEventArgs(graphics, new Rectangle(Point.Empty, size)));
                  InvokePaint(control, new PaintEventArgs(graphics, new Rectangle(Point.Empty, size)));
                  foreach(Control innerControl in control.Controls)
                  {
                        Point innerLocation = new Point(location.X + innerControl.Left, location.Y + innerControl.Top);
                        PaintRecursive(innerLocation, innerControl, graphics, innerControl.ClientSize);
                  }
            }

But it doesn't paint the controls that are drawn by unmanaged code :o(
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…
Suggested Courses

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question