Формы с установленным свойством TransparencyKey или Opacity являются так называемыми многоуровневыми окнами. Они отображаются с помощью функции «наложения» видеоадаптера. Что позволяет им иметь эффект прозрачности.
Для их захвата необходимо включить параметр CopyPixelOperation.CaptureBlt в перегрузке CopyFromScreen, которая принимает аргумент CopyPixelOperation.
К сожалению, эта перегрузка имеет критическую ошибку, которая мешает этому работать. Это не проверяет значение должным образом. Все еще не исправлено в .NET 4.0. Нет другого хорошего решения, кроме как использовать P / Invoke для создания снимка экрана. Вот пример:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
Size sz = Screen.PrimaryScreen.Bounds.Size;
IntPtr hDesk = GetDesktopWindow();
IntPtr hSrce = GetWindowDC(hDesk);
IntPtr hDest = CreateCompatibleDC(hSrce);
IntPtr hBmp = CreateCompatibleBitmap(hSrce, sz.Width, sz.Height);
IntPtr hOldBmp = SelectObject(hDest, hBmp);
bool b = BitBlt(hDest, 0, 0, sz.Width, sz.Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
Bitmap bmp = Bitmap.FromHbitmap(hBmp);
SelectObject(hDest, hOldBmp);
DeleteObject(hBmp);
DeleteDC(hDest);
ReleaseDC(hDesk, hSrce);
bmp.Save(@"c:\temp\test.png");
bmp.Dispose();
}
// P/Invoke declarations
[DllImport("gdi32.dll")]
static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int
wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, CopyPixelOperation rop);
[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);
[DllImport("gdi32.dll")]
static extern IntPtr DeleteDC(IntPtr hDc);
[DllImport("gdi32.dll")]
static extern IntPtr DeleteObject(IntPtr hDc);
[DllImport("gdi32.dll")]
static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
[DllImport("gdi32.dll")]
static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")]
static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr ptr);
}
}
Fwiw, более поздняя версия Windows предоставила обходной путь для этой ошибки. Не совсем уверен, какой, я думаю, что это был Win7 SP1. Функция BitBlt () теперь будет делать то, что вы хотите, если вы передаете только опцию CopyPixelOperation.CaptureBlt. Но, конечно, этот обходной путь не применялся ретроактивно к более ранним версиям Windows, поэтому вы не можете от него зависеть.