Я пытаюсь сделать снимок экрана приложения, и я хотел бы сделать части прямоугольника, которые не являются частью области приложений, прозрачными. Так, например, в стандартном приложении Windows я хотел бы сделать округленные углы прозрачными.
Я написал быстрое приложение test, которое работает на XP (или vista/windows 7 с отключенным aero):
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
// Just find a window to test with
IntPtr hwnd = FindWindowByCaption(IntPtr.Zero, "Calculator");
WINDOWINFO info = new WINDOWINFO();
info.cbSize = (uint)Marshal.SizeOf(info);
GetWindowInfo(hwnd, ref info);
Rectangle r = Rectangle.FromLTRB(info.rcWindow.Left, info.rcWindow.Top, info.rcWindow.Right, info.rcWindow.Bottom);
IntPtr hrgn = CreateRectRgn(info.rcWindow.Left, info.rcWindow.Top, info.rcWindow.Right, info.rcWindow.Bottom);
GetWindowRgn(hwnd, hrgn);
// fill a rectangle which would be where I would probably
// write some mask color
g.FillRectangle(Brushes.Red, r);
// fill the region over the top, all I am trying to do here
// is show the contrast between the applications region and
// the rectangle that the region would be placed in
Region region = Region.FromHrgn(hrgn);
region.Translate(info.rcWindow.Left, info.rcWindow.Top);
g.FillRegion(Brushes.Blue, region);
}
Когда я запускаю это тестовое приложение на XP (или Vista/Windows 7 с отключенным Aero), я получаю что-то вроде этого, и это здорово, потому что я могу использовать маску xor из этого, которую можно использовать позже с BitBlt.
удалена мертвая ссылка Imageshack - Скриншот
Вот проблема, на Vista или Windows 7 с включенным Aero, в окне не обязательно есть область, на самом деле в большинстве случаев ее нет. Может ли кто-нибудь помочь мне выяснить способ создания такой маски на этих платформах?
Вот некоторые из подходов, которые я уже пробовал...
1. Использование функции PrintWindow: Это не работает, потому что она возвращает скриншот из окна с отключенным Aero и этим окном это другая форма из окна, возвращенного с помощью Aero on
2 Используя Desktop Window Manager API, чтобы получить миниатюру полного размера: Это не сработало, потому что он обращается непосредственно к экрану и из того, что я могу сказать, вы не можете получить скриншот прямо из этого api. Да, я мог бы открыть окно с розовым фоном, показать миниатюру, снять скриншот, затем скрыть это временное окно, но это ужасный пользовательский интерфейс и полный хак, я бы предпочел не иметь мое имя.
3. Используя Graphics.CopyFromScreen или какой-либо другой вариант pinvoke этого: Это не работает, потому что я не могу предположить, что это окно Мне нужна информация, находящаяся в верхней части z-порядка на экране.
В настоящее время лучшим решением, которое я могу придумать, является специальный случай Aero в Windows 7 и Vista, чтобы вручную вытереть углы, жестко кодируя некоторые графические пути, которые я рисую, но это решение будет сосать, поскольку любое приложение, которое выполняет пользовательское скинирование нарушит это.
Можете ли вы придумать другое или лучшее решение?
Если вы здесь, спасибо за то, что нашли время, чтобы прочитать это сообщение, я ценю любую помощь или направление, которые вы можете предложить!