Ответ, как говорили другие, вероятно, «Нет, вы не можете сделать скриншот случайного окна из hwnd без нативных методов». Несколько предостережений, прежде чем я покажу это:
предостережение:
Для тех, кто хочет использовать этот код, обратите внимание, что размер, указанный в VisibleClipBounds, составляет всего внутри окна, и не включает в себя границу или строку заголовка. Это нарисованная область. Если бы у вас было это, вы могли бы сделать это без p / invoke.
(Если бы вы могли вычислить границу окна браузера, вы могли бы использовать VisibleClipBounds. При желании вы могли бы использовать объект SystemInformation
для получения важной информации, такой как Border3DSize
, или вы можете попытаться вычислить ее, создав фиктивную форму и извлекая границу и высоту строки заголовка из этого , но все это звучит как черная магия, из которой сделаны ошибки.)
Это эквивалентно Ctrl + Printscreen окна. Это также не делает тонкостей, которые делает возможность скриншота WatiN, таких как прокрутка браузера и получение изображения всей страницы. Это подходит для моего проекта, но не для вашего.
Улучшения:
Это можно изменить как метод расширения, если вы находитесь в .NET 3 и работаете на более высоком уровне, и опцию для типа изображения можно добавить довольно легко (для этого примера по умолчанию ImageFormat.Bmp
).
Код:
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
public class Screenshot
{
class NativeMethods
{
// http://msdn.microsoft.com/en-us/library/ms633519(VS.85).aspx
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
// http://msdn.microsoft.com/en-us/library/a5ch4fda(VS.80).aspx
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
}
/// <summary>
/// Takes a screenshot of the browser.
/// </summary>
/// <param name="b">The browser object.</param>
/// <param name="filename">The path to store the file.</param>
/// <returns></returns>
public static bool SaveScreenshot(Browser b, string filename)
{
bool success = false;
IntPtr hWnd = b.hWnd;
NativeMethods.RECT rect = new NativeMethods.RECT();
if (NativeMethods.GetWindowRect(hWnd, ref rect))
{
Size size = new Size(rect.Right - rect.Left,
rect.Bottom - rect.Top);
// Get information about the screen
using (Graphics browserGraphics = Graphics.FromHwnd(hWnd))
// apply that info to a bitmap...
using (Bitmap screenshot = new Bitmap(size.Width, size.Height,
browserGraphics))
// and create an Graphics to manipulate that bitmap.
using (Graphics imageGraphics = Graphics.FromImage(screenshot))
{
int hWndX = rect.Left;
int hWndY = rect.Top;
imageGraphics.CopyFromScreen(hWndX, hWndY, 0, 0, size);
screenshot.Save(filename, ImageFormat.Bmp);
success = true;
}
}
// otherwise, fails.
return success;
}
}