使用Print Screen
+Alt
键组合手动捕获窗口时,我得到以下信息:
但如果我尝试使用Windows API以编程方式执行此操作,我会得到以下信息:
为什么会出现差异?如何以编程方式获得第一个?
这是我的代码:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags);
public Bitmap PrintWindow()
{
Bitmap bmp = new Bitmap(windowRect.Width, windowRect.Height, PixelFormat.Format32bppArgb);
Graphics gfxBmp = Graphics.FromImage(bmp);
IntPtr hdcBitmap = gfxBmp.GetHdc();
bool success = PrintWindow(windowHandle, hdcBitmap, 0);
gfxBmp.ReleaseHdc(hdcBitmap);
if (!success)
{
Console.WriteLine("Error copying image");
Console.WriteLine(getLastError());
}
gfxBmp.Dispose();
return bmp;
}
更新: 用 BitBlt 做同样的事情。
下面是来自 CodeProject 的代码,它仍然返回一个黑色蒙版图像:
public Image CaptureWindow(IntPtr handle)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle,ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc,width,height);
// select the bitmap object
IntPtr hOld = GDI32.SelectObject(hdcDest,hBitmap);
// bitblt over
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
// restore selection
GDI32.SelectObject(hdcDest,hOld);
// clean up
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle,hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
GDI32.DeleteObject(hBitmap);
img.Save("SampleImage.png");
return img;
}
我尝试了许多CopyPixelOperation
, 的组合(大约 131,000 个中的 15,000 个),但它仍然不起作用。
使用 Windows 8、AMD Radeon HD 6870。
更新 2
看起来窗户是透明的,让窗户的蓝色渗出。当我将窗口颜色更改为黑色(使用 Windows 个性化对话框)时,我得到的内容与第二个窗口大致相似。但边界仍然缺失。
我还没有找到解决方案,但它是对问题的洞察力。