This chapter covers the theory and concepts of ActiveX, which until recently was called OLE. Most new programmers have found OLE intimidating, and the new name is unlikely to lessen that. However, if you think of ActiveX technology as a way to use code already written and tested by someone else, and to save yourself the trouble of re-inventing the wheel, you'll see why it's worth learning. And Developer Studio and MFC make ActiveX much easier to understand and implement by doing much of the ground work for you. There are five chapters in Part IV, ActiveX Applications and ActiveX Controls, and together they demonstrate what ActiveX has become.
Windows has always been a way to have several applications running at once, and right from the beginning programmers wanted to have a way for those applications to exchange information while running. The Clipboard was a marvelous innovation, though, of course, the user had to do a lot of the work. DDE, Dynamic Data Exchange, allowed applications to "talk" to each other but had some major limitations. Then came OLE 1, Object Linking and Embedding. Later there was OLE 2, and then Microsoft just called it OLE, until it moved so far beyond its original roots that it was renamed ActiveX.
ActiveX lets users and applications be document-centered, and this is probably the most important thing about it. If a user wants to create an annual report by choosing ActiveX-enabled applications, the user stays focused on that annual report. Perhaps parts of it are being done with Word and parts with Excel, but, to the user, these applications are not really the point. This shift in focus is happening on many fronts, and corresponds to a more object-oriented way of thinking among many programmers. It seems more natural now to share work among several different applications and arrange for them to communicate than to write one huge application that can do everything.
Here's a simple test to see whether you are document-centered or application-centered: How is your hard drive organized?
The directory structure in Figure 22.1 is application-centered: the directories are named for the applications that were used to create the documents they hold. All Word documents are together, even though they may be for very different clients or projects.
Figure 22.1 : An application-centered directory structure arranges documents by type.
The directory structure in Figure 22.2 is document-centered: the directories are named for the client or project involved. All the sales files are together, even though they can be accessed with a variety of different applications.
Figure 22.2 : An document-centered directory structure arranges documents by meaning or content.
If you've been using desktop computers long enough, you remember when using a program involved a program disk and a data disk. Perhaps you remember installing software that demanded to know the data directory where you would keep all the files created with that product. That was application-centered thinking, and it's fast being supplanted by document-centered thinking.
Why? What's wrong with application-centered thinking? Well, where do you put the documents that are used with two applications equally often? There was a time when each product could read its own file formats and no others. But these days, the lines between applications are blurring; a document created in one word processor can easily be read into another, a spreadsheet file can be used as a database, and so on. If a client sends you a WordPerfect document, and you don't have WordPerfect, do you make a \WORDPERFECT\DOCS directory to put it in, or add it to your \MSOFFICE\WORD\DOCS directory, or what? If you have your hard drive arranged in a more document-centered manner, you can just put it in the directory for that client.
The Windows 95 interface, now incorporated into Windows NT as well, encourages document-centered thinking by having users double-click documents to automatically launch the applications that created them. This isn't new; File Manager has had that capability for years, but it feels very different to double-click an icon that's just sitting on the desktop than it does to start an application and then double-click an entry in a list box. More and more it doesn't matter just what application or applications were involved in creating this document; you just want to see and change your data, and you want to do that quickly and simply.
After you start being document-centered, you start to see the appeal of compound documents, files created with more than one application. If your report needs an illustration, you create it in some graphic program and then stick it in with your text when it's done. If your annual report needs a table, and you already have the numbers in a spreadsheet, you don't retype them into the table feature of your word processor, or even import them, you incorporate them as a spreadsheet excerpt, right in the middle of your text. This isn't earth-shatteringly new, of course. Early desktop publishing programs, like Ventura, pulled together text and graphics from a variety of sources into one complex compound document. What's new is being able to do it simply, intuitively, and with so many different applications.
Figure 22.3 shows a Word document with an Excel spreadsheet linked into it.
Figure 22.3 : A Microsoft Word document can contain a link to an Excel file.
Follow these steps to create a similar document yourself:
The entire file appears in your document. If you make a change in the file on disk, the change is reflected in your document. You can edit the file in its own application by double-clicking it within Word. The other application is launched to edit it, as shown in Figure 22.4. If you delete the file from disk, your Word document still displays what the file last looked like, but you are not able to edit it.
Figure 22.4 : Double-clicking a linked object launches the application that created it.
You link files into your documents if you plan to use the same file in many documents and contexts, because your changes are automatically reflected everywhere that you have linked the file. Linking doesn't increase the size of your document files dramatically, since only the location of the file and a little bit of presentation information needs to be kept in your document.
Embedding is similar to linking, but a copy of the object is made and placed into your document. If you change the original, the changes are not reflected in your document. You can't tell by looking whether the Excel chart you see in your Word document is linked or embedded. Figure 22.5 shows a spreadsheet embedded within a Word document.
Figure 22.5 : A file embedded within another file looks just like a linked file.
Follow these steps to create a similar document yourself:
What's the difference? You'll see when you double-click the object to edit it. The menus and toolbars of Word disappear and are replaced with their Excel equivalents, as shown in Figure 22.6. Changes you make here are not made in the file you originally embedded. They are made in the copy of that file that has become part of your Word document.
Figure 22.6 : Editing in place is the magic of OLE embedding.
You embed files into your documents if you plan to build a compound document and then use it as a self-contained whole, without using the individual parts again. Any changes you make do not affect any other files on your disk, not even the one you copied from in the first place. Embedding makes your document much larger than it was, but you can delete the original if space is a problem.
To embed or link one object into another, you need a container and a server. The container is the application into which the object is linked or embedded-Word in these examples. The server is the application that made them, and that can be launched (perhaps in place) when the object is double-clicked-Excel in these examples.
Why would you develop a container application? To save yourself work. Imagine you have a product already developed and in the hands of your users. It does a specific task like gets a sales team organized, or schedules games in a league sport, or calculates life insurance rates. Then your users tell you that they wish it had a spreadsheet capability, so they could do small calculations on-the-fly. How long will it take you to add that functionality? Do you really have time to learn how spreadsheet programs parse the functions that users type?
If your application is a container app, it doesn't take any time at all. Tell them to link or embed in an Excel sheet, and let Excel do the work. If they don't own a copy of Excel, they need some spreadsheet application that can be an ActiveX server. You get to piggyback on the effort of other developers.
It's not just spreadsheets, either. What if users want a scratch pad, a place to scribble a few notes? Let them embed a Word document. And for bitmaps and other illustrations? Microsoft Paint, or a more powerful graphics package if they have one and it can act as an ActiveX server. You don't have to concern yourself with adding functionality like this to your programs because you can just make your application a container and your users can embed whatever they want without any more work on your part.
Why would you develop a server application, then? Look back over the reasons for writing a container application. A lot of users are going to contact developers asking for a feature to be added, and be told they can have that feature immediately-they just need an application that does spreadsheets, text, pictures, or whatever, and can act as an ActiveX server. If your application is an ActiveX server, people will buy it so that they can add its functionality to their container apps.
Together, container and server apps allow users to build the documents they want. They represent a move toward building block software and a document-centered approach to work. And if you want your application to carry the Windows 95 logo, it must be a server, a container, or both. But there is much more to ActiveX than just linking and embedding. Read on!
What if the object you want to embed is not in a file, but is part of a document you have open at the moment? You may have already discovered that you can use the Clipboard to transfer ActiveX objects. For example, to embed part of a Word document into an Excel spreadsheet, you can follow these steps:
Figure 22.7 : The Paste Special dialog box is used to link or embed selected portions of a document.
A copy of the block is now embedded into the spreadsheet. If you choose Paste Link, changes in the spreadsheet are reflected immediately in the Word document, not just when you save them. (You may have to click the selection in Word to get it updated.) This is true even if the spreadsheet document has no name and has never been saved. Try it yourself! This is certainly better than saving dummy files just to embed them into compound documents, then deleting them, isn't it?
Another way to embed part of a document into another is drag and drop. This is a user-interface paradigm that works in a variety of contexts. You click on something (an icon, a highlighted block of text, a selection in a list box) and hold the mouse button down while moving it. The thing you clicked moves with the mouse, and when you let go of the mouse button, it is dropped to the new location. That's very intuitive for things like moving or resizing windows, but now you can use it to do much, much more. For example, here's how that Excel-in-Word example would be done with drag and drop:
The selected block is embedded into the Word document. If you double-click it, you are editing in place with Excel. Dragging and dropping also works within a document to move or copy a selection.
TIP |
The block is moved by default, which means it is deleted from the Excel sheet. If you want a copy, hold down the Ctrl key while dragging, and release the mouse button before the Ctrl key. |
You can also use drag and drop with icons. On your desktop, if you drag a file to a folder, it is moved there. (Hold down Ctrl while dragging to copy it.) If you drag it to a program icon, it is opened with that program. This is very useful when you have a document you use with two applications. For example, pages on the World Wide Web are HTML documents, often created with an HTML editor, but viewed with a World Wide Web browser like Netscape Navigator. If you double-click an HTML document icon, your browser is launched to view it. If you drag that icon onto the icon for your HTML editor, the editor is launched and opens the file you dragged. After you realize you can do this, you will find your work speeds up dramatically.
All of this is ActiveX, and all of this requires a little bit of work from programmers to make it happen. So what's going on?
The heart of modern ActiveX is the Component Object Model. This is an incredibly complex topic that deserves a book of its own. Luckily, the Microsoft Foundation Classes and the Visual C++ AppWizard do much of the behind-the-scenes work for you, and so the discussion in these chapters is just what you need to know to use OLE as a developer.
The Component Object Model (COM) is a binary standard for Windows objects. That means that the executable code (in a .DLL or .EXE) that describes an object can be executed by other objects. Even if two objects were written in different languages, they are able to interact using the COM standard.
How do they interact? Through an interface. An ActiveX interface is a collection of functions, or really just function names. It's a C++ class with no data, only pure virtual functions. Your objects inherit from this class and provide code for the functions. Other programs get to your code by calling these functions. All ActiveX objects must have an interface called IUnknown (and usually have many more, all with names that start with I, the prefix for interfaces).
NOTE |
If you look at the MFC source code, you see that interfaces are actually declared like this: interface Iunknown Snoop around a little further and you find this line: #define interface struct So, in fact, an interface isn't exactly a class, it's a struct. There's very little difference. Members are private by default in a class and public by default in a struct. That's it, in C++. You can even have functions in a C++ struct, though you can't in C. And yes, a class can inherit from a struct. Microsoft made an interface a struct, because much of The ActiveX frameworkcode is written to work in both C and C++, with #ifdef __cplusplus tests scattered throughout the code. By making it a struct in both C and C++, The Microsoft developers get away with a few less #ifdefs. In C, by the way, they use pointers to functions, and implement the virtual function stuff in a way you probably don't want to learn about. |
The IUnknown interface has only one purpose: finding other interfaces. It has a function called QueryInterface() that takes an interface ID and returns a pointer to that interface for this object. All the other interfaces have a QueryInterface(), too, since they inherit from IUnknown, and you have to write them, or you would if there was no MFC. MFC implements a number of macros that simplify the job of writing OLE interfaces and their functions, as you will shortly see.
An ActiveX Automation application lets other applications tell it what to do. It exposes functions and data, called methods and properties. For example, Microsoft Excel is an ActiveX Automation object, and programs written in Visual C++ or Visual Basic can call Excel functions and set properties like column widths. That means you don't need to write a scripting language for your application any more. If you expose all the functions and properties of your application, any programming language that can use an ActiveX Automation application can be a scripting language for your application. Your users, your customers, may already know your scripting language. They essentially will have no learning curve for writing macros to automate your application (though they will need to learn the names of the methods and properties you expose).
The important thing to know about interacting with ActiveX Automation is that one program is always in control, calling the methods or changing the properties of the other running application. The application that is in control is called an ActiveX Automation controller. The application that exposes methods and functions is called an ActiveX Automation server. Excel, Word, and other members of the Microsoft Office suite are ActiveX Automation servers, and your programs can use the functions of these applications to really save you coding time.
For example, imagine being able to use the function called by the Word menu item Format, Change Case to convert the blocks of text your application uses to all uppercase, all lowercase, sentence case (the first letter of the first word in each sentence is uppercase, the rest are not), or title case (the first letter of every word is uppercase, the rest are not).
The description of how ActiveX Automation really works is far longer and more complex than the interface summary of the previous section. It involves a special interface called IDispatch, a simplified interface that works from a number of different languages.
ActiveX controls are tiny little ActiveX Automation servers that load in place. That means they are remarkably fast. They were originally called OLE Custom Controls and were designed to replace VBX controls, 16-bit controls written for use in Visual Basic and Visual C++. (There are a number of good technical reasons why the VBX technology could not be extended to the 32-bit world.) Since OLE Custom Controls were traditionally kept in files with the extension .OCX, many people referred to an OLE Custom Control as an OCX or an OCX control. Although the technology has been renamed, ActiveX controls produced by Visual C++ 4.2 are still kept in files with the .OCX extension.
The original purpose of VBX controls was to allow programmers to provide unusual interface controls to their users. Controls that looked like gas gauges or volume knobs became easy to develop. But almost immediately, VBX programmers moved beyond simple controls to modules that involved significant amounts of calculation and processing. In the same way, many ActiveX controls are far more than just controls; they are components that can be used to build powerful applications quickly and easily.
NOTE |
If you have built an OCX in earlier versions of Visual C++, you might think it is a difficult thing to do. The Control Developer Kit, integrated into Visual C++ as of version 4.0, takes care of the ActiveX (OLE) aspects of the job and allows you to concentrate on the calculations, display, or whatever else it is that makes your control worth using. The OLE Control Wizard makes getting started with an empty ActiveX control simple. (The wizard will presumably be renamed soon.) |
Because controls are actually little ActiveX Automation servers, they need to be used by an ActiveX Automation controller, but the terminology is too confusing if there are controls and controllers, so we say that ActiveX controls are used by container applications. Visual C++ and Visual Basic are both container applications, as are many members of the Office suite as well as non-Microsoft products.
In addition to properties and methods, OLE Controls have events. To be specific, a control is said to fire an event, and it does so when there is something that the container needs to be aware of. For example, when the user clicks a portion of the control, the control deals with it, perhaps changing its appearance or making a calculation, but it may also need to pass on word of that click to the container application so that a file can be opened or some other container action can be performed.
This chapter has given you a brief tour through the concepts and terminology used in ActiveX technology, and a glimpse of the power you can add to your applications by incorporating ActiveX into them. The remainder of the chapters in this part work you through the creation of ActiveX applications using MFC and the wizards in Visual C++. Check out the following: