need help on bitblt

G

Galen Somerville

I'm doing something wrong. I made up a test app and put the ZIP file on my
website

http://home.surewest.net/galen/index.html under Downloads.

Basically I have a Panel that will get continuous updates and I don't want
any flicker. In the test app it sets up a mem map and sets it to Black.

When the Button is clicked it calls a routine that puts tick marks at top
and bottom. The tick marks do not show up.

Below is the Paint event. If I remark out the BitBlt and un-remark the
e.Graphics line, the tick marks show up. But I know from experience that
this method cause flicker when doing a lot of updates.

I would appreciate any help I can get.

Thanks
GalenS

Private Sub PictDraw_Paint(ByVal sender As Object, _
ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictDraw.Paint
If bitmapflg Then
'e.Graphics.DrawImage(PictMap, e.ClipRectangle, e.ClipRectangle,
GraphicsUnit.Pixel)
BitBlt(PictDrawhDC, 0, 0, 715, 255, PicDrawhDC, 0, 0, SrcCopy)
End If
End Sub
 
A

Armin Zingler

Galen Somerville said:
I'm doing something wrong. I made up a test app and put the ZIP file
on my website

http://home.surewest.net/galen/index.html under Downloads.

Basically I have a Panel that will get continuous updates and I
don't want any flicker. In the test app it sets up a mem map and
sets it to Black.

When the Button is clicked it calls a routine that puts tick marks
at top and bottom. The tick marks do not show up.

Below is the Paint event. If I remark out the BitBlt and un-remark
the e.Graphics line, the tick marks show up. But I know from
experience that this method cause flicker when doing a lot of
updates.

I would appreciate any help I can get.

Thanks
GalenS

Private Sub PictDraw_Paint(ByVal sender As Object, _
ByVal e As System.Windows.Forms.PaintEventArgs) Handles
PictDraw.Paint If bitmapflg Then
'e.Graphics.DrawImage(PictMap, e.ClipRectangle,
e.ClipRectangle, GraphicsUnit.Pixel)
BitBlt(PictDrawhDC, 0, 0, 715, 255, PicDrawhDC, 0, 0,
SrcCopy) End If
End Sub

You can not draw on a device context that has already been released.

PictDrawhDC = GrpObj.GetHdc
GrpObj.ReleaseHdc()

After calling ReleasdHdc, PictDrawhDC is an invalid handle.


Armin
 
G

Galen Somerville

Armin Zingler said:
You can not draw on a device context that has already been released.

PictDrawhDC = GrpObj.GetHdc
GrpObj.ReleaseHdc()

After calling ReleasdHdc, PictDrawhDC is an invalid handle.


Armin

I'll ckeck that out. I released it after looking at Amit's article on Using
Bitblt.

GalenS
 
G

Galen Somerville

Galen Somerville said:
I'll ckeck that out. I released it after looking at Amit's article on
Using Bitblt.

GalenS
Armin

I had to create hdc after setting PictMap to avoid error. Still same
problem.
Also tried not disposing GrpObj. Still same problem.

GalenS

Dim GrpObj As Graphics = PictDraw.CreateGraphics
PictMap = New Bitmap(PictDraw.Width, PictDraw.Height, GrpObj)
PictDrawhDC = GrpObj.GetHdc
' GrpObj.ReleaseHdc()
GrpObj.Dispose()
 
A

Armin Zingler

Galen Somerville said:
Armin

I had to create hdc after setting PictMap to avoid error. Still same
problem.
Also tried not disposing GrpObj. Still same problem.

GalenS

Dim GrpObj As Graphics = PictDraw.CreateGraphics
PictMap = New Bitmap(PictDraw.Width, PictDraw.Height, GrpObj)
PictDrawhDC = GrpObj.GetHdc
' GrpObj.ReleaseHdc()
GrpObj.Dispose()


I don't get what you're trying to accomplish.

Maybe some general hints help:

'Drawing on a bitmap

Dim g As Graphics
Dim bmp As Bitmap

bmp = New Bitmap(100, 100)

g = Graphics.FromImage(bmp)
g.Clear(Color.Black)
g.DrawLine(Pens.White, 0, 0, 100, 100)
g.Dispose()




'Drawing a bitmap using BitBlt in a Paint event

Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As IntPtr,
ByVal hObject As IntPtr) As IntPtr
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As
IntPtr) As Boolean
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As
IntPtr) As IntPtr

Dim hdcSource, hdcDest As IntPtr
Dim OldObject, hBmp As IntPtr

hdcDest = e.Graphics.GetHdc
hdcSource = CreateCompatibleDC(hdcDest)
hBmp = bmp.GetHbitmap
OldObject = SelectObject(hdcSource, hBmp)

BitBlt(hdcDest, 0, 0, bmp.Width, bmp.Height, hdcSource, 0, 0, SrcCopy)

SelectObject(hdcSource, OldObject)
DeleteObject(hBmp)
DeleteObject(hdcSource)
e.Graphics.ReleaseHdc(hdcDest)




Armin
 
G

Galen Somerville

Armin Zingler said:
I don't get what you're trying to accomplish.

Maybe some general hints help:

'Drawing on a bitmap

Dim g As Graphics
Dim bmp As Bitmap

bmp = New Bitmap(100, 100)

g = Graphics.FromImage(bmp)
g.Clear(Color.Black)
g.DrawLine(Pens.White, 0, 0, 100, 100)
g.Dispose()




'Drawing a bitmap using BitBlt in a Paint event

Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As IntPtr,
ByVal hObject As IntPtr) As IntPtr
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As
IntPtr) As Boolean
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As
IntPtr) As IntPtr

Dim hdcSource, hdcDest As IntPtr
Dim OldObject, hBmp As IntPtr

hdcDest = e.Graphics.GetHdc
hdcSource = CreateCompatibleDC(hdcDest)
hBmp = bmp.GetHbitmap
OldObject = SelectObject(hdcSource, hBmp)

BitBlt(hdcDest, 0, 0, bmp.Width, bmp.Height, hdcSource, 0, 0,
SrcCopy)

SelectObject(hdcSource, OldObject)
DeleteObject(hBmp)
DeleteObject(hdcSource)
e.Graphics.ReleaseHdc(hdcDest)




Armin

I was a little vague on what I need. The app is getting a feed from a USB
device with four samples worth of data about every 12 milliseconds. There
are various subs in various modules that will be drawing to the Panel (or
PictureBox if better).

This is like an oscilloscope trace of Heart sounds. It works fine when I use
the e.Graphics,etc in the Paint event. But the display flickers badly. It
was suggested I use a double buffer technique. But all of the help samples I
could find just show how to do it for one operation. Of course I need to do
it continually.

Also they all show doing the work in a Paint event. I would have to have a
monster set of Select Cases or If Elses to do it all in the Paint Event.

Not shown in the TestBitblt demo is the fact that the Panel (or PictureBox)
could be on one of two forms. Therefore I have to pass the Form info to the
various subs.

Finally, a little sour grapes, this was easy to do in VB6.

GalenS
 
A

Armin Zingler

Galen Somerville said:
I was a little vague on what I need. The app is getting a feed from
a USB device with four samples worth of data about every 12
milliseconds. There are various subs in various modules that will be
drawing to the Panel (or PictureBox if better).

This is like an oscilloscope trace of Heart sounds. It works fine
when I use the e.Graphics,etc in the Paint event. But the display
flickers badly. It was suggested I use a double buffer technique.
But all of the help samples I could find just show how to do it for
one operation. Of course I need to do it continually.

Why for one operation only?
Also they all show doing the work in a Paint event. I would have to
have a monster set of Select Cases or If Elses to do it all in the
Paint Event.

Why do you need many cases?
Not shown in the TestBitblt demo is the fact that the Panel (or
PictureBox) could be on one of two forms. Therefore I have to pass
the Form info to the various subs.

Why do you have to pass the Form?
Finally, a little sour grapes, this was easy to do in VB6.


I would create a control that encapsulates the drawing. Set styles
ControlStyles.AllPaintingInWmPaint, ControlStyles.UserPaint,
ControlStyles.ResizeRedraw and ControlStyles.DoubleBuffer. Pass the data
to properties of the control. In OnPaint, paint depending on the data
passed. You can put the Control on as many forms as you like.


Armin
 
G

Galen Somerville

inline

Armin Zingler said:
Why for one operation only?

What I meant was that the help samples would show how to transfer a color
block and then dispose of everything.
Why do you need many cases?

Different subs draw in different ways. If all in one Paint Event it would
have to know which way was currently required.
Why do you have to pass the Form?
If the effective bitmap were Global, I guess I wouldn't
I would create a control that encapsulates the drawing. Set styles
ControlStyles.AllPaintingInWmPaint, ControlStyles.UserPaint,
ControlStyles.ResizeRedraw and ControlStyles.DoubleBuffer. Pass the data
to properties of the control. In OnPaint, paint depending on the data
passed. You can put the Control on as many forms as you like.


Armin

Good point. I have user controls for other purposes. I never thought of
doing it for Graphics displays. I will get right on it.

GalenS
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top