【发布时间】:2011-02-28 12:19:59
【问题描述】:
我正在尝试截取应用程序的屏幕截图,并且我想让矩形中不属于应用程序区域的部分透明。因此,例如在标准 Windows 应用程序上,我想让圆角透明。
我写了一个快速的测试应用程序,它可以在 XP(或关闭 aero 的 vista/windows 7)上运行:
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(或关闭 Aero 的 Vista/Windows 7)上运行这个测试应用程序时,我得到了类似的结果,这很棒,因为我可以从中找到一个 xor 掩码,以后可以与 BitBlt 一起使用。
删除了死掉的 Imageshack 链接 - 屏幕截图
这就是问题所在,在启用 Aero 的 Vista 或 Windows 7 上,窗口上不一定有区域,事实上在大多数情况下没有。谁能帮我想办法在这些平台上构建这样的面具?
以下是我已经尝试过的一些方法...
1.使用PrintWindow 函数:这不起作用,因为它会返回关闭 Aero 的窗口的屏幕截图,并且此窗口与打开 Aero 时返回的窗口的形状不同
2 使用Desktop Window Manager API 获取全尺寸缩略图:这不起作用,因为它直接绘制到屏幕上,据我所知,您无法直接获取屏幕截图这个api的。是的,我可以打开一个粉红色背景的窗口,显示缩略图,截屏然后隐藏这个临时窗口,但那是一种糟糕的用户体验和一个完整的黑客,我宁愿没有我的名字。
3.使用 Graphics.CopyFromScreen 或其他一些 pinvoke 变体: 这不起作用,因为我不能假设我需要从中获取信息的窗口位于屏幕 z 顺序的顶部。
现在,我能想到的最佳解决方案是在 Windows 7 和 Vista 上使用特殊情况 Aero,通过硬编码我绘制的一些图形路径来手动擦掉角落,但这个解决方案会很糟糕,因为任何执行自定义蒙皮的应用程序会打破这个。
你能想出另一个或更好的解决方案吗?
如果您在这里,感谢您花时间阅读这篇文章,感谢您提供的任何帮助或指导!
【问题讨论】:
-
有趣且经过深思熟虑的问题,希望得到更多关注。
-
您正在使用
GetWindowRgn()来获取窗口的区域。如果您使用GetWindowDC()代替(获取包括标题栏在内的窗口的 DC)然后使用SelectObject()或GetObject()以这种方式检索区域会发生什么?有什么不同吗?还有GetClipRgn()可能会返回不同的形状。 -
我没有尝试过这种方法,我会在这个周末尝试一下。
标签: c# windows-7 gdi+ gdi windows-vista