L.S.,
I am working on a program for graphing electrical signals with an AD-converter (a kind of oscilloscope) in VB.NET 2010 Express.
For this I need fast copying from a bitmap (or memory) to a picturebox (minimal 2000 pictures per second for a bitmap of 1000x300 pixels). BitBlt is great and does the job, but in VB.NET (Win7 and Win8) after a while BitBlt gives an error. I have tried to find a memory leak, but I could not find it.
I have stripped my (large) program to the essence of the problem.
It seems that if you copy from memory to memory it is O.K., but copying from memory to the Form (picturebox or panel) in combination with some interaction with the form (c.q.UI), there is a problem.
There are two examples
1) BUTTON1: starting the BitBlt api by pushing the OK button from an inputbox. After 17 times there is an error.
2) BUTTON2: The BitBlt api is activated by a timer (5 ms). The counts are displayed in a label. After some 1050 counts there is an error.
What is wrong?
Listing of the program:
A Form with two buttons , a picurebox, a label and a timer.
Imports System.Runtime.InteropServices
Public Class Form1
#Region "API's"
Public Declare Function DeleteDC Lib "gdi32" (ByVal hDC As IntPtr) As Long
Declare Auto Function GetLastError Lib "coredll.dll" () As Int32
Declare Auto Function CreateCompatibleBitmap Lib "gdi32" Alias "CreateCompatibleBitmap" (ByVal hdc As IntPtr, ByVal nWidth As Integer, ByVal nHeight As Integer) As IntPtr
Declare Auto Function CreateCompatibleDC Lib "gdi32" Alias "CreateCompatibleDC" (ByVal hdc As IntPtr) As IntPtr
Private Declare Auto Function BitBlt Lib "GDI32.DLL" ( _
ByVal hdcDest As IntPtr, _
ByVal nXDest As Integer, _
ByVal nYDest As Integer, _
ByVal nWidth As Integer, _
ByVal nHeight As Integer, _
ByVal hdcSrc As IntPtr, _
ByVal nXSrc As Integer, _
ByVal nYSrc As Integer, _
ByVal dwRop As Int32) As Boolean
Declare Auto Function SelectObject Lib "gdi32" Alias "SelectObject" (ByVal hdc As IntPtr, ByVal hObject As IntPtr) As IntPtr
#End Region
#Region "Global Variables"
Dim SRCCOPY As Int32 = &HCC0020
Dim srcPic, clrPic As Graphics
Dim HDCsrc, HDCclr As IntPtr
Dim HDCdst As IntPtr
Dim y As Single
Dim erBitBlt As Boolean
Dim cnt As Integer
Dim errorNum As Integer = Marshal.GetLastWin32Error()
#End Region
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'================ picturebox (destination) =================
'Get a Graphics Object from picturebox1
Dim dstPic As Graphics = PictureBox1.CreateGraphics
'Get the Handle
HDCdst = dstPic.GetHdc
'================= Bitmap (source) =======================
Dim mBitmap As IntPtr = CreateCompatibleBitmap(HDCdst, PictureBox1.Width, PictureBox1.Height)
Dim DCsrc As IntPtr = CreateCompatibleDC(HDCdst)
'Select bitmap into DC
SelectObject(DCsrc, mBitmap)
' Create Graphics object from DC
srcPic = Graphics.FromHdc(DCsrc)
HDCsrc = srcPic.GetHdc
srcPic.ReleaseHdc(HDCsrc)
End Sub
Sub PlotStream()
Do
y = CSng(InputBox("", "", "50"))
'copy to picturebox
erBitBlt = BitBlt(HDCdst, 0, 0, PictureBox1.Width, PictureBox1.Height, HDCsrc, 0, 0, SRCCOPY) '80 microsec
If Not erBitBlt Then
Debug.WriteLine(Marshal.GetLastWin32Error())
Stop
End If
Loop
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
PlotStream()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
cnt = cnt + 1
Label1.Text = CStr(cnt)
'copy to picturebox
erBitBlt = BitBlt(HDCdst, 0, 0, PictureBox1.Width, PictureBox1.Height, HDCsrc, 0, 0, SRCCOPY) '80 microsec
If Not erBitBlt Then
Debug.WriteLine(errorNum)
Stop
End If
End Sub
End Class
Robert
The Netherlands
I am working on a program for graphing electrical signals with an AD-converter (a kind of oscilloscope) in VB.NET 2010 Express.
For this I need fast copying from a bitmap (or memory) to a picturebox (minimal 2000 pictures per second for a bitmap of 1000x300 pixels). BitBlt is great and does the job, but in VB.NET (Win7 and Win8) after a while BitBlt gives an error. I have tried to find a memory leak, but I could not find it.
I have stripped my (large) program to the essence of the problem.
It seems that if you copy from memory to memory it is O.K., but copying from memory to the Form (picturebox or panel) in combination with some interaction with the form (c.q.UI), there is a problem.
There are two examples
1) BUTTON1: starting the BitBlt api by pushing the OK button from an inputbox. After 17 times there is an error.
2) BUTTON2: The BitBlt api is activated by a timer (5 ms). The counts are displayed in a label. After some 1050 counts there is an error.
What is wrong?
Listing of the program:
A Form with two buttons , a picurebox, a label and a timer.
Imports System.Runtime.InteropServices
Public Class Form1
#Region "API's"
Public Declare Function DeleteDC Lib "gdi32" (ByVal hDC As IntPtr) As Long
Declare Auto Function GetLastError Lib "coredll.dll" () As Int32
Declare Auto Function CreateCompatibleBitmap Lib "gdi32" Alias "CreateCompatibleBitmap" (ByVal hdc As IntPtr, ByVal nWidth As Integer, ByVal nHeight As Integer) As IntPtr
Declare Auto Function CreateCompatibleDC Lib "gdi32" Alias "CreateCompatibleDC" (ByVal hdc As IntPtr) As IntPtr
Private Declare Auto Function BitBlt Lib "GDI32.DLL" ( _
ByVal hdcDest As IntPtr, _
ByVal nXDest As Integer, _
ByVal nYDest As Integer, _
ByVal nWidth As Integer, _
ByVal nHeight As Integer, _
ByVal hdcSrc As IntPtr, _
ByVal nXSrc As Integer, _
ByVal nYSrc As Integer, _
ByVal dwRop As Int32) As Boolean
Declare Auto Function SelectObject Lib "gdi32" Alias "SelectObject" (ByVal hdc As IntPtr, ByVal hObject As IntPtr) As IntPtr
#End Region
#Region "Global Variables"
Dim SRCCOPY As Int32 = &HCC0020
Dim srcPic, clrPic As Graphics
Dim HDCsrc, HDCclr As IntPtr
Dim HDCdst As IntPtr
Dim y As Single
Dim erBitBlt As Boolean
Dim cnt As Integer
Dim errorNum As Integer = Marshal.GetLastWin32Error()
#End Region
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'================ picturebox (destination) =================
'Get a Graphics Object from picturebox1
Dim dstPic As Graphics = PictureBox1.CreateGraphics
'Get the Handle
HDCdst = dstPic.GetHdc
'================= Bitmap (source) =======================
Dim mBitmap As IntPtr = CreateCompatibleBitmap(HDCdst, PictureBox1.Width, PictureBox1.Height)
Dim DCsrc As IntPtr = CreateCompatibleDC(HDCdst)
'Select bitmap into DC
SelectObject(DCsrc, mBitmap)
' Create Graphics object from DC
srcPic = Graphics.FromHdc(DCsrc)
HDCsrc = srcPic.GetHdc
srcPic.ReleaseHdc(HDCsrc)
End Sub
Sub PlotStream()
Do
y = CSng(InputBox("", "", "50"))
'copy to picturebox
erBitBlt = BitBlt(HDCdst, 0, 0, PictureBox1.Width, PictureBox1.Height, HDCsrc, 0, 0, SRCCOPY) '80 microsec
If Not erBitBlt Then
Debug.WriteLine(Marshal.GetLastWin32Error())
Stop
End If
Loop
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
PlotStream()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
cnt = cnt + 1
Label1.Text = CStr(cnt)
'copy to picturebox
erBitBlt = BitBlt(HDCdst, 0, 0, PictureBox1.Width, PictureBox1.Height, HDCsrc, 0, 0, SRCCOPY) '80 microsec
If Not erBitBlt Then
Debug.WriteLine(errorNum)
Stop
End If
End Sub
End Class
Robert
The Netherlands