c# capture window content without borders - c#

I have to capture content and only content of one window. Like that:
(captured by ScreenCaptor)
But my program captures that:
I use this code:
IntPtr ParenthWnd = GetForegroundWindow();
if (!ParenthWnd.Equals(IntPtr.Zero))
{
IntPtr prevChild = IntPtr.Zero;
IntPtr currChild = IntPtr.Zero;
while (true)
{
currChild = FindWindowEx(ParenthWnd, prevChild, null, null);
if (currChild == IntPtr.Zero) break;
result.Add(currChild);
label3.Text += currChild.ToString() + " _ ";
prevChild = currChild;
}
}
then I choose my child window, e.g:
handle = result[0];
and finally capture screenshot:
RECT rect = new RECT();
GetWindowRect(handle, ref rect);
Bitmap image = new Bitmap(rect.Right - rect.Left, rect.Bottom - rect.Top);
using (Graphics graphics = Graphics.FromImage(image))
{
IntPtr hDC = graphics.GetHdc();
PrintWindow(new HandleRef(graphics, handle), hDC, 0);
graphics.ReleaseHdc(hDC);
}
of course I cannot crop captured image, because don't know size of each 'border'
thanks in advance

a little bit late but maby it does someone help:
private const int GWL_STYLE = -16; //hex constant for style changing
private const int WS_BORDER = 0x00800000; //window with border
private const int WS_CAPTION = 0x00C00000; //window with a title bar
private const int WS_SYSMENU = 0x00080000; //window with no borders etc.
private const int WS_MINIMIZEBOX = 0x00020000; //window with minimizebox
public static Bitmap printWindow(IntPtr hwnd)
{
RECT rc;
GetWindowRect(hwnd, out rc);
Bitmap bmp;
//make window borderless
SetWindowLong(hwnd, GWL_STYLE, WS_SYSMENU);
SetWindowPos(hwnd, -2, rc.X, rc.Y, rc.Width, rc.Height, 0x0040);
DrawMenuBar(hwnd);
bmp = new Bitmap(800, 800, PixelFormat.Format32bppArgb);
Graphics gfxBmp = Graphics.FromImage(bmp);
IntPtr hdcBitmap = gfxBmp.GetHdc();
PrintWindow(hwnd, hdcBitmap, 0);
gfxBmp.ReleaseHdc(hdcBitmap);
gfxBmp.Dispose();
//restore window
SetWindowLong(hwnd, GWL_STYLE, WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX);
DrawMenuBar(hwnd);
ShowWindowAsync(hwnd, 1); //1 = Normal
return bmp;
}

Another solution is to print the window and remove the borders from the bmp:
[DllImport("user32.dll")]
static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags);
public Bitmap printWindow()
{
RECT clientRect;
GetClientRect(WindowHandle, out clientRect);
RECT windowRect;
GetWindowRect(WindowHandle, out windowRect);
int borderSize = (windowRect.Width - clientRect.Width) / 2;
int titleBarSize = (windowRect.Height - clientRect.Height) - borderSize;
PrintWindow(MainWindowHandle, hdcBitmap, 0);
gfxBmp.ReleaseHdc(hdcBitmap);
gfxBmp.Dispose();
Bitmap bmp = bmp.Clone(new Rectangle(borderSize, titleBarSize, bmp.Width - 2*borderSize, bmp.Height - titleBarSize-borderSize), PixelFormat.Format32bppRgb);
return bmp;
}

Related

Unity, Transparent Background and Multiple Monitors

