Picture Objects
In early versions of Visual Basic, Picture was a property whose implementation was undefined to all but the most hardcore custom control writers. Today, Picture is a public interface with methods and properties available for inspection in the Object Browser. You can create your own Picture objects with Dim, Private, or Public; assign one Picture object to another with Set; and pass Picture objects as arguments. You can even create a Picture object with code, although Visual Basic won’t help you, as you’ll see later in Chapter 8. As far as Visual Basic is concerned, you can get Picture objects only indirectly through the LoadPicture function, the LoadResPicture function, or the Load Picture dialog box.
Picture objects are everywhere in Visual Basic, but using them is easier than understanding exactly what they are and why they work. For example, if you search for Picture in the Object Browser, you’ll find lots of Picture properties but no Picture type. Instead, you’ll find that Picture properties have the type StdPicture and that functions taking Picture arguments (SavePicture) or returning a Picture object (LoadPicture) use an IPictureDisp type. If you right-click in the Object Browser and select Show Hidden Members, you might also see an IPicture type. Picture, StdPicture, IPictureDisp, IPicture—what’s the difference?
The Visual Basic help for the misnamed “Picture object” (they mean the Picture class) gives a hint. It states: “You cannot create a Picture object using code like Dim X As New Picture. If you want to create a Picture object, you must use the StdPicture object (sic) like this: Dim X As New StdPicture.” Why not? Well, it turns out that StdPicture is a class, while Picture is an interface. You can never create an interface directly. Figure 7-5 shows a COM’s eye view of what’s really going on, as seen through the OleView program.
StdPicture (pronounced Stud Picture by some Visual Basic insiders) is what COM calls a coclass and what Visual Basic calls a class. You can always create a new object from a class. StdPicture implements two interfaces: Picture and IPicture. As we learned in “Interfaces,” page 150, every Visual Basic class defines an interface with the class name and a leading underscore. This mirror interface is
Figure 7-5. The StdPicture class in OleView.
called the default interface. For example, the default interface for the CMeToo class is _CMeToo. The StdPicture class wasn’t written in Visual Basic, so it need not follow this naming convention. Its default interface is Picture. Through a kind of type library aliasing magic that doesn’t concern us here, the Picture interface is the IPictureDisp interface. Don’t ask why. Just accept it. Whenever you see IPictureDisp, think Picture (and vice versa). The important point is that you must use the class, not the interface, to create new StdPicture objects.
No matter whether you use the StdPicture class or the Picture interface, the properties and methods are the same. The Handle, hPal, Type, Width, and Height properties will become your friends in the next section and throughout the rest of the book. The Render method should remain forever a stranger, since Visual Basic’s PaintPicture method encapsulates it in a friendlier fashion.
In addition to Picture, StdPicture implements the IPicture interface. If StdPicture had been written in Visual Basic, it would have had the following line near the top of the class file:
Implements IPicture
It would have had to implement properties such as IPicture_KeepOriginalFormat and methods such as IPicture_SaveAsFile. To use the IPicture methods, you would need to create a separate reference object. The code might look like this:
Dim pic As New StdPicture, ipic As IPicture
Set pic = pb.Picture
Set ipic = pic
Debug.Print ipic.KeepOriginalFormat
The IPicture members are documented in MSDN. Although I imagine that Visual Basic uses these members in its internal implementation of Picture properties and related features, you’ll rarely, if ever, use them in your own code.