VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw?
Go Back  Xtreme Visual Basic Talk > > > VB2010: Picturebox drawing disappears? Autoredraw?


Reply
 
Thread Tools Display Modes
  #1  
Old 05-26-2012, 08:04 AM
R3ck R3ck is offline
Freshman
 
Join Date: Sep 2003
Posts: 33
Default VB2010: Picturebox drawing disappears? Autoredraw?


Problem1: I have a picturebox on a form. I have also managed to draw several PNG files with transparency onto the picturebox (see below). However, If I move the form outside the border and move it back, the image is gone. My source so far:

Dim k1 As New Bitmap(My.Resources.image1)
Dim k2 As New Bitmap(My.Resources.image2)
Dim drawMe As Graphics = PictureBox1.CreateGraphics
Dim bgcolor As Color = Color.FromArgb(128, 128, 128)
drawMe.Clear(bgcolor)
drawMe.DrawImage(k1, 20, 20)
drawMe.DrawImage(k2, 20, 20)

Moving the form outside the window will erase the PictureBox1 content.

Problem/Question2:
Is it possible to draw into a hidden Picturebox2 for alot of drawings and when finished, copy the content from Picturebox2 into Picturebox1 to avoid flickering? Thanks everyone for your help. It drives me nuts and I googled for over 2 hours before posting here.
I have tried Picturebox2.image=Picturebox1.image but it does nothing!? Although Picturebox2 has an image, it doesn't 'move' into Picturebox1!
Reply With Quote
  #2  
Old 05-26-2012, 11:14 AM
snarfblam's Avatar
snarfblamVB2010: Picturebox drawing disappears? Autoredraw? snarfblam is offline
Senior Contributor

Forum Leader
* Expert *
 
Join Date: Apr 2005
Location: USA
Posts: 896
Default

First thing I'll point out is that whenever you create a Graphics object, a Bitmap object, or any other object that implements the IDisposable interface, you need to remember to call the Dispose method when you're done with that object.
Code:
Dim k1 As New Bitmap(My.Resources.image1)
Dim k2 As New Bitmap(My.Resources.image2)
Dim drawMe As Graphics = PictureBox1.CreateGraphics
Dim bgcolor As Color = Color.FromArgb(128, 128, 128)
drawMe.Clear(bgcolor)
drawMe.DrawImage(k1, 20, 20)
drawMe.DrawImage(k2, 20, 20)
drawMe.Dispose()
k1.Dispose()
k2.Dispose()
The real problem is that you're using the wrong approach. If you want to draw to a PictureBox, do it in the paint event. This way, re-drawing automatically happens when you need it to. As an added bonus, the Graphics object will be automatically created and disposed for you.
Code:
Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    ' Don't need to clear, this happens automatically.
    Dim k1 As New Bitmap(My.Resources.image1)
    Dim k2 As New Bitmap(My.Resources.image2)

    e.Graphics.DrawImage(k1, 20, 20)
    e.Graphics.DrawImage(k2, 20, 20)

    k1.Dispose()
    k2.Dispose()
End Sub
If you want to use double-buffering to avoid flickering, it's easy to create a custom double-buffered picturebox control to use. Just add a new class to your project similar to this:
Code:
Public Class DBPictureBox
    Inherits PictureBox

    Public Sub New()
        SetStyle(ControlStyles.OptimizedDoubleBuffer Or ControlStyles.AllPaintingInWmPaint, True)
    End Sub

End Class
Build your project and the double-buffered PictureBox will show up in the ToolBox.


As an alternative approach, you can create a new Bitmap, create a Graphics object from that Bitmap, and do all your drawing to that Bitmap. Assign that bitmap as the PictureBox's image.
Code:
Public Class Form1
    Dim backBuffer As New Bitmap(320, 240, Imaging.PixelFormat.Format32bppArgb)
    Dim gBackBuffer As Graphics = Graphics.FromImage(backBuffer)

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        PictureBox1.Image = backBuffer
    End Sub
End Class
Whenever you make changes to the bitmap, call the Invalidate function on the PictureBox to tell it to redraw itself.
__________________
C# _VB.NET _
Reply With Quote
  #3  
Old 05-26-2012, 03:00 PM
passel's Avatar
passelVB2010: Picturebox drawing disappears? Autoredraw? passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

The picturebox is doubled buffered by default.
If you do your drawing in the Paint event using the passed graphics object, as snarfblam says, then there shouldn't be any flashing.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #4  
Old 05-26-2012, 04:03 PM
R3ck R3ck is offline
Freshman
 
Join Date: Sep 2003
Posts: 33
Default

snarfblam!!! The backBuffer method works like a charm and will just do me fine! I appreciate your time to reply and explain how this all works. Thanks man!

