Object Linking and Embedding (OLE) is at the center of most of the changes in the new version of Visual Basic. In version 4.0, Visual Basic itself is an OLE container, and Microsoft provides the core language as an OLE object. This chapter describes these changes and how they affect you.
In this chapter, you learn about the following:
If you're already familiar with Visual Basic 3.0's OLE features, this section helps you take advantage of the new features and changes in Visual Basic 4.0. This section is just a summary, however. These new features are explained in greater depth throughout the rest of Parts II and III of this book.
The OLE 2 custom control is now built in to Visual Basic as the OLE container control in the Visual Basic Toolbox.
Visual Basic forms now support menu negotiation for OLE objects. Embedded OLE objects can add their application's menu items and toolbars to Visual Basic menu bars.
The OLE control is now built in to Visual Basic. The control appears in the Toolbox, just as it did in Visual Basic 3.0 (see fig. 11.1). The new control contains code improvements and bug fixes, plus changes to accommodate updates to the OLE 2.0 DLLs.
The built-in OLE control on the Visual Basic 4.0 Toolbox looks the same as the version 3.0 custom control.
Unlike custom controls, built-in controls can have their own methods. Therefore, Visual Basic now provides the Action property setting as methods. Although Visual Basic still provides the Action property for compatibility with existing programs, the new OLE control methods make the code much easier to read and understand. Table 11.1 compares the old Action property settings to their new method equivalents.
Table 11.1 Visual Basic 3.0's OLE Control Action Property Settings Compared to Version 4.0's Methods
Action Property Setting | Equivalent Method Name | Task |
OLE_CREATE_EMBED (0) | CreateEmbed | Creates an embedded object |
OLE_CREATE_LINK (1) | CreateLink | Creates a linked object from a file's contents |
OLE_COPY (4) | Copy | Copies the object to the system Clipboard |
OLE_PASTE (5) | Paste | Copies data from the system Clipboard to an OLE container control |
OLE_UPDATE (6) | Update | Retrieves the current data from the application that supplied the object and displays that data as a picture in the OLE container control |
OLE_ACTIVATE (7) | DoVerb | Opens an object for an operation, such as editing |
OLE_CLOSE (9) | Close | Closes an object and terminates the connection to the application that provided the object |
OLE_DELETE (10) | Delete | Deletes the specified object and frees the memory associated with it |
OLE_SAVE_TO_FILE (11) | SaveToFile | Saves an object to a data file |
OLE_READ_FROM_FILE (12) | ReadFromFile | Loads an object that the user saved to a data file |
OLE_INSERT_OBJ_DLG (14) | InsertObjDlg | Displays the Insert Object dialog box |
OLE_PASTE_SPECIAL_DLG (15) | PasteSpecialDlg | Displays the Paste Special dialog box |
OLE_FETCH_VERBS (17) | FetchVerbs | Updates the list of verbs that an object supports |
OLE_SAVE_TO_OLE1FILE (18) | SaveToOle1File | Saves an object to the OLE 1 file format |
When you edit an OLE object in-place, the object's application can supply menu items and toolbars for editing the object. Visual Basic 3.0 ignored these OLE features, but version 4.0 enables you to include them on your form, as shown in figure 11.2.
A Visual Basic MDI form displays the menu items and toolbar from the embedded object when you edit it in-place.
To get menu negotiation to work on your forms, set the Negotiate Position option for the form's menu in the Menu Editor (fig. 11.3).
The Negotiate Position list box in the Menu Editor determines how OLE in-place menus appear on a form.
You can add embedded objects directly to the Toolbox and then draw them on the form, just as you would any other control (fig. 11.4).
Add insertable OLE objects to the Toolbox.
To add insertable OLE objects to the Toolbox, use the new Custom Controls dialog box (fig. 11.5).
Choose Tools, Custom Controls to display the Custom Controls dialog box.
OLE custom controls (.OCX) look and work the same as old-style custom controls (.VBX). However, .OCX controls provide the following advantages over .VBX controls:
Visual Basic 4.0 ships OLE custom controls that replace all the .VBX controls included in Visual Basic 3.0 Professional Edition. Visual Basic can automatically upgrade projects that contain .VBX controls so that they can use their .OCX control equivalents.
You use the new Object Browser, shown in figure 11.6, for viewing the objects, properties, methods, constants, modules, and Visual Basic procedures. Visual Basic itself is an OLE application, so you can use the Browser to view Visual Basic's objects and language.
Choose View, Object Browser or press F2 to display the Object Browser dialog box.
The Object Browser displays the syntax of the item selected in the Methods/Properties list box. You can find help on the item by clicking on the question mark (?).
The Visual Basic language gains some new keywords from Visual Basic Applications Edition (VBA). If you have programmed in Excel with VBA, you are already familiar with most of the new items listed in table 11.2.
Table 11.2 Visual Basic 4.0's New Language Features
Item | Use |
For Each...Next | Iterate over the items in an array or a collection of objects, such as the Controls or Forms collection |
With...End With | Apply a set of methods or properties to a specific object. |
Line continuation ( _ ) | Break a long line of code over two or more lines. |
Optional parameters | Define parameters that the code might omit when calling the procedure. |
IsMissing function | Determine whether the code omits an optional argument. |
Property procedures | Create object properties in a class module or form. |
Public/Private | Control the scope and visibility of variables, procedures, and constants. You can make event procedures Public to call them from modules outside of the form that contains them. |
TypeName function | Determine a variable's object type or data type. |
By using several of these new language features together, you can create your own objects in Visual Basic. Table 11.3 describes how you use these features to create an object.
Table 11.3 Features for Creating Visual Basic Objects
Feature | Use |
Class modules | Create an invisible object that provides general services. Through OLE Automation, other applications can use objects in class modules. |
Form modules | Create a visible object. Other modules in an application can use objects in form modules. Also, you can make such modules available to other applications by using methods defined in a class module. |
Property procedures | Add properties to an object defined in a class or form module. |
Sub or Function procedures | Add methods to an object defined in a class or form module. |
Public and Private scope declarations | Make a property or method available to all other modules or local to the containing module. |
Class module Creatable property | Make an object available to other applications through the CreateObject and GetObject functions. |
Class module Public property | Make an object visible to other applications in the Object Browser. |
Figure 11.7 shows a class module in a Visual Basic project.
Use a class module to contain code that you want to package as an object.
The Options properties pages enable you to set two startup modes for the applications that you create: stand-alone application and OLE server (fig. 11.8). OLE servers expose their class modules as objects that can be used from other applications.
Visual Basic applications can use each other's objects, so you need a way to debug multiple Visual Basic applications at the same time. Visual Basic now enables you to run several copies of itself simultaneously. By doing so, you can trace code execution from one application to another.
Choose Tools, Options to display the Options properties pages.
The new Add-In Manager dialog box (fig. 11.9) enables you to load extensions to the Visual Basic programming system. Add-on tools from third-party vendors, such as Sheridan's VB Assist, can add items to the Visual Basic menus and respond to events in the Visual Basic programming environment.
Choose Add-Ins, Add-In Manager to display the Add-In Manager dialog box.
Visual Basic Professional Edition includes tools and documentation for creating your own Visual Basic add-ins. Visual Basic accesses these add-ins through OLE Automation, using the objects, methods, and properties defined in the add-in's class module. Figure 11.10 shows the Regadd add-in that is used as a sample in Chapter 24, "Creating Add-Ins."
The Regadd sample add-in enables you run the Registry Editor from within Visual Basic.
OLE makes it much easier for applications to share data effectively with one another. Because they can so easily share data, individual applications can focus on the tasks that they perform best instead of trying to be all things to all users. Figure 11.11 illustrates how desktop applications have evolved to share data with each other.
As shown in figure 11.11, early desktop applications written for MS-DOS had a very hard time sharing data among applications. Only one application could run at a time, so you had to save your data to disk, exit, and load the data in the next application. Some applications, like SideKick, worked around this laborious process by using a technique called terminate-and-stay-resident (TSR). A TSR application could "pop up" as you worked in another application, perform a task, and then return you to your previous application. TSRs were tricky to write, however, and took up blocks of the limited memory (640K) available to your main application.
Another DOS programming approach to sharing data was to build all your needed applications into a single .EXE file. Lotus 1-2-3 1.0 is the most successful example of this approach. By combining spreadsheet, word processing, and data management tasks, Lotus 1-2-3 could meet most users' needs within a single application. Users could share the data among the pieces of the application without exiting. In later versions, however, Lotus 1-2-3 ran into problems related to its size. Because the application tried to fit three specialized tasks into a limited space, it had to sacrifice features or speed.
Under DOS, applications struggled to share data with each other.
By the time Lotus 1-2-3's size became a serious problem, Lotus had several approaches that it could employ to address it. Most of these approaches involved "end-runs" around the operating system to gain access to additional memory. Those were turbulent times full of expanded memory managers, complicated strings of drivers in CONFIG.SYS, and many hardware and software incompatibilities.
Windows 3.0 and the Intel 80386 CPU finally laid all these divergent approaches to rest. Windows used the new CPU's protected-memory features to enable multiple applications to run at the same time. In addition, Windows added a system service, the Clipboard, to enable applications to share data.
The Clipboard was very limited, however. It could hold only one item at a time, and any application could overwrite its contents with new data at any time. To share data between two applications reliably, the two applications needed a dedicated channel. OLE 1.0 introduced this channel as Dynamic Data Exchange (DDE).
Using DDE, a source application could transmit data to a target application, and the target would send back an acknowledgment after receiving the data. Although more reliable than the Clipboard, DDE was still prone to problems. If the connection failed, it was difficult to determine why. Did the other application terminate? Was the system busy? Another limitation of DDE was that it supported only the transfer of textual data. Bitmaps, formatted text, and other binary data could not cross a DDE channel.
OLE breaks everything into small, usable parts called objects. On a technical level, OLE defines the way that these objects fit together. Think of OLE objects as Lego blocks, with OLE as the little, stubby pegs and corresponding orifices on the tops and bottoms of the blocks that enable the blocks (objects) to fit together snugly, as shown in figure 11.12.
OLE defines how objects fit together. You can use OLE objects to assemble whatever you want.
With Legos, you don't have to worry about which parts fit together—they all interconnect the same way. You don't think about the little doohickies on each block that make these connections possible, until you step on a block with your bare feet one cold morning.
The same principle applies to OLE objects: You don't have to worry about why the pieces snap together as long as you remember to put your toys away when you finish playing with them. Visual Basic keeps OLE objects in the Toolbox (fig. 11.13).
In Visual Basic 4.0, you can add OLE objects directly to the Visual Basic Toolbox and then add the objects directly on a form by drawing them.
As mentioned previously, OLE objects are data plus behavior. The OLE DLLs give container applications access to both the object's data and the functions (behavior) that the object provides. Container applications use the object's application code to display, activate, and edit the object.
You can extend OLE slightly to make more of an object's functions available to a container application—which is where OLE Automation comes in. OLE Automation is part of OLE 2.0; it uses the same DLLs and is part of the same standard, but it is generally treated separately from the rest of OLE because a separate group within Microsoft developed it and because OLE Automation serves a different purpose than the rest of OLE.
Under OLE Automation, an OLE object's application can provide methods and properties for each object. Programming languages such as Visual Basic and Visual C++ can use these properties and methods to perform actions within the OLE object's application (fig. 11.14).
OLE Automation enables Visual Basic to use an OLE object's properties and methods.
OLE Automation enables Visual Basic to use an OLE object's properties and methods.
Although the code resides in your Visual Basic project, it executes within the object's application. You can use OLE Automation to control other applications remotely, or to control OLE objects that you embed on your forms.
OLE Automation enables you to build an application from precompiled parts (OLE objects) instead of having to create your own components for everything. If you have used custom controls extensively, you already understand the utility of component architecture. Building an application with components rather than with line-by-line code saves time and simplifies maintenance.
For example, inserting a Word document on a form is easier than programming all your own word processing tasks into a text box. When you insert a Word document on a form, you also provide your form with thousands of features, including formatting, printing, and spell checking. Using a text box, you would have to write code for each of those features.
OLE Automation objects are part of a separate, stand-alone application, such as Microsoft Excel or Word. Custom controls exist only as part of another application. Although you can access custom control methods and properties from within your current application, you cannot access custom controls from other applications. Figures 11.15 and 17 illustrate this difference.
OLE Automation objects' cross-application boundaries.
Custom controls are available only within an application.
With OLE Automation, you can use the methods and properties that are in another application. DLLs enable you to do something similar: call functions from the DLL in your Visual Basic code. OLE Automation provides the following important differences, however:
Because of these differences, OLE Automation is much easier to use than DLLs in Visual Basic code. Chapter 18, "Creating Objects," shows you how to repackage DLLs, such as the Windows API, in the form of OLE Automation objects.
Container applications don't call OLE objects directly; instead, they send their requests to the OLE DLLs, which pass the requests to the OLE object's application. Figure 11.17 illustrates this interaction and table 11.1 describes the OLE DLLs.
The OLE DLLs intercede between OLE containers and OLE objects.
Table 11.4 OLE DLLs and the Services That They Provide
DLL File | Function |
COMPOBJ.DLL | Create and access OLE objects |
OLE2.DLL | Perform standard OLE actions on objects |
OLE2CONV.DLL | Convert data in an OLE object from one type to another |
OLE2DISP.DLL | Access OLE Automation objects by invoking methods and properties |
OLE2NLS.DLL | Perform string comparisons based on the user's national language |
OLE2PROX.DLL | Coordinate access to objects across processes |
STORAGE.DLL | Save OLE objects to files and read OLE objects from files |
TYPELIB.DLL | Access object libraries that describe OLE Automation objects |
The OLE DLLs are interdependent; they must all be present for OLE to work.
OLE uses the system registration database to find the .EXE and .DLL files that provide OLE objects and to determine what services the OLE objects provide. You can view the system registration database by using the Registry Editor (REGEDIT.EXE), as shown in figure 11.18.
Enter the command REGEDIT /V to see a full listing of the system registration database.
The system registry is the Windows equivalent of the MS-DOS PATH environment variable, although the system registry includes much more information. Applications that support OLE write to the system registry their location on disk and the services that they support. The OLE DLLs check this information whenever a request is made for an OLE object (fig. 11.19).
Applications register their information, and then OLE uses the information to fill requests.
OLE objects that support OLE Automation have another file, an object library, that contains much more information than the system registry. The object library contains a complete description of an object's properties, methods, and constants. You can view an object's object library by using the Visual Basic Object Browser, as shown in figure 11.20.
The Object Browser lists the properties, methods, and constants that an OLE Automation object defines.
Visual Basic uses the information in the object library to bind to the code in an OLE object's application. When you compile your application, Visual Basic writes these bindings into your application so that your application calls the code directly.
OLE 2.0 is certainly a great improvement over OLE 1.0. It extends applications beyond their traditional boundaries to let them share data and tasks smoothly. However, many important areas could still use improvement. Some of the areas are within OLE itself, others are within the applications that provide OLE objects. The following are some of the current limitations of OLE 2.0:
Microsoft developed OLE 2.0 specifically to solve the problems with OLE 1.0. OLE 2.0 needed to provide the following:
A little word like data can hide a lot of complexity. You might tend to think of data as neat little 80-column rows of ASCII characters, but in fact, data is more like any sort of gooey stuff that an application might decide is useful. Because there's no accounting for some applications' taste, you have no way to anticipate the type of data that one application might want to share with another.
Instead of trying to enumerate all the types of data that an application can share, OLE defines a set of services that each application must provide for each type of data to share. These services enable other applications to do the following:
Data that defines all these services is called an OLE object (data + behavior = object).
OLE also defines how applications request and use services from an OLE object. Applications that follow these rules are called OLE containers. Figure 11.21 shows how an OLE container and an OLE object interact.
An OLE container with an OLE object.
Because OLE is all about sharing data, the document in which an OLE object appears may or may not store that object. OLE objects stored in the currently open document are called embedded objects. Objects displayed in one document but actually stored in a separate file are called linked objects. Figure ll.23 illustrates the difference between linked and embedded objects.
Linked objects versus embedded objects; the difference is where the data resides.
Figure 11.23 glosses over a sticky issue: Under OLE, the word file is no longer synonymous with the word document. A document can contain several different OLE objects, some of which may be stored in other files. OLE calls such documents compound documents. Figure 11.23 shows what actually is stored in an OLE compound document file.
A compound document includes the data for embedded objects and the location of linked objects.
When a user opens a compound document, the container application displays a picture of each of the OLE objects that the document contains. You can edit directly objects that the container application created (called native data). If the objects are from other applications, you must activate them before you can edit them.
When you activate an object, the OLE DLLs start the application that created the object. You activate embedded objects in place—that is, you can edit them without leaving the compound document. You open linked objects in a separate window that contains the application that created the linked object. Figures 11.24 and 11.25 show the difference between editing embedded and linked objects.
Double-click a linked object to edit it in a separate window.
Double-click an embedded object to edit it in place.
When an embedded object is active for editing, the menu bars and toolbars from the object's application replace the menu bars and toolbars that the container application normally displays. Only the container application's File menu remains unchanged, because the container application is still responsible for saving the compound document or opening new documents. This feature is called menu negotiation.
Not every object provides the same actions. For example, you may not be able to "edit" an embedded video clip. Similarly, you cannot "play" a word processing document. The user actions that an object supports are the object's verbs. A pop-up menu displays an object's verbs when the user right-clicks on the object (see fig. 11.26).
To display an object's verbs, right-click on the object.
When a user chooses one of the object's verbs, the OLE DLLs do the following tasks:
The user can deactivate the object by closing the object from the File menu or by activating another object. After the user deactivates the object, the OLE DLLs do the following:
Keeping track of the number of references to an application is one of the central tasks that the OLE DLLs perform.
OLE 2.0's goal is to enable the user to move data between applications as directly as possible. The most direct way to manipulate things in Windows is by dragging and dropping objects with the mouse. Naturally, OLE provides this capability between applications (see fig. 11.27).
Dragging an object from one application and dropping it into another.
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.