You control OLE objects by using the OLE control's properties and methods. All OLE objects share these properties and methods, whether they were created with the OLE control or with an insertable object. This chapter tells you how to control OLE objects in code.
In this chapter, you learn how to do the following:
To create OLE objects at run time, you use the OLE control. It provides the methods listed in table 13.1 to create objects.
Table 13.1 OLE Control Methods for Creating Objects
OLE Control Method | Use |
oleobject.InsertObjDlg | Displays the standard OLE Insert Object dialog box to enable the user to select an OLE object to create |
oleobject.CreateEmbed file[, type] | Creates an embedded object in code without displaying the OLE Insert Object dialog box |
oleobject.CreateLink file | Creates a linked object from a file without displaying the OLE Insert Object dialog box |
Follow these steps to create an OLE object at run time:
To create a linked or embedded object at run time, click the Insert Object dialog box's Cancel button.
These lines display the Insert Object dialog box (fig. 13.1) when the user double-clicks the OLE object control.
To create an embedded object without displaying the Insert Object dialog box, follow the procedure in the preceding section, but substitute this code in step 3:
The preceding lines of code embed a new, empty worksheet in the OLE control OLE1. To base the embedded object on a file, specify the file name in the first argument, as in the following example:
If you specify a file name for CreateEmbed, Visual Basic ignores the second argument. If a file contains more than one type of object, Visual Basic simply uses the first object in the file. You cannot specify an object within a file by using CreateEmbed.
The CreateEmbed method uses the class type of the OLE object to create new embedded objects (the type argument). Table 13.2 lists the class types for some commonly available OLE objects.
Table 13.2 Class Types for Common OLE Objects
Application | Class Type |
Microsoft Equation Editor | Equation |
Microsoft Equation Draw | MSDraw |
Microsoft Word document (any version) | WordDocument |
Microsoft Word document (any version) | Word.Document |
Microsoft Word document (version 6.0) | Word.Document.6 |
Microsoft Word picture (version 6.0) | Word.Picture.6 |
Microsoft Note-It | Note-It |
Microsoft WordArt | WordArt |
A package (a file of any format) | Package |
Microsoft Paintbrush | PBrush |
Microsoft Quick Recorder | SoundRec |
Microsoft Excel chart | Excel.Chart |
Microsoft Excel worksheet | Excel.Sheet |
Microsoft Excel worksheet (version 5.0) | Excel.Sheet.5 |
Microsoft Excel worksheet (version 5.0) | Excel.Chart.5 |
ShapeWare Visio Drawing (version 2.0) | ShapewareVISIO20 |
The OLE class type differs from the OLE programmatic ID that CreateObject and GetObject methods use. See Chapter 12, "Creating OLE Containers," for more information on CreateObject and GetObject.
To create a linked object without displaying the Insert Object dialog box, follow the procedure in the section "Creating OLE Objects at Run Time," but substitute this code in step 3:
Obviously, this procedure causes an error if C:\EXCEL\STOCK.XLS does not exist. To prompt a file name from the user, add a Common Dialog control to the form and use the code in listing 13.1.
Listing 13.1 Getting a File Name to Create a Linked Object
The function FileExists verifies that the user entered a valid file name in the Open File dialog box. Using FileLen and error checking is one of the faster ways of checking for a file, although it certainly is not the only way.
One of biggest problems with creating OLE objects at run time is getting them to display correctly on screen. When you create objects at design time, you draw the object and can adjust its appearance manually. When you create OLE objects at run time, you must write code to handle the object's display. To handle the display of OLE objects at run time, you can use several techniques:
The following sections describe how to use the OLE control's SizeMode property and Resize event to perform these programming tasks.
The OLE control's SizeMode controls how the OLE control displays an OLE object. Table 13.3 lists the possible settings for the SizeMode property.
Table 13.3 SizeMode Property Settings
SizeMode Constant | Value | Use |
vbOLESizeClip (default) | 0 | Clip the object to fit in the control |
vbOLESizeStretch | 1 | Stretch or shrink the object's height and width to match the control without retaining the object's original proportions |
vbOLESizeAutoSize | 2 | Resize the control to match the object's height and width |
vbOLESizeZoom | 3 | Stretch or shrink the object's height and width to match the control while retaining the object's original proportions |
If the OLE control does not match the size of the OLE object that it contains, Visual Basic triggers a Resize event for the object. The Resize event has the following form for the OLE control:
The HeightNew and WidthNew arguments indicate a recommended size for the object. This size is that of the OLE object in its original form. You can use these arguments with the SizeMode property to control the scaling of an OLE object. To learn more about this technique, see the section "Scaling the Object to Fit the Control," later in this chapter.
The Resize event occurs when the displayed size of an OLE object changes, as in the situations described in table 13.4.
Table 13.4 Situations That Result in a Resize Event
A Resize Event Occurs When | If the Current SizeMode Seeting Is |
---|---|
A new object is inserted in the control | Any setting |
The size of an object changes because it was updated | Any setting but vbOLESizeClip |
The OLE control's Height and Width properties are used to change the object's size | Any setting but vbOLESizeClip |
The SizeMode property changes to a new setting | vbOLESizeClip |
The SizeMode property changes to vbOLESizeAutosize | vbOLESizeStretch or vbOLESizeZoom |
The Resize event does not occur when SizeMode changes from any setting to vbOLESizeClip or vbOLESizeAutoSize to any setting. In the latter situation, the control size matches the object size, so no visual change occurs either.
A simple way to size an OLE object is to display it on a separate form that matches the size of the OLE control, and then enable the user to resize the form. Use the ScaleMode settings vbOLESizeClip or vbOLESizeAutoSize when creating OLE objects to display in a sizable window.
To see how this scheme works, follow these steps:
When you resize a form, you can see more of the object. This "object in a window" approach is good for multiple-document interface (MDI) applications.
Another way to size objects is to enable the user to scroll large objects up, down, right, or left. To create scrollable OLE objects, you use the ScaleMode setting vbOLESizeAutoSize, as described in these steps:
After creating the sample in this section, you can resize the form or scroll it to see more of the object.
In step 6, you use the support procedure in listing 13.2 to adjust the scroll bar's positions on the form. This procedure is useful in a variety of contexts, so the companion CD presents it as a separate procedure instead of building it in to the form's Resize event.
Listing 13.2 A Procedure for Adjusting Scroll Bars When a Form Is Resized
OLE objects are often (but not always) much larger than the OLE control drawn on a form. Therefore, scaling the object to fit in the control often results in an object that's hard to read on screen.
This type of display is useful when legibility is not an issue or when you are displaying small objects, such as small graphics. Use the ScaleMode settings vbOLESizeZoom or vbOLESizeStretch when scaling objects to fit the OLE control.
Usually vbOLESizeZoom is more useful than vbOLESizeStretch, because it maintains the object's original proportions.
Scaling enables you to fit more on screen than other display methods. However, to create legible objects, you must combine scaling with sizing the OLE control. To create a best fit, use the SizeMode setting vbOLESizeZoom, the Resize event, and the Height and Width properties together.
To see how to create the best fit for OLE objects inserted at run time, follow these steps:
The scroll bar controls the zoom ratio of the OLE control.
After creating the sample in this section, you can zoom the size of the object by using the scroll bar.
Unfortunately, relying on the ScaleMode property settings vbOLESizeZoom and vbOLESizeStretch does not work well for all applications. In particular, Microsoft Word updates scaled objects in a peculiar way. You can work around these display problems by capturing the image of the OLE control with its Picture property. To learn how to do so, see the section "Capturing the Object's Picture," later in this chapter.
By default, Visual Basic prevents you from moving embedded objects while they are being edited in place (see fig. 13.7).
When you try to move or resize an embedded object, it "snaps back" to its original position.
To enable users to move or size OLE objects at run time, use the ObjectMove event procedure. ObjectMove has the following form:
The arguments to the ObjectMove event procedure are the position and dimensions to which the user dragged the object. To make the object respond to the user's action, simply assign the ObjectMove arguments to the OLE control's Left, Top, Width, and Height properties, as follows:
Now when the user moves or resizes the OLE object, the OLE control adjusts to the new size and location as shown in figure 13.8.
The ObjectMove event procedure enables the OLE control to respond when the user moves or resizes an embedded object.
The OLE control's Picture property enables you to capture the image on the control. This is useful for performance tricks and for low-level control of the object's appearance. You need to use the Picture property when the object's application doesn't update the display correctly or when you want to display the object quickly, without loading the object's application.
To see how to capture the OLE object's picture, follow these steps:
Displaying the image of an OLE object in a picture box or image control can fix display problems with scaling. It can also speed up applications and save memory.
You can also save an OLE object's image as a Windows metafile by using the SavePicture statement, as in the following example:
By saving the images of objects to disk before exiting, you can make your OLE container applications appear to start up instantaneously—without waiting for other applications to load. For more information on this, see Chapter 14, "Advanced Programming Techniques."
By default, Visual Basic updates linked objects whenever the user saves the source data while editing the linked object. However, Visual Basic currently does not automatically handle changes that other users make to the source file (such as storing a file on a network), nor do such changes currently trigger events in Visual Basic.
To control updating in code, use the OLE control's UpdateOptions property, the Updated event, and the Update method.
Table 13.5 describes the UpdateOptions property's three settings.
Table 13.5 The UpdateOptions Property Settings
UpdateOptions Setting | Value | Description |
vbOLEAutomatic (default) | 0 | Updates the OLE control when the user changes or saves the data in the linked object. Not all applications update the OLE control on every edit, however. |
vbOLEFrozen | 1 | The user can edit the object, but the displayed object does not reflect the edits. Calling the Update method does not update the object from its source. |
vbOLEManual | 2 | The user can edit the object, but the displayed object doesn't reflect the edits. You can use the Update method to update the object from its source. |
The Updated event occurs when the user edits, closes, or renames the source file while editing the object from within the OLE control. The Updated event can also occur when the OLE control first loads (as at startup) if the source file for the link has changed since the last time that the control loaded.
These events occur regardless of the UpdateOptions property setting. However, not all applications notify the OLE control as they are updated. For instance, Microsoft Word does not trigger the Updated event until the user saves or closes the file. Microsoft Excel, however, triggers the Updated event each time that a cell of data on a worksheet changes.
The Updated event procedure has this form:
The Code argument corresponds to the type of update that occurred. Table 13.6 describes the possible values.
Table 13.6 Possible Values of the Code Argument
Code Constant | Value | Meaning |
vbOLEChanged | 0 | The object's data has changed |
vbOLESaved | 1 | The application that created the object has saved the object's data |
vbOLEClosed | 2 | The application that created the linked object has closed the file that contains the object's data |
vbOLERenamed | 3 | The application that created the linked object has renamed the file that contains the linked object's data |
Some actions might cause more than one event to occur. For example, if the user closes a file and saves changes, the OLE control receives three Updated successive events: vbOLEChanged, vbOLESaved, and vbOLEClosed.
Use the Update method to update linked objects from their source files. In Visual Basic 4.0, Microsoft has changed this method, which in Visual Basic 3.0 used the Action property setting OLE_UPDATE to update links. In Visual Basic 4.0, the Action property still works, but using the Update method makes code clearer and easier to understand.
By default, the OLE control activates its linked or embedded object as specified by the application that provides the object (usually by double-clicking) or when the user chooses Edit or Open from the object's pop-up menu. To control activation in code, use the AutoActivate property and the DoVerb method.
Table 13.7 describes the AutoActivate property's settings.
Table 13.7 The AutoActivate Property Settings
AutoActivate Constant | Value | Description |
vbOLEActivateManual | 0 | Activates the object when you call the DoVerb method |
vbOLEActivateGetFocus | 1 | Activates the object when the OLE control receives focus |
vbOLEActivateDoubleClick (default) | 2 | Activates the object when the user double-clicks the OLE control |
vbOLEActivateAuto | 3 | Activates the object when the application-specified event occurs; usually this is the same as vbOLEActivateDoubleClick |
The DoVerb method has this form:
The verbnumber argument corresponds to the index of the verb on the object's pop-up menu. If you omit this argument, the method performs the default verb (usually Edit).
To activate an object for editing, use the DoVerb method with no arguments. This triggers the default response from the object's application, which is usually to edit the object.
To ensure that the action taken is Edit, check the OLE control's ObjectVerbs property. The following code checks the OLE object's list of verbs. If it finds an Edit verb, it performs it.
When you activate a linked object, it opens in its application. Embedded objects can activate in place. To ensure that an object opens in its application, use the object's Open verb.
The following code checks the OLE object's list of verbs. If the code finds an Open verb, it performs that verb.
To deactivate an object, switch focus to another object on the form. Switching focus does not close any objects open in another application window.
When you open objects in another application window, you also must close those objects from within that application. If the application supports OLE Automation, you can close the objects programmatically through the OLE control's Object property.
The following lines of code activate an Excel object for editing. These lines open the object in the Excel application. Then the code uses the Excel Close method to close the workbook in Excel.
To use the Object property, you need special knowledge of the objects, properties, and methods that the application exposes. For instance, the following code shows how to close a Microsoft Word document. Note that this example differs significantly from the previous Excel example.
For more information on using OLE Automation methods and properties with an OLE object, see the section "Getting the OLE Automation Object from Linked or Embedded Objects" later in this chapter.
As previously mentioned, you store linked objects in separate files on disk and store embedded objects with their container. When you embed an object on a form, you store the embedded object's data with the form in your Visual Basic application.
The application that provides an OLE object supplies ways to save linked or embedded objects through the application's user interface. If your application saves its objects, you can load them into an OLE control by using the CreateEmbed or CreateLink methods. For information on using CreateEmbed and CreateLink, see the section "Creating OLE Objects at Run Time" earlier in this chapter.
To save a linked or embedded object from within code, use the OLE control's SaveToFile method. If you save OLE objects this way, their original application cannot open them directly; instead, you must open them by using the OLE control's ReadFromFile method. SaveToFile and ReadFromFile enable you to store and retrieve individual OLE objects in code.
Use the OLE object's SaveToFile method to save a linked or embedded object directly to a file, by following these steps:
When you use SaveToFile, you cannot save more than one object to a particular file. The method always overwrites the entire file.
Use the OLE object's ReadFromFile method to load a linked or embedded object directly from a file. To read an OLE object from a file, follow these steps:
Reading a linked object that SaveToFile saved restores the link to the original file.
Use the OLE control's Object property to get the OLE Automation object from a linked or embedded object on a form. Not all applications provide OLE Automation objects. If an object does not support OLE Automation, the Object property returns Nothing.
When working with OLE Automation objects, you should create an object variable to contain the OLE Automation object. For example, the following lines of code declare an object variable and establish a reference to an embedded worksheet when the form loads:
In the preceding example, the variable mobjExcelSheet has module-level scope; that is, other procedures in the module have access to the variable. For instance, the following Click event procedure uses the OLE Automation object mobjExcelSheet to print the embedded worksheet:
Unlike other applications that support OLE Automation, Microsoft Word requires the following special syntax to get its OLE Automation object:
You must use this special syntax because Word exposes only the WordBasic language for OLE Automation. When working with the Word OLE Automation object, remember that methods and properties apply to the current document, which might not be the one that the OLE control is currently displaying.
The following lines of code establish a reference to the WordBasic OLE Automation object:
The following two event procedures demonstrate how the WordBasic methods apply to the current document. If cmdOpenNew runs before cmdPrintDocument, Word prints the newly opened document rather than the one that the OLE control is currently displaying.
My OLE controls do not always update the display correctly.
If the control appears grayed after you edit an object, try closing the object's application. If that does not help, reload the object on the form. In extreme cases, you might have to capture the OLE object's image and display it within a picture box or image control. For information on how to do so, see the section "Capturing the Object's Picture" earlier in this chapter.
When I edit linked or embedded objects, my application crashes.
Be careful when opening linked or embedded objects for editing. Having more than one object open in the same application might cause that application to crash.
When using an OLE object's OLE Automation object, I frequently encounter "Method or property does not exist" errors.
Usually this error indicates that you are using the wrong syntax. Check the application's documentation for the method. Often the problem involves the number of arguments or their data types.
My application doesn't recognize an object that it created.
Even if your application creates an object, it doesn't recognize that object after the SaveToFile method saves it. You can load such objects only by using the ReadFromFile method.
For more information on the following topics, see the indicated chapters:
© 1996, QUE Corporation, an imprint of Macmillan Publishing USA, a Simon and Schuster Company.