2009-04-12 53 views
0

我对Vista的理解是,每个窗口都会获得自己的屏幕缓冲区,然后通过alpha混合等来创建屏幕。在Vista中捕获隐藏的窗口

那么,有没有什么办法可以截屏,其被遮挡或部分通过直接读取这些缓冲区关闭屏幕的窗口?当您将鼠标悬停在任务栏上或将鼠标悬停在任务栏上时,Vista会执行此操作。

我在德尔福这样做,但在任何语言的代码就足够了。

回答

2

我相信这些缓冲区时做这些窗口都关闭屏幕不存在。或者部分离屏时部分存在。

如果你留意窗口的缩略图,你会发现,当这些窗口最小化或关闭屏幕也不会更新。 WM_PAINT将在窗口被从屏幕拖动到打开时触发,这再次表明此数据尚未缓存在某处。

+0

的缓冲器是肯定有的,而被更新。开始播放视频,用另一个窗口覆盖它,将鼠标悬停在工具栏上,然后获得播放视频的缩略图。 – 2009-04-12 12:40:55

0

下面是一些代码,我写了很久以前在C#中的屏幕捕获应用程序。它使用Win32函数GetWindowRect得到你想要捕捉,创建与大小的位图,然后使用Win32函数PrintWindow询问窗口本身打印到该位图的窗口的范围:

RECT lRectangle = new RECT(); 
if (!GetWindowRect(lWindow.HWnd, ref lRectangle)) 
{ 
    MessageBox.Show(this, "An error occured while measuring the selected window.", Text, MessageBoxButtons.OK, MessageBoxIcon.Error); 
    return; 
} 

fCapturedImage = new Bitmap(lRectangle.Right - lRectangle.Left, lRectangle.Bottom - lRectangle.Top, PixelFormat.Format32bppArgb); 
using (Graphics lGraphics = Graphics.FromImage(fCapturedImage)) 
{ 
    HDC lHdc = lGraphics.GetHdc(); 
    PrintWindow(lWindow.HWnd, lHdc, 0); 
    lGraphics.ReleaseHdc(lHdc); 
} 
0

具有u considired挂钩WM_PAINT消息有用吗? “Windows图形编程:Win32 GDI和DirectDraw”的作者冯远为此提出了示例dll。我认为用这种方式也可以捕获DirectXed窗口(随时都可以使用它)。 PLZ参考http://www.fengyuan.com/article/wmprint.html 你可以通过谷歌找到工作的delphi例子。也检查expterts-exchange.com

0

我认为可能是在新的DWM APi(桌面Windows管理器),让你编写和安装自定义桌面管理器,访问您看到在Flip3d和其他相同的缩略图观点。

0

做到这一点(C#)

public static Bitmap PrintWindow(IntPtr hwnd) 
    { 
     RECT rc; 
     WinUserApi.GetWindowRect(hwnd, out rc); 

     Bitmap bmp = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb); 
     Graphics gfxBmp = Graphics.FromImage(bmp); 
     IntPtr hdcBitmap = gfxBmp.GetHdc(); 
     bool succeeded = WinUserApi.PrintWindow(hwnd, hdcBitmap, 0); 
     gfxBmp.ReleaseHdc(hdcBitmap); 
     if (!succeeded) 
     { 
      gfxBmp.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(Point.Empty, bmp.Size)); 
     } 
     IntPtr hRgn = WinGdiApi.CreateRectRgn(0, 0, 0, 0); 
     WinUserApi.GetWindowRgn(hwnd, hRgn); 
     Region region = Region.FromHrgn(hRgn); 
     if (!region.IsEmpty(gfxBmp)) 
     { 
      gfxBmp.ExcludeClip(region); 
      gfxBmp.Clear(Color.Transparent); 
     } 
     gfxBmp.Dispose(); 
     return bmp; 
    }