18 March 2019

StdFont and StdPicture

GFA-BASIC 32 provides two COM objects for use with fonts and two for use with pictures, Font and StdFont and Picture and StdPicture. The Font and Picture objects are GB specific, they are used with other objects like Form.Font and Form.Picture, etc. So, why would do you need StdFont and StdPicture?

StdFont and StdPicture are standard automation OLE objects, so maybe you can use them with an automation server like Office? In theory it should. VB/VBA uses StdFont and StdPicture for its font and picture objects and they should be compatible with GB’s StdFont and StdPicture. However, when you try to assign a Font object from an Excel cell to a variable of the StdFont datatype, GB complains about incompatible data types.
There are a few situations where you might stumble upon a Std* COM type, for instance when you are converting VB/VBA code. Another use can be found for StdFont: it allows you to create a font object on its own. StdPicture is less useful in this respect.

StdFont and StdPicture are coclasses
StdFont and StdPicture are for use in a GB program mainly. Both types allow the New clause in a Dim statement, because both StdFont and StdPicture are coclasses from which you can create an object instance. (You cannot use New on a Font or Picture object.) The New keyword in the declaration inserts object-creation code into the program. The result of New is a new instance of the StdFont or StdPicture class provided by olepro32.dll. That’s one of the reasons GB requires the presence of this DLL. After an object has been created it has a pointer to an interface - located in olepro32.dll as well – which holds the address of the array of functions (properties and methods). These interfaces are called IFontDisp and IPictureDisp. In fact, IFontDisp and IPictureDisp only expose the IDispatch functions, there is no way to directly access the properties and methods. When you use a StdFont or StdPicture property the compiler inserts late binding code, it cannot early bind to the properties.
For a discussion on IDispatch see CreateObject Caching.

Normally, as with all IDispatch objects (Object type), you can only tell at runtime whether a property is accessed correctly. However, this is not true for the StdFont and StdPicture objects. GFA-BASIC 32 checks the syntax at compile time because it knows quite a lot of the properties that can be accessed through IDispatch. Therefor, the compiler can perform a syntax check on the names and arguments. In addition, the compiler can optimize the late binding code for the properties of these Std* types. The properties’ disp-ids are documented and the compiler can hard-code them into the executable code. This prevents the compiler from inserting code to obtain the disp-id before calling IDispatch.Invoke. Although the compiler can optimize a disadvantage of using the IDispatch interface is the use of Variants when passing arguments to and from properties.

Using StdFont and StdPicture
So there are only disadvantages in using StdFont and StdPicture, it seems. This is certainly true for the StdPicture; it doesn’t provide any useful functionality to actually create a picture. The only way to create a picture object is when you use CreatePicture or LoadPicture. You can assign such a picture to either a StdPicture or Picture data type. However, why would you want to assign it to a (New) StdPicture type? Let’s see how that should work.

Dim p As New StdPicture ' creates a new instance
Set p = LoadPicture(f$) ' assign new instance

The Set command assigns a new object to a variable. When that variable currently holds a reference to another object that object is released first. So, the StdPicture object instance created with New is released before the new picture is assigned.
The New keyword caused the creation of an ‘empty’ StdPicture object. Since all properties of StdPicture are read-only there is no way to manipulate the data of the StdPicture object (same is true for a Picture object). Consequently, the statement Dim p As New StdPicture is not very useful. It doesn’t provide any other functionality as the Picture object and it causes the compiler to insert (slower) late binding code.

The use of a StdFont is more useful. A New StdFont creates a new font that can be assigned to anything with a Font property. (In GB StdFont and Font are compatible types.) This feature is more useful than applying New on a StdPicture as the example shows:

Dim f As New StdFont    ' new instance
f.Bold = True           ' set properties
f.Name = "Arial"
Set frm1.Font = f       ' assign

In contrast with StdPicture the StdFont properties are also writeable and makes the StdFont a very useful object.

StdFont and StdPicture are IDispatch objects. Using New creates a new instance, but this isn’t very useful for a StdPicture object.