passel: You just clarified to me how double buffering works: all needs to be done in the Paint event! I would have never guessed. Thanks!

I'm just moving from VB6 to VB2010 and get really frustrated at times to understand all these new concepts. So thanks again for all your help!

Last edited by R3ck; 05-26-2012 at 04:10 PM.
Reply With Quote
  #5  
Old 05-26-2012, 07:34 PM
R3ck R3ck is offline
Freshman
 
Join Date: Sep 2003
Posts: 33
Default

And another question: I have done extensive graphics manipulation and its stored into the backbuffer.
Now I need a cursor image to MouseMove in realtime over the background (it's not the standard mousepointer ).
I can't redraw the entire background for every mousemove, its too slow.

My idea was this:

1) Store the background image into a bitmap/image variable (whatever works)
2) Now for every mouse move, restore the background first and draw the new item on top

I tried Restore and Save methods (http://msdn.microsoft.com/en-us/libr...aphics.restore) but this just seems confusing and didn't get me anywhere. Any clues?

Last edited by R3ck; 05-26-2012 at 09:15 PM.
Reply With Quote
  #6  
Old 05-27-2012, 01:19 AM
hDC_0VB2010: Picturebox drawing disappears? Autoredraw? hDC_0 is offline
Contributor

* Expert *
 
Join Date: Feb 2004
Posts: 559
Default Using texturebrush for sprites with transparent background.

You've been given the code to create a backbuffer.
So copy the background graphic to the backbuffer and then be able to use texturebrush
to copy over the sprite you want to the backbuffer using the mousemove x,y positioning,
before setting the picturebox to the backbuffer image.

That's one way to do it after you hide the real cursor.

For an example of using texturebrush see passel's texturebrush example attached to this post.
Reply With Quote
  #7  
Old 05-27-2012, 01:23 AM
R3ck R3ck is offline
Freshman
 
Join Date: Sep 2003
Posts: 33
Default

hDC_0, yes the backbuffer method works great. This is the first time I'm reading about "TextureBrush". Heading to MSDN now and downloaded the sprite example. Some reading to do now. Thanks!

Last edited by R3ck; 05-27-2012 at 01:29 AM.
Reply With Quote
  #8  
Old 05-27-2012, 03:04 AM
R3ck R3ck is offline
Freshman
 
Join Date: Sep 2003
Posts: 33
Default

OK I tried to keep it really simple but I guess that's not how its designed to work:

Code:
Dim backBuffer As New Bitmap(1500, 440, Imaging.PixelFormat.Format32bppArgb) 'stores complex background image
Dim backBuffer2 As New Bitmap(1500, 440, Imaging.PixelFormat.Format32bppArgb) 'should store a copy of the background image PLUS mousepointer
Dim drawMe2 As Graphics = Graphics.FromImage(backBuffer2)

'---In the Form1_Load event:
PictureBox.Image = backBuffer2 'the background on form to display buffer2

'---In the MouseMove event:
Dim arrow As New Bitmap(My.Resources.arrow) 'my MousePointer
backBuffer2 = backBuffer 'copy backBuffer2 into backBuffer to never overwrite original background
drawMe2.DrawImage(arrow, e.Location.X, 0) 'paint mousepointer and everything else onto into buffer2
---
Now this doesn't work for whatever reason. Is TextureBrush the only way to resolve this? Sorry for these newbie questions and for your help in advance!
Reply With Quote
  #9  
Old 05-27-2012, 03:56 PM
hDC_0VB2010: Picturebox drawing disappears? Autoredraw? hDC_0 is offline
Contributor

* Expert *
 
Join Date: Feb 2004
Posts: 559
Default DrawImage, Texturebrush, and Bitblt

Quote:
Originally Posted by R3ck
Is TextureBrush the only way to resolve this?
Did you even try TextureBrush?
In your posted code snippet a Texturebrush call would be used instead of
DrawImage (which can be slower than texturebrushing when doing animation).

Did you look at passel's rotating car sprite example I cited above?
Did you have trouble understanding it?

There is a GDI+ in .Net thread in the forum's KB (Tutor's Corner) that can serve as a newbie introduction.
Texturebrushing is explained in the last post of that thread.
There is also a thread on using backbuffers in .Net.

There is also another test that passel did to load a picture transparently
atop another image. It attached to this post if you want to check it out.

The other alternative is to use the Bitblt API.

I personally don't recommend it over using TextureBrush,
but it's still available in the ,Net environment.
One potential drawback: Using the Bitble API (via a Declare call) makes a hidden PInvoke (which means using unmanaged code).

