Screen Capability


The Screen object provides some information about the current capabilities of the graphics screen, but it’s pitifully short of what you might hope for. The GetDeviceCaps API function can tell you anything you need to know about the screen or about any specific device context. This is one of those Swiss-army-knife functions that takes 100 different constants as arguments and returns a different value, depending on which constant you passed.


For example, here’s how to determine how many color planes and how many bits per pixel your video supports:

cPlanes = GetDeviceCaps(hdcDst, PLANES)
cPixelBits = GetDeviceCaps(hdcDst, BITSPIXEL)

You need this information every time you create a bitmap, as you’ll see later in this chapter. Although this seems like something the Screen object ought to provide, it doesn’t—but the Video object does.


The CVideo class is implemented in VIDEO.CLS in the VBCore component. VBCore also creates a single global instance of this class as the Video object. You can see sample output from it in the AllAbout program (ALLABOUT.VBP) described in Chapter 11. CVideo is a simple class that wraps the GetDeviceCaps function to tell you everything you ever dreamed of knowing about your video device. Here’s enough code to show you how it works:

Private hdcScreen As Long

Private Sub Class_Initialize()
hdcScreen = GetDC(hNull)
End Sub

Private Sub Class_Terminate()
Call ReleaseDC(hNull, hdcScreen)
End Sub

Private Function GetCaps(iCode As Long) As Long
GetCaps = GetDeviceCaps(hdcScreen, iCode)
End Function

Property Get BitsPerPixel() As Long
BitsPerPixel = GetCaps(BITSPIXEL)
End Property

Property Get ColorPlanes() As Long
ColorPlanes = GetCaps(PLANES)
End Property

Metafiles 1, Visual Basic 0


Metafiles present several interesting problems to the Visual Basic programmer. It’s easy enough to assign a metafile to the Picture property from a resource, a file, the Clipboard, or a picture. You have to jump through some API hoops to send a metafile to the printer, however, because the printer doesn’t have a Picture property. (This chapter doesn’t cover that task specifically, but it will give some helpful background.)


Visual Basic won’t help you create or record metafiles either. Visual Basic drawing methods such as Line and Circle draw to canvas objects, but they don’t know anything about metafiles, and you don’t have a way to redirect them to the HDC of a metafile.


What Visual Basic needs is a CMetafile class, inherited from the CCanvas class (or perhaps CMetafile should implement the IDrawable interface). CMetafile objects would have all the normal canvas properties and methods plus a Play method to replay the metafile and a Save method to write it to disk. You could call the Clear method to wipe out any previous commands and then draw on the CMetafile object using your favorite drawing and painting methods.


In fact, you could design just such a CMetafile class. The API calls to create a metafile are easy enough. The problem is that you would need to reimplement the whole Visual Basic graphics library to give your CMetafile class the Line, Circle, and other methods it needs. Furthermore, you wouldn’t be able to do so completely because the syntax of the Line, Circle, and PSet methods isn’t a legal procedure syntax that you can emulate in your own methods.


Nevertheless, you could fake it—if you happen to have several months of spare time. It would be a lot easier for Visual Basic to add this class than for you to do it. Maybe in the next version. In the meantime, it’s simpler to create metafiles in a drawing program and then play them through the Picture property.


I’ve found this class to be overkill in most programs; it’s usually easier to just call GetDeviceCaps. But once in a while, CVideo is just what you need.