I'm trying to learn a few things, but I'm kinda stuck and I don't know where to go from here. I'm either blind or just confused.
I've been looking at some scripts from here: Answers.Unity
Right now, I got the background transparency working on my main screen, but I'm wondering what I should do to make this happen on my second monitor too. Or third, if I had one. As of right now the other screens turn black. This is the code:
[SerializeField]
private Material m_Material;
[SerializeField]
private Camera mainCamera;
private bool clickThrough = true;
private bool prevClickThrough = true;
private struct MARGINS
{
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
}
[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
[DllImport("user32.dll")]
static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, byte bAlpha, int dwFlags);
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
private static extern int SetWindowPos(IntPtr hwnd, int hwndInsertAfter, int x, int y, int cx, int cy, int uFlags);
[DllImport("Dwmapi.dll")]
private static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);
const int GWL_STYLE = -16;
const uint WS_POPUP = 0x80000000;
const uint WS_VISIBLE = 0x10000000;
const int HWND_TOPMOST = -1;
int fWidth;
int fHeight;
IntPtr hwnd;
MARGINS margins;
public bool OverUI()
{ //Use sparingly
//Set up the new Pointer Event
PointerEventData m_PointerEventData = new PointerEventData(EventSystem.current);
m_PointerEventData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(m_PointerEventData, results);
if (results.Count > 0) return true;
return false;
}
void Start()
{
fWidth = Screen.width;
fHeight = Screen.height;
margins = new MARGINS() { cxLeftWidth = -1 };
hwnd = GetActiveWindow();
SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fWidth, fHeight, 32 | 64); //SWP_FRAMECHANGED = 0x0020 (32); //SWP_SHOWWINDOW = 0x0040 (64)
DwmExtendFrameIntoClientArea(hwnd, ref margins);
Application.runInBackground = true;
}
void Update()
{
// If our mouse is overlapping an object
RaycastHit hit = new RaycastHit();
clickThrough = !Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition).origin,
mainCamera.ScreenPointToRay(Input.mousePosition).direction, out hit, 100,
Physics.DefaultRaycastLayers) && !OverUI();
if (clickThrough != prevClickThrough)
{
if (clickThrough)
{
SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
SetWindowLong (hwnd, -20, (uint)524288 | (uint)32);//GWL_EXSTYLE=-20; WS_EX_LAYERED=524288=&h80000, WS_EX_TRANSPARENT=32=0x00000020L
SetLayeredWindowAttributes (hwnd, 0, 255, 2);// Transparency=51=20%, LWA_ALPHA=2
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fWidth, fHeight, 32 | 64); //SWP_FRAMECHANGED = 0x0020 (32); //SWP_SHOWWINDOW = 0x0040 (64)
}
else
{
SetWindowLong (hwnd, -20, ~(((uint)524288) | ((uint)32)));//GWL_EXSTYLE=-20; WS_EX_LAYERED=524288=&h80000, WS_EX_TRANSPARENT=32=0x00000020L
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fWidth, fHeight, 32 | 64); //SWP_FRAMECHANGED = 0x0020 (32); //SWP_SHOWWINDOW = 0x0040 (64)
}
prevClickThrough = clickThrough;
}
}
void OnRenderImage(RenderTexture from, RenderTexture to)
{
Graphics.Blit(from, to, m_Material);
}
Could anyone guide me a little bit so that I can figure this out?
Edit: I've figured out a little bit.. I think.
When Unity opens, (with multiple displays), it creates two windows in the task bar. I'm guessing I need to find that other window, set it as active and then run something similar to this code again. But I'm guessing I would need to fix the pos and margins before doing so.
It's beyond my understanding of WinApi right now, but I hope someone knows a bit more about this than me.

How to save Bitmap from ActiveX component

