Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The answer is as others have stated, probably "No, you cannot take a screenshot of a random window from an hwnd without native methods.". Couple of caveats before I show it:</p> <p><strong>Forewarning:</strong></p> <p>For anyone who wants to use this code, note that the size given from the VisibleClipBounds is only <em>inside</em> the window, and does <em>not</em> include the border or title bar. It's the drawable area. If you had that, you might be able to do this without p/invoke.</p> <p>(If you could calculate the border of the browser window, you could use the VisibleClipBounds. If you wanted, you could use the <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.systeminformation_properties.aspx" rel="nofollow noreferrer"><code>SystemInformation</code></a> object to get important info like <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.systeminformation.border3dsize.aspx" rel="nofollow noreferrer"><code>Border3DSize</code></a>, or you could try to calculate it by creating a dummy form and <a href="http://ivision.wordpress.com/2007/01/05/title-bar-height-and-form-border-width-of-net-form/" rel="nofollow noreferrer">deriving the border and title bar height from that</a>, but that all sounds like the black magic that bugs are made of.)</p> <p>This is equivalent to Ctrl+Printscreen of the window. This also does not do the niceties that the WatiN screenshot capability does, such as scroll the browser and take an image of the whole page. This is suitable for my project, but may not be for yours.</p> <p><strong>Enhancements:</strong></p> <p>This could be changed to be an extension method if you're in .NET 3 and up-land, and an option for the image type could be added pretty easily (I default to <code>ImageFormat.Bmp</code> for this example).</p> <p><strong>Code:</strong></p> <pre><code>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; } } /// &lt;summary&gt; /// Takes a screenshot of the browser. /// &lt;/summary&gt; /// &lt;param name="b"&gt;The browser object.&lt;/param&gt; /// &lt;param name="filename"&gt;The path to store the file.&lt;/param&gt; /// &lt;returns&gt;&lt;/returns&gt; 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; } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload