473,378 Members | 1,507 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

BitMap to Control in Paint Event

I am trying to implement drawing on a bitmap and using bitblt to transfer
it to the control graphics object in the paint event. It seems to draw on
the bitmap ok but doesn't get transferred to the control graphics object in
the paint event. Any help would be appreciated. Here is my code:

public class as mycontrol

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

Private v_BackImage As Bitmap = New Bitmap(Me.Width, Me.Height,
Me.CreateGraphics)
Private gph As Graphics = Graphics.FromImage(v_BackImage)

'do some drawing on gph

Private Sub Panel_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
'Get Device contexts for Source and Memory Graphics Objects
Dim hdcSrc As IntPtr = gph.GetHdc
Dim hdcDest As IntPtr = e.Graphics.GetHdc
BitBlt(hdcDest, 0, 0, Me.Width, Me.Height, hdcSrc, Me.Width, Me.Height,
13369376)
'Clean Up
gph.ReleaseHdc(hdcSrc)
e.Graphics.ReleaseHdc(hdcDest)
end sub

end class

--
Dennis in Houston
Nov 21 '05 #1
7 1996
Private Declare Function SelectObject Lib "gdi32" Alias "SelectObject"
(ByVal hdc As IntPtr, ByVal hObject As IntPtr) As IntPtr
Private Declare Function DeleteObject Lib "gdi32" Alias "DeleteObject"
(ByVal hObject As IntPtr) As Integer
....
Dim hdcBitmap, hdcControl, hdcOriginal As IntPtr
....
hdcBitmap = gph.GetHdc
hdcControl = e.Graphics.GetHdc
hdcOriginal = SelectObject(hdcBitmap, v_BackImage.GetHbitmap)
BitBlt(hdcControl, 0, 0, v_BackImage.Width, v_BackImage.Height, hdcBitmap,
0, 0, &HCC0020)
SelectObject(hdcBitmap, hdcOriginal)
DeleteObject(hdcOriginal)
e.Graphics.ReleaseHdc(hdcControl)
gph.ReleaseHdc(hdcBitmap)
....
gph.Dispose() ' When you're done.
"Dennis" <De****@discussions.microsoft.com> schreef in bericht
news:01**********************************@microsof t.com...
I am trying to implement drawing on a bitmap and using bitblt to transfer
it to the control graphics object in the paint event. It seems to draw on
the bitmap ok but doesn't get transferred to the control graphics object
in
the paint event. Any help would be appreciated. Here is my code:

public class as mycontrol

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

Private v_BackImage As Bitmap = New Bitmap(Me.Width, Me.Height,
Me.CreateGraphics)
Private gph As Graphics = Graphics.FromImage(v_BackImage)

'do some drawing on gph

Private Sub Panel_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
'Get Device contexts for Source and Memory Graphics Objects
Dim hdcSrc As IntPtr = gph.GetHdc
Dim hdcDest As IntPtr = e.Graphics.GetHdc
BitBlt(hdcDest, 0, 0, Me.Width, Me.Height, hdcSrc, Me.Width, Me.Height,
13369376)
'Clean Up
gph.ReleaseHdc(hdcSrc)
e.Graphics.ReleaseHdc(hdcDest)
end sub

end class

--
Dennis in Houston

Nov 21 '05 #2
Thanks a lot for the reply...I know it took a lot of you time. I included it
into my program and it works fine except for one problem. The line
"DeleteObject(hdcOriginal)" somehow causes the form containing my control to
lose it's identity such that it throw an exception "Object not set to
reference" when I try to access it's properties such as me.Enabled. If I
delete the line "DeleteObject(hdcOriginal)" then it works fine.

"Qwert" wrote:
Private Declare Function SelectObject Lib "gdi32" Alias "SelectObject"
(ByVal hdc As IntPtr, ByVal hObject As IntPtr) As IntPtr
Private Declare Function DeleteObject Lib "gdi32" Alias "DeleteObject"
(ByVal hObject As IntPtr) As Integer
....
Dim hdcBitmap, hdcControl, hdcOriginal As IntPtr
....
hdcBitmap = gph.GetHdc
hdcControl = e.Graphics.GetHdc
hdcOriginal = SelectObject(hdcBitmap, v_BackImage.GetHbitmap)
BitBlt(hdcControl, 0, 0, v_BackImage.Width, v_BackImage.Height, hdcBitmap,
0, 0, &HCC0020)
SelectObject(hdcBitmap, hdcOriginal)
DeleteObject(hdcOriginal)
e.Graphics.ReleaseHdc(hdcControl)
gph.ReleaseHdc(hdcBitmap)
....
gph.Dispose() ' When you're done.
"Dennis" <De****@discussions.microsoft.com> schreef in bericht
news:01**********************************@microsof t.com...
I am trying to implement drawing on a bitmap and using bitblt to transfer
it to the control graphics object in the paint event. It seems to draw on
the bitmap ok but doesn't get transferred to the control graphics object
in
the paint event. Any help would be appreciated. Here is my code:

public class as mycontrol

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

Private v_BackImage As Bitmap = New Bitmap(Me.Width, Me.Height,
Me.CreateGraphics)
Private gph As Graphics = Graphics.FromImage(v_BackImage)

'do some drawing on gph

Private Sub Panel_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
'Get Device contexts for Source and Memory Graphics Objects
Dim hdcSrc As IntPtr = gph.GetHdc
Dim hdcDest As IntPtr = e.Graphics.GetHdc
BitBlt(hdcDest, 0, 0, Me.Width, Me.Height, hdcSrc, Me.Width, Me.Height,
13369376)
'Clean Up
gph.ReleaseHdc(hdcSrc)
e.Graphics.ReleaseHdc(hdcDest)
end sub

end class

--
Dennis in Houston


Nov 21 '05 #3
Yeah, i looked at it some more and the code is not correct. Two things are
incorrect:

First of all, you don't need 'hdcOriginal', because you release 'hdcBitmap'
anyway. So the line becomes:

SelectObject(hdcBitmap, v_BackImage.GetHbitmap)

and you can remove:

DeleteObject(hdcOriginal)

but you already did that.

Secondly, and more importantly, you need to delete the handle to the bitmap:

Dim hdcBitmapHandle As IntPtr = v_BackImage.GetHbitmap
....
SelectObject(hdcBitmap, hdcBitmapHandle )
....
DeleteObject(hdcBitmapHandle)

If you don't do this, you're application will run for a while, but then you
will get an error somthing like "Error: object still in use.".

Off-topic remark:
If speed is important for you application, notice that the line
"SelectObject(hdcBitmap, hdcBitmapHandle )" takes up about 85% of the total
time to perform this. You might consider creating a class that holds and
releases the handle to the bitmap only 1 time. First I thought keeping a
handle to a bmp would cause problems, but it seems to work ok. Now BitBlt is
40% faster then DrawImage method.

"Dennis" <De****@discussions.microsoft.com> schreef in bericht
news:22**********************************@microsof t.com...
Thanks a lot for the reply...I know it took a lot of you time. I included
it
into my program and it works fine except for one problem. The line
"DeleteObject(hdcOriginal)" somehow causes the form containing my control
to
lose it's identity such that it throw an exception "Object not set to
reference" when I try to access it's properties such as me.Enabled. If I
delete the line "DeleteObject(hdcOriginal)" then it works fine.