Try to save screen of AxMsTscAxNotSafeForScripting (Microsoft Terminal Services Client Control), but cant find any information about it...
I try one code, but it screen only field of element...
https://i.imgur.com/fo6jKDT.png
[Flags]
private enum DrawingOptions
{
PRF_CHECKVISIBLE = 0x00000001,
PRF_NONCLIENT = 0x00000002,
PRF_CLIENT = 0x00000004,
PRF_ERASEBKGND = 0x00000008,
PRF_CHILDREN = 0x00000010,
PRF_OWNED = 0x00000020
}
private const uint WM_PAINT = 0xF;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr dc, DrawingOptions opts);
var bm = new Bitmap(rdp.Width, rdp.Height, rdp.CreateGraphics());
using (Graphics g = Graphics.FromImage(bm))
{
IntPtr dc = g.GetHdc();
try
{
SendMessage(rdp.Handle, WM_PAINT, dc,
DrawingOptions.PRF_CLIENT |
DrawingOptions.PRF_NONCLIENT |
DrawingOptions.PRF_CHILDREN);
}
finally
{
g.ReleaseHdc();
}
}
pictureBox1.Image = bm;
This code helped to save the form image and displays ActiveX perfectly. Since the item is static, I'll just crop the image and get the screenshot I want.
[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags);
public static Bitmap PrintWindow(IntPtr hwnd)
{
RECT rc;
GetWindowRect(hwnd, out rc);
Bitmap bmp = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb);
Graphics gfxBmp = Graphics.FromImage(bmp);
IntPtr hdcBitmap = gfxBmp.GetHdc();
PrintWindow(hwnd, hdcBitmap, 0);
gfxBmp.ReleaseHdc(hdcBitmap);
gfxBmp.Dispose();
return bmp;
}

How to capture Outlook Form Region as a image? VSTO Outlook Addin

I want to save a image of a completed Form in Outlook. I am using VSTO Outlook Addin. I am able to capture a full screen image, but I am having no luck with the form region by its self. Does anyone have any ideas?
var bmpScreenshot = new Bitmap(this.Width,
this.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
var grxScreenshot = Graphics.FromImage(bmpScreenshot);
grxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
string outputFileName = #"C:\Users\63530\Desktop\image.png";
using (MemoryStream memory = new MemoryStream())
{
using (FileStream fs = new FileStream(outputFileName, FileMode.Create, FileAccess.ReadWrite))
{
bmpScreenshot.Save(memory, ImageFormat.Png);
byte[] bytes = memory.ToArray();
fs.Write(bytes, 0, bytes.Length);
}
}
This is how I capture any window content. I hope it helps you, but it is not clear what is this you want to capture. This code works even if the window is not in foreground.
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags);
public static Bitmap GetSnapshot(IntPtr hWnd) // capture a window by its handle
{
Int32 windowLeft;
Int32 windowTop;
Int32 windowWidth;
Int32 windowHeight;
if (hWnd == IntPtr.Zero) return null;
if (!GetWindowRect(hWnd, out windowLeft, out windowTop, out windowWidth, out windowHeight)) return null;
Bitmap bmp = new Bitmap(windowWidth, windowHeight, PixelFormat.Format32bppArgb);
Graphics gfxBmp = Graphics.FromImage(bmp);
IntPtr hdcBitmap = gfxBmp.GetHdc();
PrintWindow(hWnd, hdcBitmap, 0); // from user32.dll
gfxBmp.ReleaseHdc(hdcBitmap);
gfxBmp.Dispose();
return bmp;
}
private static bool GetWindowRect(IntPtr hWnd, out Int32 left, out Int32 top, out Int32 width, out Int32 height)
{
left = 0;
top = 0;
width = 0;
height = 0;
RECT rct = new RECT();
if (!GetWindowRect(hWnd, ref rct)) return false; // from user32.dll
left = rct.Left;
top = rct.Top;
width = rct.Right - rct.Left + 1;
height = rct.Bottom - rct.Top + 1;
return true;
}
public struct RECT
{
public Int32 Left;
public Int32 Top;
public Int32 Right;
public Int32 Bottom;
}

Drawing Window to Image file

