PC Review


Reply
Thread Tools Rate Thread

BitMap to Control in Paint Event

 
 
=?Utf-8?B?RGVubmlz?=
Guest
Posts: n/a
 
      13th Mar 2005
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
 
Reply With Quote
 
 
 
 
Qwert
Guest
Posts: n/a
 
      13th Mar 2005
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" <(E-Mail Removed)> schreef in bericht
news:017F3DEA-8243-4CBA-BD15-(E-Mail Removed)...
>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



 
Reply With Quote
 
=?Utf-8?B?RGVubmlz?=
Guest
Posts: n/a
 
      13th Mar 2005
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" <(E-Mail Removed)> schreef in bericht
> news:017F3DEA-8243-4CBA-BD15-(E-Mail Removed)...
> >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

>
>
>

 
Reply With Quote
 
Qwert
Guest
Posts: n/a
 
      13th Mar 2005
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" <(E-Mail Removed)> schreef in bericht
news:2209D59F-A3D9-4212-BBCF-(E-Mail Removed)...
> 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" <(E-Mail Removed)> schreef in bericht
>> news:017F3DEA-8243-4CBA-BD15-(E-Mail Removed)...
>> >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

>>
>>
>>



 
Reply With Quote
 
Qwert
Guest
Posts: n/a
 
      13th Mar 2005
> "SelectObject(hdcBitmap, hdcBitmapHandle )" takes up about 85% of the
> total...


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


 
Reply With Quote
 
=?Utf-8?B?RGVubmlz?=
Guest
Posts: n/a
 
      13th Mar 2005
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...
>
>
>

 
Reply With Quote
 
Qwert
Guest
Posts: n/a
 
      13th Mar 2005
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...
>>
>>
>>



 
Reply With Quote
 
=?Utf-8?B?RGVubmlz?=
Guest
Posts: n/a
 
      13th Mar 2005
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...
> >>
> >>
> >>

>
>
>

 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Bitmap Paint Help GerryE Microsoft Access VBA Modules 5 30th Sep 2009 04:48 PM
how to control the paint event Richard Microsoft VB .NET 3 13th Mar 2004 02:47 PM
How to resize the bitmap used for Paint event active Microsoft VB .NET 5 3rd Dec 2003 06:40 PM
Re: C# Control Paint Event & Graphics Dave Martin Microsoft C# .NET 1 25th Aug 2003 08:58 AM
Re: C# Control Paint Event & Graphics Goran Genter Microsoft C# .NET 0 19th Aug 2003 10:18 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 08:14 AM.