By: Jack Hoxley
Written: May 2000
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:
- 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.
- 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.
- 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
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.
Dim DX As New DirectX7
Dim DD As DirectDraw7
'The first buffer holds a bitmap. The second "Primary"
'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
'from drawing over the top of other windows.
Dim ddClipper As DirectDrawClipper
'A simple initialization flag.
Dim bInit As Boolean Private
'Start the ball rolling......
On Error GoTo ErrHandler:
'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
'dim DeskTopBpp as long
'DesktopBpp = DX.SystemBpp
Call DD.SetCooperativeLevel(Me.hWnd, DDSCL_NORMAL)
'Indicate that the ddsCaps member is valid in this
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",
'Creates the clipper, and attaches it to the picturebox
'the primary surface. This is all that has to be done - the clipper
'itself handles everything else.
Set ddClipper = DD.CreateClipper(0)
'Yes it has been initialized and is ready to blit
bInit = True
'Ok now were ready to blit this thing, call the
'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.
MsgBox "Unable to initialize DirectDraw - Closing program", vbInformation,
Private Sub Form_Resize()
'This procedure is called by the me.show event or
'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:
On Error GoTo ErrHand:
'Has it been initialized? If not let's get out of
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
'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
ddrval = Primary.blt(r1, picBuffer, r2, DDBLT_WAIT)
MsgBox "There was an error whilst redrawing the screen.", vbCritical,
Private Sub picBox_Paint()
'This procedure is called during runtime when the
'is moved or resized.
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.