Anyone know why this keeps returning a blank image? I found this function here.
I pass in a handle to a notepad process/window.
public static Image DrawToBitmap(IntPtr handle)
{
Bitmap image = new Bitmap(500, 500, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (Graphics graphics = Graphics.FromImage(image))
{
IntPtr hDC = graphics.GetHdc();
SendMessage(new HandleRef(graphics, handle), WM_PRINT, hDC, PRF_CHILDREN);
graphics.ReleaseHdc(hDC);
}
return image;
}
I make use of the above like so:
Image myimage = DrawToBitmap(handle);
myimage.Save("C:\\here.png", ImageFormat.Png);
Thanks all for any help
Update
I think I have managed to get the error code from SendMessage using the below:
if (SendMessage(handle, WM_PRINT, hDC, PRF_CLIENT))
{
Console.WriteLine("Success!");
}
else
{
Console.WriteLine("Error: " + Marshal.GetLastWin32Error());
}
I get an error of 8 and I found it means not enough memory? I have over 500MB free! Maybe I am understanding this wrong?
Instead of SendMessage you could just use PrintWindow
Here is a sample
public static Image DrawToBitmap(IntPtr handle)
{
RECT rect = new RECT();
GetWindowRect(handle, ref rect);
Bitmap image = new Bitmap(rect.Right - rect.Left, rect.Bottom - rect.Top);
using (Graphics graphics = Graphics.FromImage(image))
{
IntPtr hDC = graphics.GetHdc();
PrintWindow(new HandleRef(graphics, handle), hDC, 0);
graphics.ReleaseHdc(hDC);
}
return image;
}
#region Interop
[DllImport("USER32.DLL")]
private static extern bool PrintWindow(HandleRef hwnd, IntPtr hdcBlt, int nFlags);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
#endregion
Try passing PRF_CLIENT or PRF_NONCLIENT to SendMessage in addition to PRF_CHILDREN.
Also, how are you deriving the handle that you are passing to the function?

How to get the screenshot of the form

Any method to output the screenshot of an active form?
Even simpler answer supported by .NET:
Control.DrawToBitmap.
Use the Control.DrawToBitmap() method. For example:
private void timer1_Tick(object sender, EventArgs e) {
var frm = Form.ActiveForm;
using (var bmp = new Bitmap(frm.Width, frm.Height)) {
frm.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
bmp.Save(#"c:\temp\screenshot.png");
}
}
Try this:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
namespace ScreenshotCapturer
{
public partial class Form1 : Form
{
private static Bitmap bmpScreenshot;
private static Graphics gfxScreenshot;
public Form1()
{
InitializeComponent();
}
private void btnCapture_Click(object sender, EventArgs e)
{
// If the user has choosed a path where to save the screenshot
if (saveScreenshot.ShowDialog() == DialogResult.OK)
{
// Hide the form so that it does not appear in the screenshot
this.Hide();
// Set the bitmap object to the size of the screen
bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap
gfxScreenshot = Graphics.FromImage(bmpScreenshot);
// Take the screenshot from the upper left corner to the right bottom corner
gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
// Save the screenshot to the specified path that the user has chosen
bmpScreenshot.Save(saveScreenshot.FileName, ImageFormat.Png);
// Show the form again
this.Show();
}
}
}
}
Here's an extension method you can use:
#region Interop
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr hdc, PRF_FLAGS drawingOptions);
const uint WM_PRINT = 0x317;
[Flags]
enum PRF_FLAGS : uint
{
CHECKVISIBLE = 0x01,
CHILDREN = 0x02,
CLIENT = 0x04,
ERASEBKGND = 0x08,
NONCLIENT = 0x10,
OWNED = 0x20
}
#endregion
public static Image CaptureImage(this Control control)
{
Image img = new Bitmap(control.Width, control.Height);
using (Graphics g = Graphics.FromImage(img))
{
SendMessage(
control.Handle,
WM_PRINT,
g.GetHdc(),
PRF_FLAGS.CLIENT | PRF_FLAGS.NONCLIENT | PRF_FLAGS.ERASEBKGND);
}
return img;
}
Form inherits from Control, so you can use it on a form too.
Because Control.DrawToBitmap has some limitations (most notably drawing child controls in reverse order) I have made this alternative. The variable _control is the WinForms Control/Form that you want to copy.
using (Bitmap bitmap = new Bitmap(width, height)) {
using (Graphics gb = Graphics.FromImage(bitmap))
using (Graphics gc = Graphics.FromHwnd(_control.Handle)) {
IntPtr hdcDest = IntPtr.Zero;
IntPtr hdcSrc = IntPtr.Zero;
try {
hdcDest = gb.GetHdc();
hdcSrc = gc.GetHdc();
BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRC_COPY);
} finally {
if (hdcDest != IntPtr.Zero) gb.ReleaseHdc(hdcDest);
if (hdcSrc != IntPtr.Zero) gc.ReleaseHdc(hdcSrc);
}
}
bitmap.Save(...);
}
[DllImport("gdi32.dll", EntryPoint = "BitBlt")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool BitBlt(
[In()] System.IntPtr hdc, int x, int y, int cx, int cy,
[In()] System.IntPtr hdcSrc, int x1, int y1, uint rop);
private const int SRC_COPY = 0xCC0020;
this.Opacity = 0;
Rectangle bounds = Screen.GetBounds(Point.Empty);
// create the bitmap to copy the screen shot to
Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
// now copy the screen image to the graphics device from the bitmap
using (Graphics gr = Graphics.FromImage(bitmap))
{
gr.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
}
this.Opacity = 100;
Now just
gr.Save(#"c\pic.jpg",ImageFormat.jpg);
This will save a screenshot of your active window to your C: drive.
The SendKeys.Send("") is used to send keypresses to the computer. In this case % is used to press Alt and {PRTSC} obviously to press the Print Screen button on your keyboard.
Hope this helps someone!
private void printScreenButton_Click(object sender, EventArgs e)
{
SendKeys.Send("%{PRTSC}");
Image img = Clipboard.GetImage();
img.Save(#"C:\\testprintscreen.jpg");
}
here is:
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 bool StretchBlt(
IntPtr hdcDest, // handle to destination DC
int nXOriginDest, // x-coord of destination upper-left corner
int nYOriginDest, // y-coord of destination upper-left corner
int nWidthDest, // width of destination rectangle
int nHeightDest, // height of destination rectangle
IntPtr hdcSrc, // handle to source DC
int nXOriginSrc, // x-coord of source upper-left corner
int nYOriginSrc, // y-coord of source upper-left corner
int nWidthSrc, // width of source rectangle
int nHeightSrc, // height of source rectangle
int dwRop // raster operation code
);
[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);
[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 void run_test()
{
Rectangle rc = new Rectangle();
Image img = ScreenToImage(ref rc, false);
img.Save(#"C:\Users\ssaamm\Desktop\Capt44ure.JPG", System.Drawing.Imaging.ImageFormat.Jpeg);
img.Dispose();
}
private Image ScreenToImage(ref Rectangle rcDest, bool IsPapaer)
{
IntPtr handle = this.Handle;
//this.Handle
// get te hDC of the target window
IntPtr hdcSrc = GetWindowDC(handle);
// get the size
RECT windowRect = new RECT();
GetWindowRect(handle, ref windowRect);
int nWidth = windowRect.right - windowRect.left;
int nHeight = windowRect.bottom - windowRect.top;
if (IsPapaer)
{
float fRate = (float)rcDest.Width / nWidth;
//float fHeight = nHeight * fRate;
//rcDest.Height = (int)(nHeight * fRate);
//rcDest.Width = (int)(rcDest.Width);// * fRate);
rcDest.X = 0;
rcDest.Y = 0;
rcDest.Height = (int)(nHeight * fRate);
//rcDest.Width = (int)(nWidth * fRate);
}
else
{
rcDest.X = 0;
rcDest.Y = 0;
rcDest.Height = nHeight;
rcDest.Width = nWidth;
}
// create a device context we can copy to
IntPtr hdcDest = CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = CreateCompatibleBitmap(hdcSrc, rcDest.Width, rcDest.Height);
// select the bitmap object
IntPtr hOld = SelectObject(hdcDest, hBitmap);
// bitblt over
StretchBlt(hdcDest, rcDest.X, rcDest.Y, rcDest.Width, rcDest.Height, hdcSrc, 0, 0, nWidth, nHeight, SRCCOPY);
// restore selection
SelectObject(hdcDest, hOld);
// clean up
DeleteDC(hdcDest);
ReleaseDC(handle, hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
DeleteObject(hBitmap);
return img;
}

Categories