Please support our sponsor:
DirectX4VB.Com - All You Need For Multimedia Visual Basic Programming

Main Site Links Resources Tutorials
News VB Gaming Code Downloads DirectX 7
Contact Webmaster VB Programming Product Reviews DirectX 8
  General Multimedia Articles DirectX 9
      Miscellaneous

 

DirectDraw: Windowed Mode
By: Jack Hoxley
Written: May 2000
Download: DD_Windowed.Zip (190kb)


Windowed mode is the alternative to fullscreen mode. Windowed mode is most useful when it is used in normal windows programs as it holds very little use for games. If you're wanting directdraw functionality for a CAD program, Intensive drawing program or some form of art software, windowed mode is what you'll want to use.

Whereas fullscreen mode controls the entire screen, windowed mode is allocated a small portion of this; in visual basic it uses a picturebox as a container. This means that you can have normal windows designs and controls around a central image - making directdraw part of the user-interface, as opposed to making the user-interface part of directdraw (typical of fullscreen mode).

There are three main differences/advantages to using windowed mode:

  1. Windowed mode does not use a backbuffer; everything is blitted directly to the primary surface. In windowed mode the primary surface represents the picturebox that it is contained in.
  2. No need for constant blitting or loops. Whereas in fullscreen mode you have to constantly update the screen, in windowed mode you only have to update the screen as-and-when you need to (ie. after something has changed). This makes it much less of a resource hog, and allows for a completely different coding structure.
  3. Clippers. In fullscreen mode your application is always at the front - anything that gets in the way is drawn over. This can't happen in windowed mode, your application will be interacting with other windows, or the user will have other windows open on screen. When this is the case it is quite likely that an open window will overlap with your viewport/picturebox, to stop this from happening directdraw employs the use of a clipper; this stops your application drawing over the top of other windows.

Fortunately, windowed mode is much easier to program than fullscreen mode; although once setup many things cross over between them, the initial code and structure is much simpler.

Option Explicit

'Main Variables
Dim DX As New DirectX7
Dim DD As DirectDraw7

'The first buffer holds a bitmap. The second "Primary" surface
'represents what appears on screen.

Dim picBuffer As DirectDrawSurface7
Dim Primary As DirectDrawSurface7

'The first desciptor describes the screen
'The second describes the surface that the bitmap will go into.

Dim ddsd1 As DDSURFACEDESC2
Dim ddsd2 As DDSURFACEDESC2

'The clipper handles obscured surfaces and stops our application
'from drawing over the top of other windows.

Dim ddClipper As DirectDrawClipper

'A simple initialization flag.
Dim bInit As Boolean Private


Sub Form_Load()
'Start the ball rolling......
init
End Sub


Sub init()
On Error GoTo ErrHandler:

'Initialization procedure
'The empty string parameter means to use the active display driver

Set DD = DX.DirectDrawCreate("")

'Indicate this app will be a normal windowed app - not fullscreen.
'with the same display depth as the current display. This can
'be very limiting - The end-user can have the desktop in anything
'from 16 colours to 16 million. To find out what the current depth is
'use:
'dim DeskTopBpp as long
'DesktopBpp = DX.SystemBpp

Call DD.SetCooperativeLevel(Me.hWnd, DDSCL_NORMAL)

'Indicate that the ddsCaps member is valid in this type
ddsd1.lFlags = DDSD_CAPS
'This surface is the primary surface (what is visible to the user)
ddsd1.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE
'You're now creating the primary surface with the surface description you just set
Set Primary = DD.CreateSurface(ddsd1)

'Now let's set the second surface description
ddsd2.lFlags = DDSD_CAPS
'This is going to be a plain off-screen surface - ie, to hold a bitmap
ddsd2.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
'Now we create the off-screen surface from the pre-rendered picture

Set picBuffer = DD.CreateSurfaceFromFile(App.Path & "\background.bmp", ddsd2)

'Creates the clipper, and attaches it to the picturebox and
'the primary surface. This is all that has to be done - the clipper
'itself handles everything else.

Set ddClipper = DD.CreateClipper(0)
ddClipper.SetHWnd picBox.hWnd
Primary.SetClipper ddClipper

'Yes it has been initialized and is ready to blit
bInit = True

'Ok now were ready to blit this thing, call the blt procedure
'One huge advantage of Windowed mode is that you don't
'have to have a loop, you just call "blt" when you need the
'picture to be updated.

blt

Exit Sub
ErrHandler:
MsgBox "Unable to initialize DirectDraw - Closing program", vbInformation, "error"
End
End Sub


Private Sub Form_Resize()
'This procedure is called by the me.show event or when
'The form is resized during runtime.
'Since DX uses pixels and VB uses twips this procedure
'Syncs up the two scales
'Remember to change the ScaleMode property on the
'Form to Pixels. Notice the Width and Height of the form
'Stay in twips even after you change the ScaleMode, but
'The ScaleWidth and the ScaleHeight are now in pixels.

picBox.Width = Me.ScaleWidth
picBox.Height = Me.ScaleHeight

'Update the display:
blt
End Sub


Sub blt()
On Error GoTo ErrHand:

'Has it been initialized? If not let's get out of this procedure
If bInit = False Then Exit Sub

'Some local variables
Dim ddrval As Long
Dim r1 As RECT 'The screen size
Dim r2 As RECT 'The bitmap size

'Gets the bounding rect for the entire window handle, stores in r1
Call DX.GetWindowRect(picBox.hWnd, r1)
r2.Bottom = ddsd2.lHeight
r2.Right = ddsd2.lWidth

'Using Blt instead of Bltfast is essential - do not try and use bltfast.
'The advantage of using blt is that it resizes the picture to be the same as
'the picture box, this means that we can resize the window and the code
'will adapt to fit the new size - even though it will look really ugly
'when stretched.

ddrval = Primary.blt(r1, picBuffer, r2, DDBLT_WAIT)

Exit Sub
ErrHand:
MsgBox "There was an error whilst redrawing the screen.", vbCritical, "error"
End Sub


Private Sub picBox_Paint()
'This procedure is called during runtime when the form
'is moved or resized.

DD.RestoreAllSurfaces
init
blt
End Sub

 

Simple as that. You now have the basic structure for a directdraw windowed mode application. Many of the methods for fullscreen mode apply to windowed mode, such as copying bitmaps, drawing primitives and drawing text.

You can download a copy of the sample project from the Downloads page, or you can download it straight from the top of the page.

DirectX 4 VB © 2000 Jack Hoxley. All rights reserved.
Reproduction of this site and it's contents, in whole or in part, is prohibited,
except where explicitly stated otherwise.
Design by Mateo
Contact Webmaster
This site is hosted by Exhedra Solutions, Inc., the parent company of RentACoder.com and PlanetSourceCode.com