Я пытаюсь сделать снимок экрана приложения, и я хотел бы сделать части прямоугольника, которые не входят в область приложений, прозрачными. Так, например, в стандартном приложении Windows я хотел бы сделать закругленные углы прозрачными.
Я написал быстрое тестовое приложение, которое работает на 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 при
.
2 Использование Desktop Window Manager API для получения миниатюры в натуральную величину: Это не сработало, потому что оно рисует прямо на экране и, как я могу сказать, вы можете ' получить скриншот прямо из этого API. Да, я мог бы открыть окно с розовым фоном, показать миниатюру, сделать снимок экрана, а затем скрыть это временное окно, но это ужасный пользовательский опыт и полный взлом, я бы предпочел, чтобы мое имя не отображалось.
3. Используя Graphics.CopyFromScreen или какой-либо другой вариант пинвока: Это не работает, потому что я не могу предположить, что окно, из которого мне нужна информация, находится в верхней части z-порядка на экран.
На данный момент лучшее решение, которое я могу придумать, - это особый случай Aero в Windows 7 и Vista, чтобы вручную стирать углы, жестко кодируя некоторые графические контуры, которые я рисую, но это решение будет неудачным, поскольку любое приложение, выполняющее пользовательский скиннинг сломаю это.
Можете ли вы придумать другое или лучшее решение?
Если вы здесь, спасибо, что нашли время прочитать этот пост, я ценю любую помощь или направление, которое вы можете предложить!