Double Buffering in VB6
Author |
Message |
CodeMonkey2000
|
Posted: Tue Sep 11, 2007 4:01 pm Post subject: Double Buffering in VB6 |
|
|
Is there any way of getting rid of the screen flicker? Also is there a way to take a screen shot of your VB form (similar to turing's pic.new)? |
|
|
|
|
|
Sponsor Sponsor
|
|
|
CodeMonkey2000
|
Posted: Thu Sep 13, 2007 2:58 pm Post subject: RE:Double Buffering in VB6 |
|
|
No suggestions? |
|
|
|
|
|
Nick
|
Posted: Thu Sep 13, 2007 3:03 pm Post subject: RE:Double Buffering in VB6 |
|
|
no idea did u try using the search feature or looking at some tuturials? |
|
|
|
|
|
cpu_hacker4.0
|
Posted: Tue Oct 09, 2007 7:17 pm Post subject: Re: Double Buffering in VB6 |
|
|
yeah ive always wondered about double buffering in vb |
|
|
|
|
|
CodeMonkey2000
|
Posted: Tue Oct 09, 2007 7:27 pm Post subject: RE:Double Buffering in VB6 |
|
|
Apparently you can't, not in VB6 anyway. |
|
|
|
|
|
Euphoracle
|
Posted: Tue Oct 09, 2007 11:22 pm Post subject: RE:Double Buffering in VB6 |
|
|
DoubleBuffering is just drawing to an offscreen image and then drawing that image to the screen at one time, so it's not drawing bit-by-bit, but instead as a whole. I KNOW this is possible because I friend made a "3D" 2D tunnel in VB6 and sent it to me. It's just not given to you like in .Net (You can set Control.DoubleBuffered, which just wraps an offscreen image and sends that to paint instead of the plain Graphics object).
Here, I did it in Java (because that's what I'm learning for school) to demonstrate how it can be done manually.
Java: | /*
* Drawable Base Frame :D
* */
// Imports
import java.awt.*;
// Application
class DrawableFrame2D extends Frame
{
// Buffers, fixes flickering
private Graphics gBuffer;
private Image iBuffer;
// Defaults
private final Point DEFAULT_POS = new Point( 200, 200 );
private final Point DEFAULT_SIZE = new Point( 640, 480 );
private final Color DEFAULT_BACK_COLOR = Color. WHITE;
public static void main ( String[] arg )
{
// DrawableFrame2D App = new DrawableFrame2D( "Drawable Base Test!", true );
}
public DrawableFrame2D ( String title, boolean max )
{
// Title bar
setUndecorated ( true );
// Perform the form init requirements
setTitle ( title );
setVisible ( true );
// Size based on maximized
if ( max )
{
// Get the current resolution
Dimension screenSize = Toolkit. getDefaultToolkit(). getScreenSize();
setBounds ( 0, 0, screenSize. width, screenSize. height - 20 );
}
else
setBounds ( DEFAULT_POS. x, DEFAULT_POS. y, DEFAULT_SIZE. x, DEFAULT_SIZE. y );
setBackground ( DEFAULT_BACK_COLOR );
// Stuff we don't mess with
setLocationRelativeTo ( null );
}
// Fixes the flicker bug, I hope :)
public void update ( Graphics g )
{
// Recreate our buffers
if ( iBuffer == null )
iBuffer = createImage ( getSize ( ). width, getSize ( ). height );
gBuffer = iBuffer. getGraphics( );
// Call paint with our buffer
paint ( gBuffer );
// Paint our buffer
g. drawImage( iBuffer, 0, 0, this );
// Kill us, so we can be recreated later
gBuffer. dispose( );
}
} |
As you can see, this is a very crude example that bases itself off a Panel. paint is an abstract method that is forced to be call. Essentially, all you'd have to do is make a class based on Form, override update to use your doublebuffer, call the base, just to make sure you didn't forget anything, and then draw your image, unless, of course, you can't do any of that in VB6 (the way I described it) in which case: ( X _ x )
Find your equivalent VB6 classes, and code away :V |
|
|
|
|
|
Brightguy
|
Posted: Sat Oct 13, 2007 7:03 pm Post subject: Re: Double Buffering in VB6 |
|
|
Well how about that, I never knew "Double Buffering" had a name... but here's an example of how to do it in classic VB, just change the filename variable to point to a picture.
VisualBASIC: | Option Explicit
Private Const filename = "C:\picture.jpg"
Private backDC As Long, picDC As Long, picInfo As BITMAP
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetObject Lib "gdi32.dll" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, ByRef lpObject As Any) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Sub Form_Load()
'Damn twips
Me.ScaleMode = vbPixels
'Load the picture into the device context and retrieve info
picDC = CreateCompatibleDC(GetDC(0))
SelectObject picDC, LoadPicture(filename)
GetObject LoadPicture(filename), Len(picInfo), picInfo
'Create device context for the background
backDC = CreateCompatibleDC(GetDC(0))
End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
'Draw picture on background
BitBlt backDC, X - Int(picInfo.bmWidth / 2), Y - Int(picInfo.bmHeight / 2), picInfo.bmWidth, picInfo.bmHeight, picDC, 0, 0, vbSrcCopy
Form_Paint
End Sub
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button > 0 Then
'Draw picture on background
BitBlt backDC, X - Int(picInfo.bmWidth / 2), Y - Int(picInfo.bmHeight / 2), picInfo.bmWidth, picInfo.bmHeight, picDC, 0, 0, vbSrcCopy
Form_Paint
End If
End Sub
Private Sub Form_Paint()
'Draw background on form
BitBlt Me.hdc, 0, 0, Me.ScaleWidth, Me.ScaleHeight, backDC, 0, 0, vbSrcCopy
End Sub
Private Sub Form_Resize()
'Create bitmap of proper size for the background
Dim backBitmap As Long
backBitmap = CreateCompatibleBitmap(GetDC(0), Me.ScaleWidth, Me.ScaleHeight)
SelectObject backDC, backBitmap
DeleteObject backBitmap
'Draw picture in the middle of background
BitBlt backDC, Int((Me.ScaleWidth - picInfo.bmWidth) / 2), Int((Me.ScaleHeight - picInfo.bmHeight) / 2), picInfo.bmWidth, picInfo.bmHeight, picDC, 0, 0, vbSrcCopy
Form_Paint
End Sub
Private Sub Form_Unload(Cancel As Integer)
'Cleanup memory
DeleteDC backDC
DeleteDC picDC
End Sub |
|
|
|
|
|
|
CodeMonkey2000
|
Posted: Sat Oct 13, 2007 8:21 pm Post subject: RE:Double Buffering in VB6 |
|
|
Wow thanks Brightguy. What's gdi32? Is that like SDL? Can I use SDL instead? |
|
|
|
|
|
Sponsor Sponsor
|
|
|
rdrake
|
Posted: Sat Oct 13, 2007 8:28 pm Post subject: Re: RE:Double Buffering in VB6 |
|
|
CodeMonkey2000 @ Sat Oct 13, 2007 8:21 pm wrote: Wow thanks Brightguy. What's gdi32? Is that like SDL? Can I use SDL instead? Graphical Device Interface. It's used by Windows to draw graphics on the monitor and to output graphics to printers and such. |
|
|
|
|
|
CodeMonkey2000
|
Posted: Sat Oct 13, 2007 9:17 pm Post subject: RE:Double Buffering in VB6 |
|
|
Why doesn't this work?
VisualBASIC: |
Option Explicit
Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, lpPoint As Any) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
Dim redPen As Long
Dim mousePress As Boolean
Private Sub Form_Load()
redPen = CreatePen(0, 15, vbRed)
DeleteObject SelectObject(hdc, redPen)
mousePress = False
End Sub
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button > 1 And Not mousePress Then
MoveToEx hdc, X, Y, 0
LineTo hdc, X, Y
ElseIf Button > 1 And mousePress Then
LineTo hdc, X, Y
Else
mousePress = False
End If
Refresh
End Sub
|
|
|
|
|
|
|
Brightguy
|
Posted: Sun Oct 14, 2007 1:43 am Post subject: Re: Double Buffering in VB6 |
|
|
A few things:
-Make sure ScaleMode is in pixels
-Don't use Refresh unless AutoRedraw is true
-Button > 1 doesn't recognize left clicks
-mousePress will never be true |
|
|
|
|
|
CodeMonkey2000
|
Posted: Sun Oct 14, 2007 7:35 am Post subject: Re: Double Buffering in VB6 |
|
|
Thanks. For those interested, here is a decent reference for gdi32 commands. |
|
|
|
|
|
|
|