Re: capture screen even when workstation is locked
- From: "Jeremy Chapman" <me@xxxxxxxx>
- Date: Wed, 14 Dec 2005 15:05:48 -0800
Thanks for the info. After a little more searching with your direction, I
think I found a solution (only on xp and 2003) using the PrintWindow API.
Thought i'd share. I tried the WM_Print message but couldn't get it to work
at all with the window I wanted to capture. Doing a BitBlt also worked, but
not when the workstation was locked.
public class gdi32
{
private class Externs
{
[System.Runtime.InteropServices.DllImport(strGDI32DLL,
CharSet=CharSet.Auto, SetLastError=true)]
public static extern int GetDeviceCaps(int iHdc,int iIndex);
}
/// <summary>
///
/// </summary>
/// <param name="iHdc"></param>
/// <param name="eIndex"></param>
/// <returns></returns>
public static int GetDeviceCaps(int iHdc,enCapsIndex eIndex)
{
return Externs.GetDeviceCaps(iHdc,(int)eIndex);
}
/// <summary>
///
/// </summary>
public enum enCapsIndex
{
/// <summary>
/// The device driver version.
/// </summary>
DRIVERVERSION = 0,
/// <summary>
/// Device technology.
/// </summary>
TECHNOLOGY = 2,
/// <summary>
/// Width, in millimeters, of the physical screen.
/// </summary>
HORZSIZE = 4,
/// <summary>
/// Height, in millimeters, of the physical screen.
/// </summary>
VERTSIZE = 6,
/// <summary>
/// Width, in pixels, of the screen.
/// </summary>
HORZRES = 8,
/// <summary>
/// Height, in raster lines, of the screen.
/// </summary>
VERTRES = 10,
/// <summary>
/// Number of pixels per logical inch along the screen width. In a system
with multiple display monitors, this value is the same for all monitors.
/// </summary>
LOGPIXELSX = 88,
/// <summary>
/// Number of pixels per logical inch along the screen height. In a
system with multiple display monitors, this value is the same for all
monitors.
/// </summary>
LOGPIXELSY = 90,
/// <summary>
/// Number of adjacent color bits for each pixel.
/// </summary>
BITSPIXEL = 12,
/// <summary>
/// Number of color planes.
/// </summary>
PLANES = 14,
/// <summary>
/// Number of device-specific brushes.
/// </summary>
NUMBRUSHES = 16,
/// <summary>
/// Number of device-specific pens.
/// </summary>
NUMPENS = 18,
/// <summary>
/// Number of device-specific markers.
/// </summary>
NUMMARKERS = 20,
/// <summary>
/// Number of device-specific fonts.
/// </summary>
NUMFONTS = 22,
/// <summary>
/// Number of entries in the device's color table, if the device has a
color depth of no more than 8 bits per pixel. For devices with greater color
depths, 1 is returned.
/// </summary>
NUMCOLORS = 24,
/// <summary>
/// Reserved.
/// </summary>
PDEVICESIZE = 26,
/// <summary>
/// Value that indicates the curve capabilities of the device, as shown
in the following table.
/// </summary>
CURVECAPS = 28,
/// <summary>
/// Value that indicates the line capabilities of the device, as shown in
the following table:
/// </summary>
LINECAPS = 30,
/// <summary>
/// Value that indicates the polygon capabilities of the device, as shown
in the following table.
/// </summary>
POLYGONALCAPS = 32,
/// <summary>
/// Value that indicates the text capabilities of the device, as shown in
the following table.
/// </summary>
TEXTCAPS = 34,
/// <summary>
/// Flag that indicates the clipping capabilities of the device. If the
device can clip to a rectangle, it is 1. Otherwise, it is 0.
/// </summary>
CLIPCAPS = 36,
/// <summary>
/// Value that indicates the raster capabilities of the device, as shown
in the following table.
/// </summary>
RASTERCAPS = 38,
/// <summary>
/// Relative width of a device pixel used for line drawing.
/// </summary>
ASPECTX = 40,
/// <summary>
/// Relative height of a device pixel used for line drawing.
/// </summary>
ASPECTY = 42,
/// <summary>
/// Diagonal width of the device pixel used for line drawing.
/// </summary>
ASPECTXY = 44,
/// <summary>
/// For printing devices: the width of the physical page, in device
units. For example, a printer set to print at 600 dpi on 8.5-x11-inch paper
has a physical width value of 5100 device units. Note that the physical page
is almost always greater than the printable area of the page, and never
smaller.
/// </summary>
PHYSICALWIDTH = 110,
/// <summary>
/// For printing devices: the height of the physical page, in device
units. For example, a printer set to print at 600 dpi on 8.5-by-11-inch
paper has a physical height value of 6600 device units. Note that the
physical page is almost always greater than the printable area of the page,
and never smaller.
/// </summary>
PHYSICALHEIGHT = 111,
/// <summary>
/// For printing devices: the distance from the left edge of the physical
page to the left edge of the printable area, in device units. For example, a
printer set to print at 600 dpi on 8.5-by-11-inch paper, that cannot print
on the leftmost 0.25-inch of paper, has a horizontal physical offset of 150
device units.
/// </summary>
PHYSICALOFFSETX = 112, // Physical Printable Area x margin
/// <summary>
/// For printing devices: the distance from the top edge of the physical
page to the top edge of the printable area, in device units. For example, a
printer set to print at 600 dpi on 8.5-by-11-inch paper, that cannot print
on the topmost 0.5-inch of paper, has a vertical physical offset of 300
device units.
/// </summary>
PHYSICALOFFSETY = 113,
/// <summary>
/// Scaling factor for the x-axis of the printer.
/// </summary>
SCALINGFACTORX = 114,
/// <summary>
/// Scaling factor for the y-axis of the printer.
/// </summary>
SCALINGFACTORY = 115
}
}
public class User32
{
const string strUSER32DLL = "user32.dll";
private class Externs
{
[System.Runtime.InteropServices.DllImport(strUSER32DLL,
CharSet=CharSet.Auto, SetLastError=true)]
public static extern int PrintWindow(int iHwnd, int hdcBlt, uint iFlags);
}
/// <summary>
///
/// </summary>
/// <param name="hWnd"></param>
/// <param name="eFlags"></param>
/// <returns></returns>
public static System.Drawing.Bitmap PrintWindow(int hWnd,
enPrintWindowFlags eFlags)
{
int iWidth = 0;
int iHeight = 0;
int hdcSrc = User32.GetWindowDC(hWnd);
try
{
iWidth = gdi32.GetDeviceCaps(hdcSrc,gdi32.enCapsIndex.HORZRES);
iHeight = gdi32.GetDeviceCaps(hdcSrc,gdi32.enCapsIndex.VERTRES);
}
finally
{
User32.ReleaseDC(hWnd,hdcSrc);
}
System.Drawing.Bitmap pImage = new System.Drawing.Bitmap(iWidth,
iHeight);
System.Drawing.Graphics graphics =
System.Drawing.Graphics.FromImage(pImage);
IntPtr hDC = graphics.GetHdc();
//paint control onto graphics using provided options
try
{
Externs.PrintWindow(hWnd, (int)hDC, (uint)eFlags);
}
finally
{
graphics.ReleaseHdc(hDC);
}
return pImage;
}
public enum enPrintWindowFlags : uint
{
/// <summary>
///
/// </summary>
PW_ALL = 0x00000000,
/// <summary>
/// Only the client area of the window is copied. By default, the entire
window is copied.
/// </summary>
PW_CLIENTONLY = 0x00000001
}
}
"Stoitcho Goutsev (100) [C# MVP]" <100@xxxxxxx> wrote in message
news:efh$w1LAGHA.344@xxxxxxxxxxxxxxxxxxxxxxx
> Jeremy,
>
> No, it is not possible. If it was it would be a big security flaw. One of
> the reason people lock their stations is because they don't want anyone to
> be able to see what is on the screen.
>
> Secondly, You can grab only what is visible on the screen. You cannot
> capture anything that is not visible e.g. part of a window obscured by
> other window. When the workstation is locked there is nothing on the
> screen, but the dialog for unlocking the station.
>
> Windows provides a message called WM_PRINT this message is meant to be
> used to ask a window to draw itself to an arbitrary graphic device
> context. In theory it can be used for capturing invisible parts of a
> window, but this message needs to be handled and processed by the target
> application. I remember playing with this message when I was doing Win32
> native programming and it worked with all standard windows' controls, but
> almost never worked with third party controls and windows.
> Once I tried to use this in a .NET application but there were some problem
> with the Graphics object and I didn't have any success. However I gave up
> pretty quick because I did it out of curiosity only, it wasn't important.
> It might be possible to make it work with .NET application, I don't know.
>
>
> --
>
> Stoitcho Goutsev (100) [C# MVP]
>
> "Jeremy Chapman" <me@xxxxxxxx> wrote in message
> news:ORPS5AEAGHA.3048@xxxxxxxxxxxxxxxxxxxxxxx
>> Is it possible to grab a screen shot of an application window even when
>> the workstation is locked? I can do it when it's not locked but just get
>> a black image when it is locked.
>>
>
>
.
- References:
- capture screen even when workstation is locked
- From: Jeremy Chapman
- capture screen even when workstation is locked
- Prev by Date: Re: How do I display XML in the new .NET 2.0 WebBrowser control
- Next by Date: Error creating window handle
- Previous by thread: capture screen even when workstation is locked
- Next by thread: Re: capture screen even when workstation is locked
- Index(es):
Relevant Pages
|