微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

捕获屏幕截图包括.NET中的半透明窗口

我想要一个相对黑客的方式来做到这一点,任何想法? 例如,下面的截图不包含半透明窗口:

Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object,ByVal e As System.EventArgs) Handles MyBase.Shown Text = "Opaque Window" Dim win2 As New Form win2.Opacity = 0.5 win2.Text = "Tranparent Window" win2.Show() win2.Top = Top + 50 win2.Left = Left() + 50 Dim bounds As Rectangle = System.Windows.Forms.Screen.GetBounds(Point.Empty) Using bmp As Bitmap = New Bitmap(bounds.Width,bounds.Height) Using g As Graphics = Graphics.FromImage(bmp) g.copyFromScreen(Point.Empty,Point.Empty,bounds.Size) End Using bmp.Save("c:tempscn.gif") End Using Process.Start(New Diagnostics.processstartinfo("c:tempscn.gif") With {.UseShellExecute = True}) End Sub End Class

要么我的谷歌真的很糟糕,或者这听起来不容易。 我很确定为什么会发生这种情况,因为video驱动程序将不得不分开内存来完成这个工作,但我不在乎它为什么不起作用,我只是想不这样做…

*打印屏幕键的黑客

*第三方软件

* SDKfunction是好的,但我会upVote用户拥有的每个对象,可以让我看看它在纯粹的框架(只是在开玩笑,但它会很好)。

如果这是唯一的方法,如何在VB中做到这一点?

1M谢谢。

需要什么权限才能使用System.Net.HttpListener而不添加命名空间预留?

如何使C#应用程序充当服务?

如何使用visual basic.net express版本安装Windows服务?

为什么.NET应用程序阻止Windowsclosures?

授予在没有UAC提示的情况下启动时启动的应用程序的pipe理员权限?

第二台显示器全屏窗口

如何编写一个连续监听的服务器作为服务

在.NET中,当你最小化程序时,垃圾回收器会被调用吗?

使用Bonjour而不在Win7上安装框架

在.NET中获取目录数据的最快方法

具有TransparencyKey或Opacity属性的窗体就是所谓的分层窗口。 它们使用视频适配器的“覆盖”功能显示。 这使得他们能够获得透明度的效果

捕获它们需要打开接受copyPixelOperation参数的copyFromScreen重载中的copyPixelOperation.CaptureBlt选项。

不幸的是,这个超载有一个严重的错误,阻止这个工作。 它不适当地验证值。 在.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,sz.Height,hSrce,copyPixelOperation.sourcecopy | copyPixelOperation.CaptureBlt); Bitmap bmp = Bitmap.FromHbitmap(hBmp); SelectObject(hDest,hOldBmp); DeleteObject(hBmp); DeleteDC(hDest); ReleaseDC(hDesk,hSrce); bmp.Save(@"c:temptest.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版本提供了一个解决这个bug的方法。 不完全确定,我认为这是Win7 SP1。 如果只传递copyPixelOperation.CaptureBlt选项,BitBlt()函数现在将执行所需的操作。 但是,当然,这种解决方法并不适用于早期的Windows版本,因此您不能真正依赖它。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