积极答复者
关于image.fromhbitmap的错误

问题
-
textbox1 是窗口句柄,截图后,用 转成图片,执行次数多了,就会报错
于是我做了循环测试如下,大约执行一分到两分钟就报错,这是它报出来的错误,请问是哪里错了,该如何解决,谢谢
错误图片 :social.msdn.microsoft.com/Forums/getfile/1501111
Do While True SourceDC = GetWindowDC(TextBox1.Text) DestDC = CreateCompatibleDC(SourceDC) Bhandle = CreateCompatibleBitmap(SourceDC, Width, Height) SelectObject(DestDC, Bhandle) BitBlt(DestDC, 0, 0, Width, Height, SourceDC, Left, Top, &HCC0020) ReleaseDC(TextBox1.Text, SourceDC) PictureBox1.Image = Image.FromHbitmap(Bhandle) GC.Collect() Application.DoEvents() Loop
- 已移动 Sara LiuMicrosoft contingent staff 2019年11月7日 7:54
答案
-
應該是在 Image.FromHbitmap 後要釋放記憶體
參考在 Image.FromHbitmap 方法 中的注解 : DeleteObject GDI GDI Image方法会生成GDI位图的副本; 因此,可以在创建新的后立即使用方法释放传入的位图。 FromHbitmap
使用 DeleteObject 請參考 : Bitmap.GetHbitmap 方法 中的示例
在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/
- 已标记为答案 此显示名称已经被使用 2019年11月8日 7:53
-
DeleteObject对正在被Select的对象无效所以SelectObject的返回值要保存起来,用完了就恢复上一次的值。
ReleaseDC的参数是HWND类型,传字符串地址进去显然不会有效果。
CreateCompatibleDC创建的DC要用DeleteDC删除。
函数不熟一定要把文档先看一遍,这些都是MSDN的文档里的内容……
这些函数都是有返回值指示成功或者失败的,写代码要养成检查返回值的习惯。
Visual C++ MVP- 已标记为答案 此显示名称已经被使用 2019年11月8日 7:52
全部回复
-
應該是在 Image.FromHbitmap 後要釋放記憶體
參考在 Image.FromHbitmap 方法 中的注解 : DeleteObject GDI GDI Image方法会生成GDI位图的副本; 因此,可以在创建新的后立即使用方法释放传入的位图。 FromHbitmap
使用 DeleteObject 請參考 : Bitmap.GetHbitmap 方法 中的示例
在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/
- 已标记为答案 此显示名称已经被使用 2019年11月8日 7:53
-
應該是在 Image.FromHbitmap 後要釋放記憶體
參考在 Image.FromHbitmap 方法 中的注解 : DeleteObject GDI GDI Image方法会生成GDI位图的副本; 因此,可以在创建新的后立即使用方法释放传入的位图。 FromHbitmap
使用 DeleteObject 請參考 : Bitmap.GetHbitmap 方法 中的示例
在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/
Do While True SourceDC = GetWindowDC(TextBox1.Text) DestDC = CreateCompatibleDC(SourceDC) Bhandle = CreateCompatibleBitmap(SourceDC, Width, Height) SelectObject(DestDC, Bhandle) BitBlt(DestDC, 0, 0, Width, Height, SourceDC, Left, Top, &HCC0020) ReleaseDC(TextBox1.Text, SourceDC) DeleteObject(Bhandle) PictureBox1.Image = Image.FromHbitmap(Bhandle) GC.Collect() Application.DoEvents() Loop
你好,谢谢你的回答,我加了 DeleteObject 还是在PictureBox1.Image = Image.FromHbitmap(Bhandle)
这一行提示同样的错误 -
DeleteObject对正在被Select的对象无效所以SelectObject的返回值要保存起来,用完了就恢复上一次的值。
ReleaseDC的参数是HWND类型,传字符串地址进去显然不会有效果。
CreateCompatibleDC创建的DC要用DeleteDC删除。
函数不熟一定要把文档先看一遍,这些都是MSDN的文档里的内容……
这些函数都是有返回值指示成功或者失败的,写代码要养成检查返回值的习惯。
Visual C++ MVP- 已标记为答案 此显示名称已经被使用 2019年11月8日 7:52
-
DeleteObject对正在被Select的对象无效所以SelectObject的返回值要保存起来,用完了就恢复上一次的值。
ReleaseDC的参数是HWND类型,传字符串地址进去显然不会有效果。
CreateCompatibleDC创建的DC要用DeleteDC删除。
函数不熟一定要把文档先看一遍,这些都是MSDN的文档里的内容……
这些函数都是有返回值指示成功或者失败的,写代码要养成检查返回值的习惯。
Visual C++ MVP你好,谢谢你的回答,找到问题了,这个代码是为了提问写的,没注意到,感谢您的提醒,问题出在了实际代码中的声明,我声明错了。非常感谢
-
你好,
可以尝试下我下面这个例子,测试了一下,没有出现报错的情况。
应当传入句柄值,你传入的是Text.text。
另外,为什么你要使用Do while true。。。Loop呢?下面这种调用方式可能更好。
Private Sub TextBox4_TextChanged(sender As Object, e As EventArgs) Handles TextBox4.TextChanged PictureBox1.Image = CaptureWindow(TextBox4.Handle) End Sub
Imports System.Runtime.InteropServices Public Class Form1 Public Class GDI32 Public Const SRCCOPY As Integer = &HCC0020 <DllImport("gdi32.dll")> Public Shared Function BitBlt(ByVal hObject As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hObjectSource As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As Integer) As Boolean End Function <DllImport("gdi32.dll")> Public Shared Function CreateCompatibleBitmap(ByVal hDC As IntPtr, ByVal nWidth As Integer, ByVal nHeight As Integer) As IntPtr End Function <DllImport("gdi32.dll")> Public Shared Function CreateCompatibleDC(ByVal hDC As IntPtr) As IntPtr End Function <DllImport("gdi32.dll")> Public Shared Function DeleteDC(ByVal hDC As IntPtr) As Boolean End Function <DllImport("gdi32.dll")> Public Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean End Function <DllImport("gdi32.dll")> Public Shared Function SelectObject(ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr End Function End Class Public Class User32 <StructLayout(LayoutKind.Sequential)> Public Structure RECT Public left As Integer Public top As Integer Public right As Integer Public bottom As Integer End Structure <DllImport("user32.dll")> Public Shared Function GetDesktopWindow() As IntPtr End Function <DllImport("user32.dll")> Public Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr End Function <DllImport("user32.dll")> Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As IntPtr End Function <DllImport("user32.dll")> Public Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef rect As RECT) As IntPtr End Function End Class Public Function CaptureWindow(ByVal handle As IntPtr) As Image Dim hdcSrc As IntPtr = User32.GetWindowDC(handle) Dim windowRect As User32.RECT = New User32.RECT() User32.GetWindowRect(handle, windowRect) Dim width As Integer = windowRect.right - windowRect.left Dim height As Integer = windowRect.bottom - windowRect.top Dim hdcDest As IntPtr = GDI32.CreateCompatibleDC(hdcSrc) Dim hBitmap As IntPtr = GDI32.CreateCompatibleBitmap(hdcSrc, width, height) Dim hOld As IntPtr = GDI32.SelectObject(hdcDest, hBitmap) GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY) GDI32.SelectObject(hdcDest, hOld) GDI32.DeleteDC(hdcDest) User32.ReleaseDC(handle, hdcSrc) Dim img As Image = Image.FromHbitmap(hBitmap) GDI32.DeleteObject(hBitmap) GC.Collect() Application.DoEvents() Return img End Function Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Do While True PictureBox1.Image = CaptureWindow(TextBox4.Handle) Loop End Sub 'Private Sub TextBox4_TextChanged(sender As Object, e As EventArgs) Handles TextBox4.TextChanged ' PictureBox1.Image = CaptureWindow(TextBox4.Handle) 'End Sub End Class
希望对您有所帮助。
Julie
如果您对Visual Studio 或Microsoft Azure相关产品感兴趣,请点击此链接,或扫描以下二维码注册获取相关信息。
- 已编辑 Julie Xu-MSFTMicrosoft contingent staff, Moderator 2019年11月8日 7:26