Visual Basic 3.0 was the first OLE 2.0compliant application to be released by Microsoft. Unfortunately, there were no commercial 16-bit OLE 2.0 source or server applications when Visual Basic 3.0 appeared in mid-1993. Visio (then Shapeware)
Corporation beat Microsoft to the punch by introducing the first 16-bit OLE 2.0 applicationVisio 3.0complete with OLE Automation server capability in late September of 1993. Microsoft followed shortly thereafter with OLE 2.0-compliant 16-bit
versions of Word, Excel, and Project. Microsoft Excel 5.0 was the first application to provide both OLE 2.0 client and server capabilities, and to include Visual Basic (Applications Edition) as its application programming (macro) language.
Visual Basic 4.0 is the first programming tool to take full advantage of 32-bit OLE 2.1, the foundation for Microsoft's concept of a "componentized version" of Microsoft Office, which was described by Bill Gates during his keynote address at
the Fall 1995 Comdex exposition. Instead of today's Office 95 mega-apps, future versions of Microsoft productivity software will consist of a collection of specialized OLE objects, loosely linked to individual documents. Concerning the features of new
Microsoft Office applications scheduled to arrive by the turn of the century, Gates says that you won't need to focus on particular applications or directories; you'll be able to navigate without having to start a program. Until the "OLE
millennium" arrives, however, you'll need to start a program to take advantage of OLE 2.1. Visual Basic 4.0 makes creating applications that orchestrate OLE 2.1 objects a reasonably simple task.
This chapter covers the following topics, with emphasis on the applicability of each of the topics to Visual Basic database applications:
If you're an experienced user of Windows word-processing or spreadsheet applications, you've undoubtedly employed OLE 2.x for a variety of purposes, such as adding graphs or charts to documents or embedding bitmapped or vector-based images. If
you've made extensive use of OLE 2.x, you might be tempted to skip over the general description of OLE that follows. However, the information in the sections that follow are important for all users of OLE, because these sections define the updated
object terminology employed by OLE 2.1.
OLE 2.1 uses Microsoft's Component Object Model (COM), the programming foundation on which all OLE 2.x applications are constructed. The terminology and descriptions of the general methodology of COM and OLE 2.x presented in the following
sections are based on OLE 2.0 guidelines established by Microsoft's Programmer's Guide for OLE 2.0, part of the documentation that accompanied the original OLE 2.0 Software Development Kit (SDK), and the OLE section of the Win32 SDK, which is includ
ed on the Microsoft Development Library Level II and Level III CD-ROMs.
OLE is a method of inter-process communication (IPC) for transferring documents between two Windows applications running on a PC under Windows 95, Windows 3.1+, Windows for Workgroups 3.1+, or Windows NT 3.1+, or between two applications running on an
Apple Macintosh computer under System 7+. You also can use OLE as an IPC on a RISC-based computer that uses the MIPS or Digital Equipment Alpha MPU chips and runs Windows NT 3.1+. OLE 1.0 and 2.0 are designed for use on a single computer. This means that
both the OLE container (client) and the server application must run simultaneously on your computer. OLE 2.1 and Visual Basic 4.0, however, let you create Remote Automation Objects (RAOs) that reside on PCs running Windows NT 3.51+ Server. Applications
that are 16-bit and 32-bit Visual Basic 4.0 as well as other applications that support VBA can connect to RAOs through Remote Procedure Calls (RPCs) over the network. Visual Basic 4.0 RAOs are discussed Chapter 23, "Creating and Managing Remote
Automation Objects."
Future versions of OLE and products that are intended to compete with Microsoft's COM and OLE standards, such as Common Object Request Broker Architecture (CORBA) and the OpenDoc "standard" proposed by Apple, IBM, and Novell, are expected to
be able to share any type of OLE object, not just RAOs, across networks of computers that run a variety of operating systems. Microsoft's dominance of the productivity applications software suite business (Microsoft Office is reported to have 90 percent or
more of the market) and delays in releasing OpenDoc SDKs has relegated OpenDoc to a distant second in the "object wars" of the late 1990s.
The next major step in Microsoft's OLE development program is to implement NetworkOLE on Windows NT Server and Windows 95 clients. (Microsoft has referred to Visual Basic's RAO as "NetworkOLE 0.9.") NetworkOLE is required to implement Bill
Gates's vision of networked productivity application components and is needed to extend the reach of OLE to the Internet and beyond. Microsoft Interactive TV (MITV), as an example, uses NetworkOLE for future bi-directional cable TV networks that promise
video-on-demand (VOD), near-VOD, and interactive video entertainment. The next major version of Windows NT, code-named Cairo, and future versions of Windows 95 are expected to include the production version of NetworkOLE.
The word object doesn't appear in the index of Bill Gates's long-awaited book, The Road Ahead, which was published while this chapter was being written. A brief description of the concept behind MITV and a photograph of a prototype of a media server for MITV, code-named Tiger, appears on page 70 of the book. The Tiger server shown in the book was first demonstrated to the public at Cable '95, the mid-1995 convention of the National Cable TV Association. Microsoft's glossy brochure, "Microsoft Interactive TV: In Detail," describes the use of NetworkOLE in conjunction with interactive TV.
The sections that follow describe the terminology applicable to the current versions of OLE.
A document, in OLE terminology, is any object that is created by a Windows application and contains some type of data. A document can be a bitmapped image created with Windows 95 Paint, an Excel worksheet (or a range of worksheet cells), part or
all of a Microsoft Word document, a Visio diagram (.vsd), a waveform audio (.wav) file, a video clip (.avi), or a MIDI music (.mid) file.
The application that initiates the communication link to embed or link the OLE object is called the container application. The application that originally created or that supplies the linked object is called the server application.
Container applications were called OLE clients prior to the introduction of OLE 2.0. Container applications create compound documents. A compound document is a document in the container application's chosen format (called an object
class) that contains a document object created by a server application that uses a data structure different from the container application. Figure 14.1 illustrates a three-level hierarchy of OLE documents. The source document itself can be a compound
document, in which case it is said to have nested objects.
Figure 14.1. A diagram of a Visual Basic 4.0 compound document containing another compound document.
You cannot edit a nested source document (the smaller white document in Figure 14.1) contained in a OLE 1.0 source container document (the document with the gray surface in Figure 14.1) that, in turn, is embedded or linked into your container application's compound document. An OLE 2.x server is required to edit nested objects.
When you link or embed an OLE object from a source document into a container application's document, you create the compound document. The differences between documents that are embedded in or linked to a container document are as follows:
With graphic images created by most OLE server applications, you do not save disk space by linking instead of embedding the image. This is because creating the presentation of the image requires the same data as is stored in the file. The presentation of OLE images is contained in a Windows metafile. If the presentation contains a bitmap, your application can clip or scale the metafile that contains the bitmap, but the size of the original data remains the same. You need specialty OLE server applications or OLE controls that create thumbnail images, such as the MultiMedia Tools of Lenel Systems, to take advantage of the disk space savings offered by linking bitmapped images. A thumbnail image is a miniature version (not a scaled version) of the original image, usually about the size of an application icon. The presentation of a linked video clip (.avi file) is the first frame of the clip.
Linked objects can be updated to current data values by either an automatic link or a manual link. An automatic link refreshes the presentation by opening and reading the file designated by the link when the form containing linked object
activates. A manual link requires that you activate the object, make a menu choice, or click a command button to update the presentation. You can link the entire file (a complete object), or only a range of cells or a block of text (a partial
object).
The following list describes the four major categories of OLE 2.x servers:
Qualifying to apply Microsoft's trademarked "Designed for Windows 95" logo for Windows software packages requires that the application be 32-bit and support OLE 2+ containers, objects, or both containers and objects. This requirement, which isn't applicable to utilities or applications that run exclusively in full-screen mode (particularly PC games), has increased the number and variety of OLE servers, and to a lesser extent, OLE container applications. The level of required OLE support depends on whether an application uses files; applications that open files must support OLE drag-and-drop operations. Support for in-place activation, compound files, and OLE Automation is strongly recommended, but not mandatory. You're not likely to find an OLE 2.x full server or mini-server application that doesn't support in-place activation.
OLE 2.1 running under Windows 95 and Windows NT provides support for interoperability of 16-bit and 32-bit by a process called thunking. The following list describes how 16-bit and 32-bit OLE objects can interoperate with 16-bit and 32-bit
container applications:
Windows 3.1+, Windows 95, and Windows NT 3.5+ use a variety of thunking processes (Universal, Flat, and Generic, respectively.) The "Thunk Layer Operation" chapter of the OLE Programmer's Reference in the Win32 SDK provides detailed information on the thunking process for OLE 2.x operations.
OLE 2.x extends the capabilities of OLE 1.0 with the following new features:
Each of these features, with the exception of object programmability, is discussed in the sections that follow. The next chapter, " Using OLE Automation with Productivity Applications," describes the new object programmability feature of OLE
2.x, how you program objects with Visual Basic 4.0, and how VBA fits into the OLE picture. Subjects such as the effect of OLE 2.x on the Windows 95 and Windows NT Registry, the new and improved Insert Object dialog of OLE 2.1, and how Visual
Basic 4.0 interacts with OLE server applications are discussed later in this chapter.
An OLE 1.0 server application opens its own window when you edit or play a linked or embedded object. If the OLE 2.x application supports in-place activation (also called in-place editing), the behavior of an embedded source document
differs from the norm for OLE 1.0. OLE 2.x's in-place activation feature has four defined states:
OLE 2.x servers can create outside-in and inside-out objects. Outside-in objects require the user to double-click the object or select Activate from a menu to activate the object. Inside-out objects are active at all times; they can be edited in place and can remain in the active state when the input focus moves to another control or form. Inside-out objects, typified by OLE Controls, behave as if they were part of the container document itself, rather than objects created by another application. Microsoft's criterion for server applications that create inside-out objects is that the server must load in no more than a half second. Thus, mega-apps (applications with .EXE files exceeding 1MB) need not apply for inside-out status. The half-second requirement is somewhat ambiguous because Microsoft did not specify a standard hardware platform for testing object loading time.
OLE applications of any type register the verbs that control the actions your container application can apply to the source object and server application. The two most common verbs are Edit and Play; however, server applications can register special
verbs, such as Slide Show (in PowerPoint), Edit Package and Activate Content (in Object Packager), and Open. OLE server applications register their verbs in the Windows 95 and Windows NT Registry databases. OLE 2.x's Registry entries are discussed
later in this chapter.
The simplest method for embedding or linking an OLE 1.0 object to create a compound document is to select all or a portion of the document and copy the selection to the Clipboard and then use the Paste Special choice of the Edit menu to
embed or link the object in your container document. When you choose Paste Special, instead of Paste, a dialog lets you select between embedding or linking the object. (Paste automatically embeds the object.) OLE 2.x adds a new
and even simpler way of creating a compound objectdragging a file from Windows Explorer or an document icon from the desktop, or dragging a selection from an open source document into your container document and dropping it where you want it. As an
example, in Visual Basic design mode, you can add an OLE container control of any object type, then drag a file from Windows Explorer and drop it on the control. This action replaces the object in the OLE Control. You also can drop files into the OLE
Control in run mode if you set the value of the OLE container control's OLEDropAllowed property to True.
Figure 14.1, shown earlier in this chapter, illustrates a hierarchy of compound documents that contain other compound documents (nested objects). The explanatory text for Figure 14.1 mentions that you only can edit the first level of source documents
with OLE 1.0. OLE 2.x enables you to edit compound documents created with OLE 2.x server applications that are nested as deeply as you want. This is because OLE 2.x treats compound documents as containers at each level of embedding or
linking. You can open the application that created the source document in your container document and then open the application that created the source document in the next (deeper) object layer. You return to your own container application by successively
choosing File | Exit in the server application that created each of the nested objects.
When you create an OLE 1.0 compound document in a container application, the properties of the source document, such as the type font used to display data, are determined within the source application. If you link a spreadsheet to a word processing
document, the word processing document's font (11-point Palatino, for example) and the font used by the spreadsheet (9-point Helvetica, for example) might not be compatible from a stylistic standpoint. If you alter the font of the spreadsheet, the change
becomes a permanent part of the source document file. Changing the spreadsheet font may make the spreadsheet's appearance inconsistent with the other members of its class.
OLE 2.x solves this dilemma by providing compound documents with container property inheritance. Property inheritance enables the source document to inherit the values of the container's properties, such as the font used for the object's
presentation. Thus, the presentation of a spreadsheet object takes on the appearance of the word-processing container document and gives the illusion of being an integral part of the container document. OLE 2.x objects that support property
inheritance are called smart OLE objects.
OLE 2.x is designed for multiplatform applications that use a variety of operating systems and graphical environments. At present, OLE 2.0 is supported by Windows 3.11, Windows for Workgroups 3.11, Windows NT 3.1+, and Apple's System 7+. This
means that objects you create on PC, Macintosh, and RISC computers for which Windows NT is available need to be interoperable on each type of computer. OLE 2.1 requires Windows NT or Windows NT 3.51+; it along with OLE 2.0 is within the limitations
described in the section titled "Interoperability of 16-Bit and 32-Bit OLE Clients and Servers." The objective of OLE 2.x's object-type conversion and emulation is to make objects created by a server that is resident on one platform behave
in the same manner when you manipulate the objects with a different server on another type of computer. The two methods by which OLE 2.x accomplishes this feat are as follows:
In 16-bit Windows, the type of an OLE object is defined by entries in the registration database that equate a file extension and a programmatic identifier (ProgID), such as .xls=Excel.Sheet.5. In turn, another entry converts the type designator to a
description (long name) of the object class, as in Excel.Sheet.5=Microsoft Excel 5.0 Sheet. If you have additional .xls=ObjectType.Class entries, these ProgID entries represent your type emulation or conversion options for .xls files. Windows 95 and
Windows NT use Registry keys in HKEY_CLASSES_ROOT to relate the ProgID to the file extension. The Registry's (Default) value for the .xls key in HKEY_CLASSES_ROOT is the data string "Excel.Sheet.5". Entries for OLE 2.x servers in
the registration database are discussed in the section titled "Installing OLE 2.x Applications and the Registry," which follows shortly.
OLE 2.x offers four additional features that fall into the category of utility functions. The following is a description of the four utility functions:
When you install an OLE server application under Windows 95 or Windows NT, the setup application for the new software adds entries to your Registry (System.dat and User.dat) files. The purpose of the Registry, which treats both files as a common
database, is to provide a persistent source of information on the associations between the file typespecified by a unique file extensionand the OLE object type. The Registry also provides the information that File Manager needs to associate an
application with a file extension, so that, for example, dragging a .txt file icon from Explorer and dropping it on a printer icon causes Notepad to open and print the file.
The registration data for Windows 95 and Windows NT is stored in a binary format, which is more robust than the format of Windows 3.1's REG.DAT, which has the unfortunate characteristic of being easily corruptible. Windows 95 creates a backup of
System.dat and User.dat (System.da0 and User.da0) each time you launch Windows. System.dat stores information on the hardware and software installed on the computer; User.dat stores information about the user(s) of the computer and specific system
configurations for the user(s). In the event a problem is detected with a previous version of the Registry, the backup files replace the originals. Windows NT takes the manual approach to Registry restoration, allowing you to use the "Last known good
menu" during boot. Information that was contained in Windows 3.1+'s WIN.INI and SYSTEM.INI files now is stored in the Registry. For backward compatibility, Windows 95 also reads WIN.INI and SYSTEM.INI, but corresponding Registry entries override
entries in these .INI files. The ultimate objective of Windows 95 and Windows NT 3.5+ is to eliminate conventional .INI files. If you install Windows 95 on a new machine or in its own directory, then install only 32-bit Windows applications; the .INI files
contain few or no entries.
Windows 95's Registry files are much larger than the combination of Windows 3.1's WIN.INI, SYSTEM.INI, and REG.DAT. As an example, the combination of System.dat and User.dat on the computer used to write this book is close to 2MB. The bulk of the data in the Registry is devoted to registering OLE servers of various classes.
Windows 95 provides a new Registry Editor application (RegEdit), which enables you to view and modify Registry entries. You launch RegEdit from the Start | Programs | Accessories | System Tools menu. Figure 14.2 shows the opening window of RegEdit with
the HKEY_CLASSES_ROOT entry for .bas files expanded. The (Default) value, "E:\VB4\vb.exe %1", launches the 16-bit version of Visual Basic 4.0 when you double-click a .bas file. Windows NT versions through 3.51 use Regedt32.exe, which is similar
to the less elegant Windows 3.1+ version of RegEdit. The next version of Windows NT, which was in beta testing as Windows NT 4.0 when this edition was written, is expected to include a version of RegEdit similar to that of Windows 95. Therefore, this
edition only covers the Windows 95 version of RegEdit.
Don't make changes to Registry values unless you know exactly what you're doing. Be sure to make a note of prior Registry values before making a change. An incorrect value of Registry data can prevent Windows 95 from booting. Registry files and backups
are hidden, system files. To manually replace System.dat and User.dat with the backup copies, you must use DOS's Attrib.exe application to remove the hidden and system attributes of both sets of files, copy the backup versions over the originals, and then
reset the file attributes to their original state. This is not a fun process and is fraught with opportunity for error.
Traditionally, file extensions have been used to identify the data type of DOS files. Prior to the advent of OLE 1.0 and REG.DAT, Windows 3.0 used entries in the [Extensions] section of the WIN.INI file to create associations between file extensions
and applications, such as txt=notepad.exe ^.txt, to create an association between .TXT files and Windows Notepad. Windows 3.1's OLE 1.0 and enhanced File Manager required more information than was practical to add to the already-overcrowded WIN.INI file.
Therefore, Windows 3.1 substitutes registration database for the WIN.INI [Extensions] entries. File-type association entries in REG.DAT are similar to those in WIN.INI. For example, .bmp = PBrush associates bitmap (.BMP) files with Windows Paintbrush
application (PBrush). PBrush is the programmatic identifier (ProgID) for Paintbrush.
As Windows applications have increased in sophistication, using file extensions to specify object types has become a problem. As an example, Excel 7.0 .xls files now contain Workbook, Sheet, Chart, and Excel VBA Module objects. The ProgID value
for all but the .xlc file type of versions prior to Excel 5.0.xls, .xla, .xlm, and so onis Excel.Sheet.5. Files with the.xlc extension are associated with the Excel.Chart.5 object. Saving all of the objects
supported by an application in a single file type, such as Access's .mdb database files, makes applications simpler to use. On the other hand, the "single file contains all" approach complicates that portion of your life that is devoted to Visual
Basic programming. If, for example, you link an Excel Chart object to a Visual Basic OLE container control, the user can activate the object, open worksheet behind the chart, and modify the value it contains.
Although the 32-bit version of Excel is 7.0, the object and file structure of Excel did not change in the upgrade from 16-bit Excel 5.0 to 32-bit Excel 7.0. Therefore, ProgIDs for Excel 7.0 refer to version 5.0 objects. The same is true for the 16-bit Word 6.0 upgrade to 32-bit Word 7.0; the Word 7.0 ProgID is Word.Document.6. Versions of Access prior to 7.0 were not OLE servers, so this issue doesn't apply to Access 95 (version 7.0).
OLE 2.x server registration occurs in the HKEY_CLASSES_ROOT\CLSID hive of the Registry. A hive corresponds to a subfolder (subdirectory) of the Registry. CLSID (Class ID) is a 32-character GUID (Globally-Unique IDentifier) that uniquely
identifies each OLE 2.x server. To check the registration data for an OLE server, launch the Registry Editor and choose Edit | Find to open the Find dialog. Type the executable file name, including the extension or the ProgID in the
Find What text box and click the Find Next button. Press F3 to bypass file extension association entries until RegEdit reaches the . . .\CLSID hive. Figure 14.3 shows the result of searching for Excel.Sheet.5; the CLSID for Excel is
{00020810-0000-0000-C000-000000000046}. The 32-bit LocalServer32 data entry for Excel 7.0 points to the location of Excel.exe on your fixed disk"E:\MSOffice\Excel\Excel.exe" on the computer used to write this edition. If the entry does not
point to the current location of the server, double-click the string ("AB") icon to open the Edit String dialog shown in Figure 14.4. Edit the Value Data string as required to specify the new location for both the 32-bit LocalServer32 and 16-bit
LocalServer values, unless you want to use Excel 5.0 for testing 16-bit container applications.
Figure 14.3. The Registry Editor displaying the result of a search for Excel.Sheet.5.
You only need to edit the pointer to the location of an OLE server if you move the server files from one folder to another. Manually moving the location of OLE servers is not a recommended practice. Instead, you uninstall the server and then reinstall it in its new location. To qualify for the "Designed for Windows 95" logo, all applications must include uninstall programs that remove the applications' files and all registry entries.
There also are CLSID entries for Excel Chart (ProgID = Excel.Chart.5) and Application objects, each of which points to d:\path\excel.exe. ProgID is the name of the object used with Visual Basic's CreateObject() function for
creating an instance of an OLE Automation server object, called late binding. Launching Excel 7.0 as an OLE Automation server requires adding the /Auto command-line parameter to preclude its window from appearing as well as adding the
Microsoft Excel item to the taskbar. Unfortunately, RegEdit doesn't have an Edit | Replace menu choice to change all the required entries. It's likely that Microsoft considered Edit | Replace to be too dangerous an operation. If
you've changed the location of an OLE server, it's easier to reregister the server using Regsvr32.exe (or Regsvr.exe for 16-bit servers), as described in the next section.
Windows 3.1+'s REGEDIT.EXE (opened with the /V parameter for verbose mode) and Windows NT's 3.5's Regedt32.exe use similar entries to specify the location of OLE servers. Only Windows 95's Regedit.exe, however, includes the full-featured Edit | Find feature described in this section. You must manually locate entries for server registration in Windows 3.1+ and Windows NT 3.5+. The hierarchy of Registry hives in Windows NT is quite similar to that of Windows 95.
[VB4_NEW]Regsvr32.exe, which is included with Visual Basic 4.0, is a command-line application that adds, updates, or deletes registry entries for 32-bit OLE servers, including 32-bit OLE Controls. The following is a list of the primary uses of
Regsvr32.exe:
To register or re-register a 32-bit OLE server, use the following syntax in the Open text box of Windows 95's Run dialog:
regsvr32.exe d:\path\oleserver.{exe|dll|ocx}
The preceding syntax example makes the assumption that Regsvr32.exe is located in the \Windows folder, the \Windows\System folder, or another folder on the current DOS path. Figure 14.5 shows the message box that appears when an OLE Control has been
successfully registeredin this case the Lenel System International's MediaDeveloper L_audi32.ocx for waveform audio applications. The normal location for Regsvr32.exe, OLE Controls, and both types of Automation servers you create with Visual Basic
4.0 is the \Windows\System folder. Remote Automation servers, however, are located on file servers once you've tested them locally. Thus, Regsvr32.exe plays an important role in dealing with Visual Basic 4.0's Remote Automation Objects. Use the 16-bit
version of Regsvr32.exeRegsvr.exeto register or re-register a 16-bit OLE server, including 16-bit OLE Controls.
Figure 14.5. Regsvr32.exe's message box indicating successful registration of an OLE control.
If you delete an OLE 2+ server from your local fixed disk drive or a remote application server, take advantage of Regsvr32.exe's ability to unregister the server. The server must be present for unregistration to work, so make sure not to delete or move
the server's file until you execute the following command line:
regsvr32.exe /u d:\path\oleserver.{exe|dll|ocx}
Figure 14.6 shows the message box you receive when unregistering a server. You can repeatedly register and/or unregister servers with no problems. Unregistering a server you move to a new location and then re-registering it ensures that all of the
server's registration data is updated.
Figure 14.6. The message box that appears after an OLE control has been successfully unregistered with Regsvr32.exe.
The process of embedding or linking OLE 2.x objects with the new built-in OLE container control doesn't differ dramatically from the methods you use with Visual Basic 3.0's MSOLE2.VBX. The major new feature of Visual Basic 4.0's OLE control is
data binding; you can bind the OLE control to OLE Object fields of tables in Jet databases. The native OLE container control of Visual Basic 4.0 is backward compatible with MSOLE2.VBX. Like Visual Basic 3.0, Visual Basic 4.0 is an OLE 2.x
container application only. Visual Basic does not have a native document format, such as a worksheet or a word processing document, so Visual Basic per se would not constitute a valid OLE 2.x full server application.
Following are some of the changes to OLE container control methods and properties between Visual Basic 3.0 and 4.0:
The following sections describe the properties and the one event of the OLE container control that are specific to OLE 2.1 operations, and then they show you how to create an OLE container control in design mode. Properties, methods, and events that
the OLE container control shares with the majority of other Visual Basic controls are not discussed in this chapter. The Drag, Move, Refresh, SetFocus, and ZOrder properties of the OLE container control are methods that are applicable to most other Visual
Basic controls. There many new methods of the OLE container control described in the following sections, but there are only two events, ObjectMove and Updated, that are unique to the OLE container object.
Table 14.1 lists each OLE-related property of the OLE control and describes the purpose of the property. The first six properties are the primary properties you need to set to create an OLE object. The properties are listed in the order in which the
properties typically would be assigned values when you add the control to a form or from code in a VBA procedure. (The DataSource and DataField properties are used only for bound OLE controls.) The remaining properties, beginning with AutoActivate, are
optional; they are listed in alphabetical order. Unless otherwise indicated, all properties listed in Table 14.1 are read-write in design and run modes. A few of the properties noted as "run mode only" are new to Visual Basic 4.0.
Property Name | Purpose |
Class | The value of ProgID that identifies the application that has created an existing object, or the application that will create a new, empty object. Setting the Class property value overrides file-extension associations established in the Registry. |
SourceDoc | The well-formed path and Filename.ext of the file that contains existing source data for a linked or embedded object. Leave the SourceDoc property empty to open a new empty object, such as a blank Excel worksheet. |
SourceItem | Determines the portion of the data within the source file to link. SourceItem is used only with linked objects. Leave SourceItem empty if you want to link the entire content of the file or if you embed the object. |
DataSource | Specifies the name of the Data control to which the OLE container control is bound. |
DataField | Specifies the name of the field, which must be of the OLE Object field data type, that contains the OLE data to display in the control. |
AppIsRunning | Returns True if the application that created the OLE object is running (run mode only). |
AutoActivate | Specifies if the source document is to be activated manually (by applying the DoVerb method with the vbOLEUIActivate constant), automatically (when the OLE control receives the focus), or by double-clicking the surface of the OLE container control. |
AutoVerbMenu | Set to True to specify that clicking the right mouse button with the mouse pointer on the surface of the object in the inactive state displays a pop-up menu with the list of verbs applicable to the object; set to False for no menu. The default value is True. |
Data | Returns a handle (Long for 32-bit applications) to the memory or GDI object for the object in the control (run mode only). |
DataChanged | Returns True if the data of a bound OLE control has been changed by editing or some other type of operation (run mode only). |
DataText | Returns or sets a text value from or to the object; the object must support a text format (run mode only). The object must support a text format (see the Format property.) |
DisplayType | Determines if the presentation of an OLE object is the object's data content (0, False) or an icon representing the application (1). The default value is False. |
Format | Returns or sets a String containing one of the Clipboard data formats (CF_. . .) supported by the object. Apply the ObjectAcceptFormats or ObjectGetFormats method to determine the Clipboard formats the object supports (run mode only). |
HostName | Returns or specifies the name of your Visual Basic application, which appears in the title bar of the window of an OLE server application (if the OLE server application supports this feature). |
lpOleObject | Returns a Long pointer to the address of the object for use with Windows API calls that require the address (run mode only). |
MiscFlags | Optional values that determine how the OLE object stores the source data and that enable you to disable the application. The default value is 0 (no flags). |
Object | Returns a pointer to the object in the container so you can apply methods and get/set the property values of the object through OLE Automation code (run mode only). |
ObjectAcceptFormats | Returns one of an array (zero-based) of strings containing one of the Clipboard formats that the object accepts (run mode only). |
ObjectAcceptFormatsCount | Returns the number of members of the ObjectAcceptFormats array (run mode only). |
ObjectGetFormats | Returns one of an array (zero-based) of strings containing one of the Clipboard formats the object can supply (run mode only). |
ObjectGetFormatsCount | Returns the number of members of the ObjectGetFormats array (run mode only). |
ObjectVerbFlags | Returns an Integer value indicating the attributes of the Verb menu choice of the specified ObjectVerbs menu (run mode only). |
ObjectVerbs | Returns one of an array (zero-based) of Integer values indicating the members of the object's menu choices (run mode only). |
ObjectVerbsCount | Returns the number of menu choices for the object (run mode only). |
OLEDropAllowed | Set to True to allow the user to drag a file from the desktop, My Computer, or Explorer, and drop it into the OLE control, thus replacing the current object (run mode only). |
OLETypeAllowed | Specifies whether you can link (0), embed (1), or either link or embed (2) an OLE source object with the control. The default value is 2. |
PasteOK | Returns True if the current contents of the Clipboard can be pasted to the object (run mode only). |
Picture | Returns the name of the file providing the graphic content of the control, if applicable (run mode only). |
SizeMode | Determines if the presentation of the object is to be clipped (0) or stretched (1), or if the OLE control is to be autosized to fit the image (2). The effect of applying these attributes is similar to their effect on Image controls. |
UpdateOptions | Determines if the OLE object is updated automatically whenever the value of the data changes (0), updated only when updated data is saved to a file (called frozen1), or manually (by applying the Update method2). Available in run mode only. |
If the computers on which you expect to install a Visual Basic application that includes OLE 2.x objects have adequate memory (16MB or more for Windows 95 and 20MB or more for Windows NT), try setting the value of the MiscFlags property to vbOLEMiscFlagMemStorage (1). Setting MiscFlags to 1 causes your application to manipulate file-based OLE data in memory rather than paging the data into or out of a file. You need a substantial amount of free RAM to manipulate large files (such as bitmaps) with more than one byte of color depth, or multimedia files.
Table 14.2 lists the new methods that apply to the OLE container control of Visual Basic 4.0. The majority of these methods replace the Action property of Visual Basic 3.0's MSOLE2.VBX control and the associated action constant. Methods may be applied
only in run mode from VBA code.
Method Name | Purpose |
Close | Breaks the connection to the contained object's server application and closes the object. |
Copy | Copies the content (data) of the contained object to the Clipboard. |
CreateEmbed | Creates an embedded object from a file specified by the strSourceDoc argument or an empty object specified by the ProgID value of the strClass argument with strSourceDoc specified as an empty string (""). |
CreateLink | Creates a linked object from a file specified by the strSourceDoc argument; the value of the optional strSourceItem argument specifies a range within the source document, such as a range of cells in an worksheet or a bookmark in a document. |
Delete | Deletes the object contained in the control. |
DoVerb | Executes the OLE verb specified by the Integer value of the vbOLEVerb constant supplied as an argument. The applicable constants are listed in Table 14.3. |
FetchVerbs | Refreshes the list of verbs provided by the object to update the ObjectVerbs property array. |
InsertObjDlg | Displays the Insert Object dialog to allow the user to insert his or her choice of objects into the OLE container. |
Paste | Pastes the contents of the Clipboard into the contained object (if the object supports the format in which the object was copied to the Clipboard). |
PasteSpecialDlg | Displays the Paste Special dialog to allow the user to choose between pasting the object or a static picture of the object. |
ReadFromFile | Replaces the content of the object with data from a file, specified by file number, that has previously saved in OLE storage format (.ole). You must open the file with the Open filename.ext For Binary As #n statement, using n as the argument of the ReadFromFile method. |
SaveToFile | Saves the content of the object as data in an OLE storage file, specified by file number (similar to ReadFromFile). |
SaveToOle1File | Saves the content of the object as data in an OLE 1.0 file, specified by file number (obsolete; for backward compatibility only). |
Update | Refreshes the presentation of the object. The Update method primarily is applicable to shared linked objects that may be updated by other users. |
Table 14.3 lists the names, values, and actions for the seven vbOLE. . . intrinsic constants you use as the argument of the DoVerb method.
Constant Name | Value | Action by the DoVerb method |
vbOLEPrimary | 0 | Performs the default action for the object, usually the equivalent of the Edit or Play menu choices. |
vbOLEShow | -1 | Activates the object for editing, either in-place or in the server's main window |
vbOLEOpen | -2 | Opens the object in the server's main window, regardless of whether the in-place activation is supported. |
vbOLEHide | -3 | Hides the server application for an embedded object. |
vbOLEUIActivate | -4 | Activates the object in-place, displays the application's toolbars, and grafts menus to the form's menu. Generates a trappable error if the object doesn't support in-place activation. |
vbOLEInPlaceActivate | -5 | Activates the object for editing when the object receives the focus. Generates a trappable error if the object doesn't support in-place activation with a single mouse click. |
vbOLEDiscardUndoState | -6 | Discards all changes to the objects content that can be reversed with the Edit | Undo command. |
The only OLE-specific event of the OLE container control is Updated. The Updated event is triggered whenever the data or the status of the source object of an OLE container control changes. The syntax of the event handler subprocedure for the Updated
event of OLE 2.x container controls is this:
Sub oleName_Updated (intTypeOfChange)
The required intTypeOfChange parameter (Visual Basic supplies the argument name Code) accepts one of the four values shown in Table 14.4 to indicate whether a change to the OLE data or to the status of the OLE object triggered the Updated event.
The OLE_. . . constants of Visual Basic 3.0 are replaced by Visual Basic 4.0's vbOLE. . . constants. Although you can continue to use the old constant names in Visual Basic 4.0 applications, there is no guarantee that future versions of Visual Basic will
support the obsolete names.
Constant Name | Value | Purpose |
vbOLEChanged | 0 | Indicates that a change to the OLE data triggered the event. |
vbOLESaved | 1 | Indicates that the OLE data was saved to a file by the application that created the object. |
vbOLEClosed | 2 | Indicates that the OLE server that created the application has closed. |
vbOLERenamed | 3 | Indicates that the name of the file containing linked OLE data has changed. |
When you add an OLE 2.1 container control to a form in design mode, the Insert Object dialog, shown in Figure 14.7, appears. OLE 2.x includes a set of standard dialogs, similar in concept to the common dialogs of Windows 3.1+ and Windows 95, for
inserting, converting, and emulating objects. The standard Insert Object dialog gives you the option of creating a new (empty) embedded object or an object linked to a file. You can choose any of the OLE 1.0 or OLE 2.0 server applications that are
registered in the Registry from the Object Type list box. The Object Type list box displays the MainUserTypeName values corresponding to the ProgID entries in the Registry.
Figure 14.7. The standard OLE 2.x Insert Object dialog.
If you choose to create a new embedded object, the default design-mode presentation of the object type you chose appears. When you click the right mouse button, a floating menu shows the choices available to you at this point in the creation of your
OLE control. Figure 14.8 shows an empty Excel 7.0 Sheet object embedded in the default OLE1 control with the pop-up menu activated by clicking the control with the right mouse button.
Figure 14.8. An inactive embedded Excel 7.0 worksheet in design mode with the pop-up menu activated.
The floating menu gives you the following choices that relate specifically to OLE operations:
When you choose Edit to activate the object for editing in design mode and then right-click the control, additional pop-up menu choices appear, as illustrated by Figure 14.9. The set of menu choices at the bottom of the pop-up menu varies with
the OLE server used to create the object.
The only design-mode method of embedding an object that contains a range of data in a document is to follow these steps:
Figure 14.10. The standard OLE 2.x Paste Special dialog.
Your embedded worksheet and the Properties window for the OLE1 object appear, as illustrated by Figure 14.11, for an Excel 7.0 worksheet that contains price and volume data for a large number of common stocks over a 21-day period. The Class property
displays the ProgID value of the server application's Registry entry. The SourceDoc and SourceItem property value text boxes, not shown in Figure 14.11, are empty because these values apply to linked objects only.
Figure 14.11. A selected range of an Excel 7.0 worksheet embedded in an OLE container control.
To activate the OLE object when your form opens, apply the DoVerb (vbOLEInPlaceActivate) method to the object in the Form_Activate event handler. Activating the control from the Form_Activate event (instead of the Form_Load event), displays the form and the presentation of the object while the server loads to entertain the user. Depending on the speed of the user's PC and free system resources available, opening the object's server can take an appreciable amount of time.
Linking objects follows the same procedure as embedding objects, except that you specify a link to the file, either in the Insert Object dialog (from file version) or in the Paste Special dialog. The advantages of a linked object are that the data is
not a permanent element of your form, making your application's .exe file smaller, and you obtain the current data within a shared linked object when you activate the object. Because of the size of multimedia files, such as large bitmaps and video clips,
multimedia objects are almost always linked to OLE container controls. It is unfortunate that OLE 2.1 doesn't provide the capability for activating linked objects in place. Future versions of OLE, as implemented in the next major versions of Windows 95 and
Windows NT, are likely to accommodate in-place activation of linked OLE objects.
In design mode, an embedded OLE 2.x object can graft all or part of its menu structure to the form, as shown in Figure 14.9. Embedded objects don't display the server's File menu choice, so the traditional File menu is missing in
Figure 14.9. Menus grafted from OLE servers don't appear in run mode unless you add a menubar to your form and set the NegotiateMenus property of the form to True (the default). Figure 14.12 shows the result of adding a menubar with a single
File choice when you activate an embedded Excel object in run mode. The entire menubar, except the File choice, is grafted from Excel's menubar.
Figure 14.12. The grafted menubar of an embedded Excel Worksheet object activated in run mode.
Visual Basic 4.0 forms are OLE containers and are therefore capable of participation in the creation of compound documents. If you enjoy experimentation, you can prove the truth of the preceding statement by embedding an OLE object as an insertable
object directly in a form, rather than into an OLE container control. Visual Basic 4.0's sole online help reference to insertable objects defines an insertable object as "[a]n object of an application, such as a Microsoft Excel Worksheet, that is
a type of custom control." Visual Basic 4.0 forms are simple OLE containers that support operations such as grafted menus (menu negotiation) and in-place activation.
Buttons representing insertable objects appear in Visual Basic 4.0's toolbox when you add references to the objects from the Custom Controls dialog. Marking only the Insertable Objects check box produces a list of objects identical to those of the
Object Type list of the Insert Object dialog. Figure 14.13 shows a subset of the insertable objects available on the computer used to write this edition. Like OLE controls, the objects you check appear in the toolbox when you click the OK button of the
Custom Controls dialog. Figure 14.14 shows the toolbar with Excel and Microsoft Graph tools added to the toolbox and a Microsoft Graph 5.0 (MSGraph5) inserted object activated in design mode with the datasheet made visible. The default names of insertable
objects are derived from the object type: an Excel worksheet object is Sheet1, an Excel chart or MSGraph5 object is Chart1, and a Media Player object is named mplayer1.
Figure 14.13. Part of the list of Insertable Objects that you can add to Visual Basic 4.0's toolbox.
Insertable objects that support in-place activation, such as Excel Worksheet and Microsoft Graph 5.0 objects, graft their menus to Visual Basic 4.0 menubars on activation. Figure 14.15 shows an insertable MSGraph5 object added to a form; the Chart
object is activated for editing. The background color of the chart is changed to match that of the form, and a title is added in run mode. Insertable objects have a generic property set and a few events that are common to all control objects. Insertable
objects do not directly support methods, except SetFocus and Move. Insertable objects created by OLE Automation servers have an Object property that you can use to program the insertable object. The primary use for today's insertable objects appears to be
a visual presentation for programmable objects. The advantage of an insertable object is that you can take advantage of early binding of the object without incurring the application overhead associated with the OLE container control. Programming objects
exposed by OLE Automation servers is the subject of the next chapter.
Microsoft's description of an Excel worksheet as a "type of custom control" might be a glimpse into the design of future of Microsoft Office applications. Breaking Excel and other Office applications into a collection of in-process OLE servers that implement a specific feature set closely fits Bill Gates's vision of modular desktop and networked productivity application components, discussed at the beginning of this chapter.
Although OLE 2.x is now in its third iteration (OLE 2.0, 2.01, and 2.1), in-place activation still has a long road to travel before all of its kinks are finally ironed out. Locating and sizing OLE controls to neatly accommodate frame adornments,
such as Excel's scrollbars and sheet selection tabs, and making sure all eight sizing handles appear when you activate an object in place presently is a black art that's best left to trial-and-error experimentation. Until Microsoft synchronizes future
versions of its OLE 2.x servers with the containers provided by programming tools, such as Visual Basic and Visual C++, you can expect unexpected behavior when activating objects in place. The following two sections describe workarounds for several
known problems with Visual Basic 4.0's OLE control and issues relating to Excel objects, which presently are some of the most common objects embedded in Visual Basic OLE container controls.
Microsoft's official OLE 2+ state diagram for embedded objects, included in OLE 2.x documentation of the Win32 SDK, specifies that a single click outside the surface of the activated object deactivates the object. Clicking the surface of the
form (outside the OLE container control) doesn't deactivate the object in run mode, despite the fact that the same action does deactivate the object in design mode. In run mode, the user must press Esc to deactivate the object. If your form contains at
least one control in addition to the OLE container control, you can use the Form_Click event handler to apply the SetFocus method to another control. If you don't want another control to appear on your form, add a small PictureBox control (with no border)
to the form, and set its ForeColor value to match the ForeColor property value of your form. Apply the SetFocus method to the PictureBox control, then back to the OLE container control, as in the following example:
Private Sub Form_Click() picBogus.SetFocus oleWhatever.SetFocus End Sub
The OLE container control exhibits several "strangenesses" with embedded Excel 95 worksheets. For example, Word's toolbars appear as floating toolbars upon activating an embedded Word 95 document object, but Excel 95's toolbars do not appear
on activation. Although the Formula Bar choice appears when opening Excel's View menu, the formula bar does not appear on activation, except for a instant. Activating embedded Excel 95 worksheets created from .xls files often results
in peculiar appearance in the OLE container, and it is guaranteed to be bizarre if Excel's AutoFit method has been applied to worksheet columns. Figure 14.16 is an example of the appearance of such a worksheet activated in run mode. You usually can solve
this problem by copying to the Clipboard the content you want to embed and then pasting the content to a newly opened worksheet. (Don't apply any automatic formatting methods to the new worksheet.) Copy the content of the new worksheet to the Clipboard and
use Paste Special to paste the unformatted version of the worksheet or range to your OLE container control.
Figure 14.16. The bizarre appearance of an autoformatted Excel 5.0 worksheet activated in run mode.
Another of the problems with activating Excel 7.0 worksheets (based on files) in Visual Basic 4.0 OLE containers is described in the Microsoft Knowledge Base document Q129793, "BUG: Excel Displays Only First Column in Embedded Worksheet."
Visual Basic 4.0's OLE container control is data-enabled, which lets you display OLE objects linked to or embedded in OLE Object fields of Jet tables. Visual Basic 3.0's MSOLE2.VBX custom control was not data-enabled; displaying objects contained in
OLE Object fields required you to write an extraordinary amount of code to deal with Jet's "OLE wrapper." When you bind the OLE container control to an OLE Object field, the control behaves almost identically to Access's bound object frame
control. It's likely that displaying OLE Objects in tables of .mdb files will be the primary application for the new OLE container control for most Visual Basic 4.0 developers.
Binding a Visual Basic 4.0 OLE container control to a field of Jet's OLE Object type requires that you add a Data control to a form and set the value of the DatabaseName property to point to a Jet .mdb file that contains a table with an OLE Object
field. (Biblio.mdb does not contain a table with an OLE Object field.) You specify the table with the OLE Object field as the RecordSource of the Data control. Add an OLE container control to the form and then click Cancel when the Insert Object dialog
appears to create an empty OLE control. Set the value of the DataSource property of the OLE container control to the name of the Data control and specify the OLE Object field as the value of the DataField property.
Figure 14.17 shows Data Form Designer's dialog for creating a simple form that displays the contents of the LastName, FirstName, Title, Notes, and Photo fields of the Employees table of Access 95's Northwind.mdb. Data Form Designer automatically adds a
bound OLE container control for OLE Object fields you specify in the Included Columns list. Figure 14.18 illustrates the resulting Employees form after adjustments have been made to the default size of the Notes and Photo controls. Double-clicking the OLE
container opens an instance of Windows Paint to let you edit the image; when bound to an OLE Object field, the OLE container control does not support in-place activation. The OLE container control appropriately treats bound objects as linked objects,
despite the fact that the OLETypeAllowed property value of the oleField4 control is specified as 1 (Embedded).
Figure 14.18. A bitmapped image contained in an Jet OLE Object field displayed in a bound OLE container control.
One of the primary purposes of OLE 2.x is to supplant Windows dynamic data exchange operations. DDE, which appeared when Microsoft released Windows 2.0 in 1987, was the primary means of interprocess communication (IPC) for Windows applications
until the advent of OLE 1.0. DDE uses a special set of Windows messages (WM_DDE. . .) to transfer data between Windows applications using the Clipboard as the intermediary. The DDE management library (DDEML.DLL) that was added to Windows 3.1 improved the
performance of DDE while retaining backward compatibility with DDE applications written for Windows 3.0.
Windows for Workgroups (WFW) 3.1 added NetDDE, a process that enables you to transfer applications between computers using the Windows network by enabling workgroup members to share data stored in the Clipboard. Windows 95 supports NetDDE only with a
16-bit Netdde.dll that requires thunking when called from 32-bit applications. The absence of a 32-bit NetDDE API in Windows 95 indicates that Microsoft considers NetDDE to be obsolete in the 32-bit environment. If you need to use IPC between commercial
Windows applications over a network, your choices of protocols are NetDDE or Microsoft Mail (MAPI, the messaging API). NetDDE is discussed briefly in Chapter 18, "Running Visual Basic Database Front-Ends on Networks," and using MAPI is one of the
subjects covered by Chapter 21, "Interacting with Microsoft Mail, Exchange, and Schedule+."
It's possible to use a Remote Automation Object (RAO) that employs OLE Automation to communicate with an instance of an OLE full server, such as Excel, that's located on the same server as the RAO. However, the overhead involved in passing data over the network and then through two out-of-process servers is likely to degrade performance dramatically.
The sections that follow provide a brief overview of DDE and the use of DDE in Visual Basic database applications. The following sections are intended to provide an overview of the use of DDE in Visual Basic database applications. The future of IPC
operations lies in OLE 2.1+ and NetworkOLE, not DDE and NetDDE.
If your Visual Basic database application needs to communicate with a Windows application that doesn't expose objects for OLE Automation operations, you don't need to make a choice; your only option is DDE. If you need cross-network communication,
NetDDE currently is the most likely (albeit cumbersome) choice.
Some commercial applications make extensive use of DDE in interacting with Access applications. For example, TEAMWorks Technologies' PaperBridge for Access uses DDE to link images of documents to Access databases. PaperBridge for Access uses an OLE
Object field of an Access table to store "wrapped" links to images stored in compressed (CCITT Type 3) TIFF files. The TIFF files can reside on the local PC, a network file server, or on a WORM (write-once, read-many optical disk) volume.
Multiple WORM drives or WORM drive carousels can store terabytes (TBone terabyte equals one trillion bytes) of document images.
Interprocess communication between two Windows applications using DDE is called a DDE conversation. The conversation is initiated by the DDE client application by requesting that a DDE server application open a DDE channel over which to hold the
conversation. DDE clients and servers are occasionally referred to as DDE source and destination applications, respectively, paralleling OLE terminology. A channel is identified by a positive integer, similar to the Windows handle that is used to identify
a connection to a client/server database with the ODBC API.
The relationship between DDE clients and servers is similar to that between client workstations and database servers. The primary difference is that both the DDE client and server applications must be running on the same computer, because the transfer
of data between applications takes place through the Windows Clipboard. The single-computer restriction does not apply if you use the Network DDE features of Windows 95.
In addition to transferring data from and to DDE server applications, you can execute instructions, usually in the form of menu commands, in DDE servers that support the DDE execute statement. This capability extends to OLE server applications that
also support DDE. (Some OLE servers do not have execute capability.) Therefore, you can retrieve data from an Excel worksheet linked to or embedded in a bound OLE object frame. The sections that follow describe DDE operations with Visual Basic 4.0 as the
client application.
The DDE server that participates in the conversation is identified by its Service name; in versions of Windows prior to 3.1, Service name was called Application name. Service name is usually, but not always, the name of the application's
executable file, without the .EXE extension. Service name is the name by which the Windows Task Manager recognizes the application. If the client request cannot obtain a DDE channel within a fixed time period, called the DDE timeout interval, you receive
an error message.
If the server application is not running, you need to launch the application with Visual Basic's Shell() function before you attempt to initiate a DDE conversation. Setting the value of the LinkMode property to a positive integer (1, 2, or 3) does not cause Windows to automatically launch the application.
As is the case with client/server databases, the client application requests data that is available in or through the server application. In the majority of cases, the data of interest is contained in a document (file) that you specify as the DDE Topic
name with the value of the LinkTopic property. You set the value of Visual Basic's LinkTopic property to the combination of the DDE Service name and the DDE Topic name, separated by a pipe (|, vertical bar) character. If the document is a file, you need to
specify a well-formed path to the file and the file name as the Topic name. The following two statements open a DDE channel from a control object (ctrDDELink) to an Excel worksheet, Sheet.xls, in the C:\Excel\Worksheets folder:
ctrDDELink.LinkTopic = "Excel|c:\excel\worksheets\sheet.xls" ctrDDELink.LinkMode = 2 'Manual
All DDE server applications are required to have a Topic name System that returns information about the server, including the names of valid topics. Testing the values returned by the System topic enables you to determine if the file that constitutes
the topic is presently open in the server application.
If setting the value of the LinkMode property successfully opens a DDE channel, Visual Basic assigns the channel number to the control object. If the link fails, you receive an error message. The preceding code fragment returns the entire content of
the worksheet to ctrDDELink.
The Item name is the method by which the server application specifies a particular piece or set of datathe data item. When the server responds to a DDE request, it copies the requested data item to the Clipboard. If the server is capable of
handling several formats, it copies the requested data item in each of the formats it supports to the Clipboard.
If you are using Microsoft Excel as the DDE server, you specify the value of the LinkItem property of the control that is to receive the data by row and column coordinates ("R1C1" or "R1C1:RyCx") or by using a named range, such as
"Database." Here's a statement that specifies that you want the values from a group of nine cells from the first three rows and three columns of an Excel worksheet:
ctrDDELink.LinkItem = "R1C1:R3C3"
The string returned to the ctrDDELink control consists of three rows separated by newline pairs (Chr$(13) & Chr$(10)), or the new intrinsic constant vbCrLf. Within each row, columns are separated by tab characters
(Chr$(9)). Therefore, you need to parse the content of ctrDDELink with Visual Basic code to separate and identify the individual data elements.
You use a bookmark name to specify a data item in Microsoft Word documents. Bookmarks denote the beginning and end of a range of text in the Word document. If the bookmark specifies a Word for Windows table, the data in the table is returned in
tab-separated columns and newline-separated rows. The syntax to return data from a table identified by the bookmark SalesTable in a Word document is this:
ctrDDELink.LinkItem = "SalesTable"
If the Topic element of the value of LinkTopic is System, you can obtain information on the capabilities of the DDE server by specifying one of the data items listed in Table 14.5 as the value of the LinkItem property. Most, but not all, applications
return each of the data items shown in Table 14.5. You need to request a list of SysItems from the application to determine which of the data items a specific server returns.
Data Item | Returns |
SysItems | A tab-separated list of items supported by the topic System, including SysItems. |
Format | A tab-separated list of the formats that the server application can copy to the Clipboard. |
Status | Either Busy or Ready. |
Topics | A tab-separated list of all open document files, plus System. |
As an example, Excel returns the values listed in Table 14.5 when you initiate a conversation on the System Topic and use the values returned by SysItems to obtain Excel's DDE server capabilities and status. In addition to the common
System Items listed in Table 14.5, Excel returns the filename and currently selected cell or range of cells, OLE protocols, and editable environmental items. Selection returns the name of the currently loaded worksheet and the location of the selection
(its cursor position) or the range of selected cells, separated by the bang symbol (!).
Once you've established a channel over which to transfer data between the DDE client and server and you've specified the data item you want, you request data with the LinkRequest method. The LinkRequest method is needed only if you specified a manual
DDE link (LinkMode = 2, "cold") or notify DDE link (LinkMode = 3, "warm"). If you specify an automatic DDE link (LinkMode = 1, "hot"), the linked control is updated any time the data item(s) in the specified Topic change. You
terminate a DDE conversation and free the DDE channel that is in use by setting LinkMode = 0.
You can use the Visual Basic LinkPoke method to send unsolicited data that is contained in the linked control object to the DDE server. The term unsolicited is used to distinguish data sent to a server application by the client from data that is
sent from the server to the client.
You can execute commands in client applications that support the DDE execute commands by applying the Visual Basic LinkExecute method to the linked control object. DDE execute commands often are menu choices or keywords in the application's macro
language. The syntax of the Visual Basic LinkExecute method is this:
ctrDDELink.LinkExecute strExecuteCmd
In the case of Excel, you can execute Excel functions, such as Select() and New(). Most DDE servers that recognize execute commands require that you enclose the commands within square brackets. The following statement creates a new Excel chart from
data contained in columns 1 through 12 of row 2 of the Excel worksheet specified as the Topic element of the value of the LinkTopic property:
ctrDDELink.LinkExecute "[Select(" & Chr$(34) & _ "R1C1:R2C12" & Chr$(34) & ")][New(2,2)]"
The explicit quotations (Chr$(34)) that enclose the selection coordinates in the preceding example are necessary; Excel requires that selection coordinates or range names be enclosed within single quotation marks.
You can execute any macro command of Excel or Word with the LinkExecute method. Multiple commands are contained within a single strExecuteCmd value; each command is separated from the next by the enclosing square brackets. Commands are executed by the
server application in the sequence in which they appear in the strExecuteCmd argument.
If you're an Access developer or use the DDE statements and functions of Word Basic or of Excel VBA, it's clear that Visual Basic takes a different approach to DDE conversations you establish with code. Access Basic and Access VBA, Word Basic, Project VBA, and Excel VBA and conventional macro functions employ the DDEInitiate() function to return a DDE channel number for the conversation. You use this channel number as an argument in all of the subsequent DDE instructions in your code until you terminate the conversation with a DDETerminate or DDETerminateAll statement. Visual Basic, on the other hand, requires that all DDE conversations take place between a linked control object, usually a text box, and the server application. The DDE channel number is associated with the linked control and is not directly accessible to your Visual Basic code. The absence of the DDE. . . commands in the Visual Basic 4.0 flavor of VBA indicates the disfavor into which DDE has fallen at Microsoft.
Like OLE 1.0 with SendKeys, using DDE often is a chancy process. The DDE management features of Ddeml.dll have improved the speed and reliability of DDE communications, but DDE operations (and especially NetDDE) remain the province of experienced
programmers. (The Windows 95 version of Ddeml.dll is the same as that of Windows 3.1+.) The following list describes some of the problems that you are likely to encounter when you use DDE in your Visual Basic applications:
If you and your clients have upgraded to OLE 2.x client and server applications, use OLE Automation rather than DDE for interprocess communication in the new Visual Basic applications you create. DDE belongs to Windows past, and OLE Automation
belongs to Windows future. According to Microsoft representatives, the next major versions of Windows 95 and Windows NT (Cairo) will be founded on today's 32-bit OLE 2.1, but will add many new features, including network transport of compound documents,
the individual objects that make up compound documents, and the modular server components that support the objects.
This is an exceptionally long chapter because interprocess communication in Windows is a complex subject. The chapter discussed OLE concepts, differences between OLE 1.0 and 2.x, and the use of data-bound OLE container controls. A general
description of Visual Basic 4.0's implementation of the client side of DDE was included.
Windows IPC methods currently are a moving targetOLE 2.x and OLE Automation have usurped DDE's status as the primary means of transferring data between Windows applications. The new Automation Objects, remote and local, you create with
Visual Basic 4.0 have no DDE counterparts. The next chapter describes how you can use Visual Basic 4.0 to orchestrate the interoperation of OLE 2.x database applications with OLE Automation.