Using GDI to draw to a backbuffer

From HashVB
Jump to: navigation, search

What is a backbuffer?

A backbuffer is device context that is created in memory to which you draw. The reason for drawing to a backbuffer may not be clear at first, but when you consider that every time a repaint is required you have to draw both the background and foreground, it is obvious that you will run into issues with the foreground flickering when the background redraws. Thus, we draw the whole 'scene' to a backbuffer, then copy the backbuffer across to our display to eliminate flickering.

How to create and use a backbuffer

API Declarations required:

   Private Declare Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
   Private Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
   Private Declare Function CreateSolidBrush Lib "gdi32.dll" (ByVal crColor As Long) As Long
   Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
   Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
   Private Declare Function Rectangle Lib "gdi32.dll" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
   Private Declare Function TextOut Lib "gdi32.dll" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
   Private Declare Function SelectObject Lib "gdi32.dll" (ByVal hdc As Long, ByVal hObject As Long) As Long
   Private Declare Function BitBlt Lib "gdi32.dll" (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 SetBkMode Lib "gdi32.dll" (ByVal hdc As Long, ByVal nBkMode As Long) As Long

The code:

   Private Sub Form_Paint()
       '-- For this example we will use the painting of a form
       
       Dim mDC As Long
       Dim mBMP As Long
       Dim hBrush As Long
       Dim sText As String
       
       '-- We're working in pixels...
       Me.ScaleMode = vbPixels
       
       '-- The first thing we have to is create a DC for our backbuffer
       '   The DC we create must be compatible with our form's DC
       mDC = CreateCompatibleDC(Me.hdc)
       '-- We then have to create a bitmap that is also compatible with the form's
       '   DC, and with the same dimensions as we wish to draw
       mBMP = CreateCompatibleBitmap(Me.hdc, Me.ScaleWidth, Me.ScaleHeight)
       '-- Select the new bitmap into our DC and delete the old one
       DeleteObject SelectObject(mDC, mBMP)
       
       '-- Now we draw to our backbuffer DC
       
       hBrush = SelectObject(mDC, CreateSolidBrush(vbBlue))
       Rectangle mDC, 10, 10, Me.ScaleWidth - 10, Me.ScaleHeight - 10
       DeleteObject SelectObject(mDC, hBrush)
       
       SetBkMode mDC, 1
       sText = "Backbuffer Test!!"
       TextOut mDC, 20, 20, sText, Len(sText)
       
       '-- Transfer the contents of the backbuffer to the form's DC
       BitBlt Me.hdc, 0, 0, Me.ScaleWidth, Me.ScaleHeight, mDC, 0, 0, vbSrcCopy
       
       '-- Clean up
       DeleteObject mBMP
       DeleteDC mDC
   End Sub