C# .NET - CaptureWindow in c#.net 2.0 windows application

Asked By masuri suhasini on 08-Apr-09 07:24 AM

Hi

In my application I have to take print screen for active window.

Below code I am using to capture screen .

Using this code I am also getting task bar.

It is unble to capture only one active window.

 

Please give me any solution to print only active form in windows application dot net 2.0.

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;



using System.Runtime.InteropServices;

using System.Drawing.Imaging;


namespace Exportform

{

public partial class ScreenCapture : Form

{

public ScreenCapture()

{

InitializeComponent();

}

private void button1_Click(object sender, EventArgs e)

{

Graphics graph = null;

try

{

Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);

graph = Graphics.FromImage(bmp);

graph.CopyFromScreen(0, 0, 0, 0, bmp.Size);

SaveImage(bmp);

}

finally

{

graph.Dispose();

}

}

private void SaveImage(Bitmap b)

{

b.Save(@"C:\1.bmp");

}


public Image CaptureWindow(IntPtr handle)

{

// get te 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);

img.Save(@"C:\2.bmp");

return img;

}

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);

}

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);

}

private void Activeform_Click(object sender, EventArgs e)

{

CaptureScreen();


}

public Image CaptureScreen()

{

// return CaptureWindow(User32.GetDesktopWindow());

IntPtr inte = User32.GetWindowDC(User32.GetDesktopWindow());

return CaptureWindow(User32.GetWindowDC(inte));

}


public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)

{

Image img = CaptureWindow(handle);

img.Save(filename, format);

}


public void CaptureScreenToFile(string filename, ImageFormat format)

{

Image img = CaptureScreen();

img.Save(filename, format);

}

}

}

Its pretty easy. The problem with your code is you are using User32.GetDesktopWindow() which would return the entire desktop.

[)ia6l0 iii replied to masuri suhasini on 08-Apr-09 12:33 PM
1. You need to find out the active window handle before you try to capture. You can use the FindWindow method to determine the handle.

2. Use the below function by passing the handle.

public Picture CaptureWindow(long hWndSrc, bool Client, long LeftSrc, long TopSrc, long WidthSrc, long HeightSrc) {
        
long hDCMemory;
        long 
hBmp;
        long 
hBmpPrev;
        long 
r;
        long 
hDCSrc;
        long 
hPal;
        long 
hPalPrev;
        long 
RasterCapsScrn;
        long 
HasPaletteScrn;
        long 
PaletteSizeScrn;
    
}
    
    Picture CaptureWindow(
int hWndSrc, bool Client, int LeftSrc, int TopSrc, long WidthSrc, long HeightSrc) {
        
int hDCMemory;
        int 
hBmp;
        int 
hBmpPrev;
        int 
r;
        int 
hDCSrc;
        int 
hPal;
        int 
hPalPrev;
        int 
RasterCapsScrn;
        int 
HasPaletteScrn;
        int 
PaletteSizeScrn;
        
LOGPALETTE LogPal;
        
//  Depending on the value of Client get the proper device context.
        
if (Client) {
            hDCSrc 
GetDC(hWndSrc);
            
//  Get device context for client area.
        
}
        
else {
            hDCSrc 
GetWindowDC(hWndSrc);
            
//  Get device context for entire
            //  window.
        
}
        
//  Create a memory device context for the copy process.
        
hDCMemory CreateCompatibleDC(hDCSrc);
        
//  Create a bitmap and place it in the memory DC.
        
hBmp CreateCompatibleBitmap(hDCSrc, WidthSrc, HeightSrc);
        
hBmpPrev SelectObject(hDCMemory, hBmp);
        
//  Get screen properties.
        
RasterCapsScrn GetDeviceCaps(hDCSrc, RASTERCAPS);
        
//  Raster
        //  capabilities.
        
HasPaletteScrn (RasterCapsScrn & RC_PALETTE);
        
//  Palette
        //  support.
        
PaletteSizeScrn GetDeviceCaps(hDCSrc, SIZEPALETTE);
        
//  Size of
        //  palette.
        //  If the screen has a palette make a copy and realize it.
        
if ((HasPaletteScrn 
                    && (PaletteSizeScrn 
== 256))) {
            
//  Create a copy of the system palette.
            
LogPal.palVersion 768;
            
LogPal.palNumEntries 256;
            
GetSystemPaletteEntries(hDCSrc, 0256, LogPal.palPalEntry(0));
            
hPal CreatePalette(LogPal);
            
//  Select the new palette into the memory DC and realize it.
            
hPalPrev SelectPalette(hDCMemory, hPal, 0);
            
RealizePalette(hDCMemory);
        
}
        
//  Copy the on-screen image into the memory DC.
        
BitBlt(hDCMemory, 00, WidthSrc, HeightSrc, hDCSrc, LeftSrc, TopSrc, vbSrcCopy);
        
//  Remove the new copy of the on-screen image.
        
hBmp SelectObject(hDCMemory, hBmpPrev);
        
//  If the screen has a palette get back the palette that was
        //  selected in previously.
        
if ((HasPaletteScrn 
                    && (PaletteSizeScrn 
== 256))) {
            hPal 
SelectPalette(hDCMemory, hPalPrev, 0);
        
}
        
//  Release the device context resources back to the system.
        
DeleteDC(hDCMemory);
        
ReleaseDC(hWndSrc, hDCSrc);
        
//  Call CreateBitmapPicture to create a picture object from the
        //  bitmap and palette handles. Then return the resulting picture
        //  object.
        
return CreateBitmapPicture(hBmp, hPal);
    
}


how to pass window handle - masuri suhasini replied to [)ia6l0 iii on 09-Apr-09 02:38 AM

Hi

Dialbo,

I have doubt  how to pass   window handle to this fuction

return CaptureWindow(User32.GetWindowDC(window handle )); useing you code

 

 

public Image CaptureScreen()

        {

           // return CaptureWindow(User32.GetDesktopWindow());      

 

            return CaptureWindow(User32.GetWindowDC(window handle ));

        }

 

[DllImport("user32.dll")]

 

        public static extern IntPtr GetWindowDC(IntPtr hWnd);

 


You need to get the attributes of the handle from the FindWindow Method.

[)ia6l0 iii replied to masuri suhasini on 09-Apr-09 02:49 AM
http://support.microsoft.com/kb/161299
http://support.microsoft.com/kb/161299
http://support.microsoft.com/kb/161299