I believe passel attached an an example ("503_vb9_1.zip") of using
the Bitblt API in VB.Net to this post.
The declares are pretty simple (and somewhat similar to VB6):
Code:
  '====== Declares needed to support GDI bitblt in .Net ===============
  '====== This is not all of the constants available, and not all of these are used in this code
  Const SRCAND = &H8800C6      ' (DWORD) dest = source AND dest
  Const SRCCOPY = &HCC0020     ' (DWORD) dest = source
  Const SRCERASE = &H440328    ' (DWORD) dest = source AND (NOT dest )
  Const SRCINVERT = &H660046   ' (DWORD) dest = source XOR dest
  Const SRCPAINT = &HEE0086    ' (DWORD) dest = source OR dest

  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 Declare Auto Function CreateCompatibleDC Lib "GDI32.DLL" _
  (ByVal hdc As IntPtr) As IntPtr

  Private Declare Auto Function DeleteDC Lib "GDI32.DLL" _
    (ByVal hdc As IntPtr) As IntPtr

  Private Declare Auto Function SelectObject Lib "GDI32.DLL" _
  (ByVal hdc As IntPtr, ByVal hObject As IntPtr) As IntPtr

  Private Declare Auto Function DeleteObject Lib "GDI32.DLL" _
  (ByVal hObject As IntPtr) As Boolean

  '====== End of Declares needed to support GDI bitblt in .Net ===============
Note: there is some commented out code in the PictureBox1_Paint event that needs to be uncommented to test out the Bitblt functionality:
Code:
    'BitBlt Not significantly faster (3%) on Acer Laptop than
    'doing the FillRectangle with the textureGrass
    'dst_hDC = e.Graphics.GetHdc
    'src_hDC = CreateCompatibleDC(dst_hDC)
    'old_hBmp = SelectObject(src_hDC, gdiGrass_hBmp)
    'For y As Integer = -LocationY To PictureBox1.Height Step 256
    '  For x As Integer = -LocationX To PictureBox1.Width Step 256
    '    BitBlt(dst_hDC, x, y, 256, 256, src_hDC, 0, 0, SRCCOPY)
    '  Next
    'Next
    'SelectObject(src_hDC, old_hBmp)
    'DeleteDC(src_hDC)
    'e.Graphics.ReleaseHdc(dst_hDC)

Last edited by hDC_0; 05-27-2012 at 04:31 PM.
Reply With Quote
  #10  
Old 05-27-2012, 06:13 PM
passel's Avatar
passelVB2010: Picturebox drawing disappears? Autoredraw? passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Well, it looks like you're not drawing in the paint event.
You've assigned backBuffer2 to PictureBox.Image, so the PictureBox control will automatically draw that image whenever the paint event happens, so you don't have to worry about drawing that.
You don't have to worry about messing it up if you draw in the paint event, since you don't modify that image.

The picturebox is double buffered, so when the paint event occurs, the picturebox has already created a memory bitmap and drawn its assigned image into it. You are passed a graphics object that will allow you to draw additional graphics, your arrow for instance, on that memory image.
When the paint event sub is exited, the memory image is copied to the screen in one shot.

So, bottom line, if you just want to draw some stuff on a fixed, but perhaps complicated, background image, then the picturebox is already geared for that. Load the image in the picturebox, add code to the paint event to draw your stuff, and then trigger the paint event whenever you want to update the image (i.e. call PictureBox.Invalidate from your mouse move event).

Quote:
Originally Posted by R3ck View Post
...
Code:
backBuffer2 = backBuffer 'copy backBuffer2 into backBuffer to never overwrite original background
...
...
Your comment implies you're want to copy backBuffer2 into backBuffer, but your code is the reverse case, copying backBuffer into backBuffer2.
But, doing an assignment that way does not make a copy of the bitmap, it copies the reference to a bitmap to another reference.
So, after that assignment, backBuffer2 and backBuffer would both be pointing to the bitmap originally associated with backBuffer.
Since they both point to the same bitmap, any change in the bitmap using either reference would affect both.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #11  
Old 06-01-2012, 06:23 AM
R3ck R3ck is offline
Freshman
 
Join Date: Sep 2003
Posts: 33
Default

Hi guys, I just want to say thank you for all your replies! I ended up using Texturebrush for this project (and had several problems in between (e.g. ResetTransform)). Since the BitBlit method doesn't seem to be significantly faster I thought I stick to the standard Methods. I must say, many things in VB6 are much easier to understand, but the limited controls could end up with a headache. Anyway, thanks again for all your replies, MUCH appreciated, I learned alot.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

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 Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw? VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw?
 
VB2010: Picturebox drawing disappears? Autoredraw?
VB2010: Picturebox drawing disappears? Autoredraw?
 
-->