"Qwert" wrote:
Private Declare Function SelectObject Lib "gdi32" Alias "SelectObject"
(ByVal hdc As IntPtr, ByVal hObject As IntPtr) As IntPtr
Private Declare Function DeleteObject Lib "gdi32" Alias "DeleteObject"
(ByVal hObject As IntPtr) As Integer
....
Dim hdcBitmap, hdcControl, hdcOriginal As IntPtr
....
hdcBitmap = gph.GetHdc
hdcControl = e.Graphics.GetHdc
hdcOriginal = SelectObject(hdcBitmap, v_BackImage.GetHbitmap)
BitBlt(hdcControl, 0, 0, v_BackImage.Width, v_BackImage.Height,
hdcBitmap,
0, 0, &HCC0020)
SelectObject(hdcBitmap, hdcOriginal)
DeleteObject(hdcOriginal)
e.Graphics.ReleaseHdc(hdcControl)
gph.ReleaseHdc(hdcBitmap)
....
gph.Dispose() ' When you're done.
"Dennis" <De****@discussions.microsoft.com> schreef in bericht
news:01**********************************@microsof t.com...
>I am trying to implement drawing on a bitmap and using bitblt to
>transfer
> it to the control graphics object in the paint event. It seems to draw
> on
> the bitmap ok but doesn't get transferred to the control graphics
> object
> in
> the paint event. Any help would be appreciated. Here is my code:
>
> public class as mycontrol
>
> 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
>
> Private v_BackImage As Bitmap = New Bitmap(Me.Width, Me.Height,
> Me.CreateGraphics)
> Private gph As Graphics = Graphics.FromImage(v_BackImage)
>
> 'do some drawing on gph
>
> Private Sub Panel_Paint(ByVal sender As Object, ByVal e As
> System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
> 'Get Device contexts for Source and Memory Graphics Objects
> Dim hdcSrc As IntPtr = gph.GetHdc
> Dim hdcDest As IntPtr = e.Graphics.GetHdc
> BitBlt(hdcDest, 0, 0, Me.Width, Me.Height, hdcSrc, Me.Width,
> Me.Height,
> 13369376)
> 'Clean Up
> gph.ReleaseHdc(hdcSrc)
> e.Graphics.ReleaseHdc(hdcDest)
> end sub
>
> end class
>
> --
> Dennis in Houston


Nov 21 '05 #4
> "SelectObject(hdcBitmap, hdcBitmapHandle )" takes up about 85% of the
total...


....I mean 'v_BackImage.GetHbitmap' method...
Nov 21 '05 #5
This is what I ended up with..is this correct? Just curious, but what does
the SelctObject statement do? I would have thought the BitBlt statement
would copy the pixels from the bitmap graphics object to the screen graphics
object with the need for further manipulation but I guess I'm wrong.

Dim hdcBitmap, hdcControl As IntPtr
Dim hdcBitmapHandle As IntPtr = v_BackImage.GetHbitmap 'Takes 85% of time
hdcBitmap = gph.GetHdc
hdcControl = e.Graphics.GetHdc
BitBlt(hdcControl, 0, 0, v_BackImage.Width, v_BackImage.Height, hdcBitmap,
0, 0,
&HCC0020)
SelectObject(hdcBitmap, hdcBitmapHandle)
DeleteObject(hdcBitmapHandle)
e.Graphics.ReleaseHdc(hdcControl)
gph.ReleaseHdc(hdcBitmap)

"Qwert" wrote:
"SelectObject(hdcBitmap, hdcBitmapHandle )" takes up about 85% of the
total...


....I mean 'v_BackImage.GetHbitmap' method...

Nov 21 '05 #6
BitBlt copies the graphic data to a Device Context. A Device Context is a
data structure maintained by GDI. A device context is associated with a
particular display device, such as a printer or video display. For a video
display, a device context is ussually associated with a particular window on
the display, but it can also be an offscreen display.
What you do, is create a Device Context and then associated a Bitmap with
the Device Context ( with SelectObject ). Then you draw to the Device
Context ( using BitBlt ) to alter the Bitmap. You can't use GDI functions to
directly draw to a bitmap.
After using a Device Context, you need to clean stuff up ( release and
delete ). Or else the device context stays locked and other attempts to draw
again will fail. And not cleaning up will result in memory leaks.

I hope this is correct. If not, I am sure another reader of this newsgroup
will be kind enough to correct it.
Dim hdcBitmapHandle, hdcBitmapDC, hdcControl As IntPtr
REM Get the handle to the device context associated with form Graphics
object.
hdcControl = e.Graphics.GetHdc
REM Get the handle to the device context associated with bitmap Graphics
object.
hdcBitmapDC = gph.GetHdc
REM Create the Windows HBITMAP from the image. You must de-allocate the
HBITMAP with Windows.DeleteObject(handle).
hdcBitmapHandle = v_BackImage.GetHbitmap
REM Link Device Context to Bitmap handle.
SelectObject( hdcBitmapDC , hdcBitmapHandle )
REM Use BitBlt to copy bits from one Device Context to another.
REM The first DeviceContext is attached to the form, the second Device
Context is attached to the bitmap.
BitBlt(hdcControl, 0, 0, v_BackImage.Width, v_BackImage.Height, hdcBitmapDC,
0, 0,
&HCC0020)
REM In general, when you clean things up, you do it in opposite order they
where created.
DeleteObject(hdcBitmapHandle)
e.Graphics.ReleaseHdc(hdcBitmapDC )
e.Graphics.ReleaseHdc(hdcControl)
This is what I ended up with..is this correct? Just curious, but what
does
the SelctObject statement do? I would have thought the BitBlt statement
would copy the pixels from the bitmap graphics object to the screen
graphics
object with the need for further manipulation but I guess I'm wrong.

Dim hdcBitmap, hdcControl As IntPtr
Dim hdcBitmapHandle As IntPtr = v_BackImage.GetHbitmap 'Takes 85% of time
hdcBitmap = gph.GetHdc
hdcControl = e.Graphics.GetHdc
BitBlt(hdcControl, 0, 0, v_BackImage.Width, v_BackImage.Height, hdcBitmap,
0, 0,
&HCC0020)
SelectObject(hdcBitmap, hdcBitmapHandle)
DeleteObject(hdcBitmapHandle)
e.Graphics.ReleaseHdc(hdcControl)
gph.ReleaseHdc(hdcBitmap)

"Qwert" wrote:
> "SelectObject(hdcBitmap, hdcBitmapHandle )" takes up about 85% of the
> total...


....I mean 'v_BackImage.GetHbitmap' method...

Nov 21 '05 #7
Thanks a lot for the explaination. It was the SelectObject statement after
the BitBlt that was confusing me. I see now that it goes before the BitBlt.

"Qwert" wrote:
BitBlt copies the graphic data to a Device Context. A Device Context is a
data structure maintained by GDI. A device context is associated with a
particular display device, such as a printer or video display. For a video
display, a device context is ussually associated with a particular window on
the display, but it can also be an offscreen display.
What you do, is create a Device Context and then associated a Bitmap with
the Device Context ( with SelectObject ). Then you draw to the Device
Context ( using BitBlt ) to alter the Bitmap. You can't use GDI functions to
directly draw to a bitmap.
After using a Device Context, you need to clean stuff up ( release and
delete ). Or else the device context stays locked and other attempts to draw
again will fail. And not cleaning up will result in memory leaks.

I hope this is correct. If not, I am sure another reader of this newsgroup
will be kind enough to correct it.
Dim hdcBitmapHandle, hdcBitmapDC, hdcControl As IntPtr
REM Get the handle to the device context associated with form Graphics
object.
hdcControl = e.Graphics.GetHdc
REM Get the handle to the device context associated with bitmap Graphics
object.
hdcBitmapDC = gph.GetHdc
REM Create the Windows HBITMAP from the image. You must de-allocate the
HBITMAP with Windows.DeleteObject(handle).
hdcBitmapHandle = v_BackImage.GetHbitmap
REM Link Device Context to Bitmap handle.
SelectObject( hdcBitmapDC , hdcBitmapHandle )
REM Use BitBlt to copy bits from one Device Context to another.
REM The first DeviceContext is attached to the form, the second Device
Context is attached to the bitmap.
BitBlt(hdcControl, 0, 0, v_BackImage.Width, v_BackImage.Height, hdcBitmapDC,
0, 0,
&HCC0020)
REM In general, when you clean things up, you do it in opposite order they
where created.
DeleteObject(hdcBitmapHandle)
e.Graphics.ReleaseHdc(hdcBitmapDC )
e.Graphics.ReleaseHdc(hdcControl)
This is what I ended up with..is this correct? Just curious, but what
does
the SelctObject statement do? I would have thought the BitBlt statement
would copy the pixels from the bitmap graphics object to the screen
graphics
object with the need for further manipulation but I guess I'm wrong.

Dim hdcBitmap, hdcControl As IntPtr
Dim hdcBitmapHandle As IntPtr = v_BackImage.GetHbitmap 'Takes 85% of time
hdcBitmap = gph.GetHdc
hdcControl = e.Graphics.GetHdc
BitBlt(hdcControl, 0, 0, v_BackImage.Width, v_BackImage.Height, hdcBitmap,
0, 0,
&HCC0020)
SelectObject(hdcBitmap, hdcBitmapHandle)
DeleteObject(hdcBitmapHandle)
e.Graphics.ReleaseHdc(hdcControl)
gph.ReleaseHdc(hdcBitmap)

"Qwert" wrote:
> "SelectObject(hdcBitmap, hdcBitmapHandle )" takes up about 85% of the
> total...

....I mean 'v_BackImage.GetHbitmap' method...


Nov 21 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Bradford | last post by:
I have an Windows application that displays lots of different colored lines in a Panel by using the Graphics.DrawLine method. The location and length of each line comes from a database query that...
3
by: pacemkr | last post by:
Is it possible to force a control to paint to a Graphics object (or Device Context, or a bitmap, anywhere aside from the form) that I provide. I am writing a windows form class that supports...
5
by: active | last post by:
This is what I do in a PictureBox New: b1 = New Drawing.Bitmap(Width, Height, Me.CreateGraphics()) g1 = Graphics.FromImage(b1) Someplace I do g1.DrawString.........
2
by: active | last post by:
Problem: The PictureBox display appears to have the image cut off. I.e., the image bottom does not display although the PictureBox has room for it. It occurred to me that what was displayed was...
6
by: jcrouse | last post by:
I am rotating some text is some label controls. In the one place I use it it works fine. In the other place I use it I can't figure out the syntax. I don't really understand the event. Where it...
15
by: Hamed | last post by:
Have I posted the message to wrong newsgroup? Or Does the question is so much strage? Would someone please kindly direct me to a true newsgroup or resource? Best Regards Hamed
1
by: martinsmith160 | last post by:
Hi all I am trying to create a level builder tool for a final year project and im having some problems drawing. I have placed a picture box within a panel so i can scroll around the image which is...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.