In this chapter you will be exposed to some of the advanced features of COM and DCOM OLE programming. First, you should know just what those two words mean.
Until now, you have been learning how to use OLE features within programs, and to use controls written by other people. For example, you used the marquee control, but you did not create the marquee control. Programs such as of Visual
Basic (the next version) and Visual C++ enable you to create class objects (objects that are derived from classes) and OCX controls that others can use in their own applications.
A survey of the technologies that go into creating an OLE control would fill a much larger volume than this one. However, for those of you who will go on to creating these controls, this chapter reviews some of the features of control creation and how
they apply to ActiveX. You will learn
The system registry is the location for all the system settings on an NT or Win95 machine. Actually, any system that supports OLE will need to have some sort of equivalent to the system registry. When Microsoft introduced it in Windows 3.0, it allowed
third-party programmers to write applications for Windows, which allowed Microsoft to sell more Windows, and so on.
Windows 3.0 has two sections of the Win.INI to enable OLE-like features[Embedding] and [Extensions]. These sections tell the OLE system what features are enabled and what file extensions are associated with those features, respectively.
The format for the [Extensions] section follows a standard keyname = value format. An example section would look like this:
[Extensions] crd=cardfile.exe ^.crd doc=C:\MSOFFICE\WINWORD\WINWORD.EXE ^.doc MDB=C:\MSOFFICE\ACCESS\MSACCESS.EXE ^.MDB mpp=C:\MSOFFICE\WINPROJ\winproj.exe ^.mpp msg=C:\PROGRA~1\MICROS~1\exchng32.exe /f ^.msg ppt=C:\MSOFFICE\POWERPNT\POWERPNT.EXE ^.ppt qry=C:\WINDOWS\MSAPPS\MSQUERY\msquery.exe ^.qry vbp=C:\VB\vb.exe ^.vbp wri=write.exe ^.wri
The Win.INI [Extensions] Section
Extension = Application FilePath ^.Extension
The [Extensions] section of the Win.INI file defines the application that is automatically associated with a given file extension. The INI file itself takes precedence over any similar settings in the system registry.
Example:
foo = C:\FooDir\FooApp.exe ^.foo
In this example, an entry is made that will cause the computer to use the FooApp.exe program to handle FOO files.
The format in the [Embedding] section of the Win.INI tells the system the name of the control, the name of the object, the path to the control, and the type of object. An example [Embedding] section would look like this:
[embedding] Mplayer = Media Clip, Media Clip, mplayer.exe, picture ComicChat.Room.1 = Comic Chat Room, Comic Chat Room, C:\MSN\CCHAT\CHAT.EXE, picture
The Win.INI [Embedding] Section
[ServerObject] = [Description 1], [Description 2] [OLE Server] [Format]
The [Embedding] section of the Win.INI file defines the OLE servers that can manipulate a given object. This file is only used for backwards-compatibility with older Windows 3.0-style programs.
Example:
My Object = My Object, My Object, C:\MyAppDir\MyApp.exe, picture
In this example, an entry is made that tells the operating system about a new type of server object called, My Object [ServerObject].
Next it gives the creatable object two descriptions. The first is a general name for the object; the second is a more generally readable description for it that will appear in menus and dialogs that refer to the object.
It also tells the system where there is an OLE server that is capable of creating one of these server objects [OLE Server].
Finally, it says what kind of file the data file will be. This is almost always picture.
Windows 3.1 added speed and OLE features to the access of the system registry components. Instead of keeping the information in diverse sections of multiple files, it keeps the most important parts of the registry in few fast-access binary files. Also,
in response to the glut of programs being written for the Windows brand of OLE, Microsoft pre-added entries for several third-party OLE applications to the distribution copies of Windows 3.1. This made the installation of OLE-capable programs go more
easily.
In Windows 95, access to the registry files is sped up considerably. This is to allow for the network feature of having dynamic keys. These keys make it possible for counters and various other real-time and metered data to be kept close to the
processing environment.
The system registry is made up of information from three files. These files contain user-specific, computer-specific, and system-specific information. It would be difficult to show just what these files look like. They are not very human-readable, but
they still contain the binary representation of a whole data structure. You have to use a tool like the RegEdit utility to read and manipulate the registry database.
The System.DAT file contains the system-specific information for the system, such as what type of monitor is installed, and how many keys are on your keyboard.
The Reg.DAT file is the computer-specific registration database of information for the system. It is through this database that changes to the registry are made. It is where support for OLE happens in Windows 95. Drag and Drop, OLE, and Compound
Documents all refer to this database to perform their operations.
The User.DAT file contains the user-specific information about the user profile. This magic little feature of Windows 95 enables each user of a machine to have a Desktop customized to his/her own taste.
The information for each user's particular setup is contained in the policy settings portion of this file. User profiles make it possible for Mom to access her newsgroups that are pointed to her favorites, and Dad's are still pointed to his when he
logs on to the system. They can also manage the ratings for Junior. One computer, multiple configurations.
The last registries file to be loaded during boot-up is the Policy.POL (System Policies) file. It can be edited with the System Policy Editor (distributed with the Windows 95 Resource Kit). The settings in the system policy override all other policies.
It is usually loaded from the network so that all the systems can be managed in one way.
There are several good utilities that come with the Windows 3.1, 95, and NT systems that can assist you in editing the registry settings.
Windows 3.1 and 95 come with RegEdit.exe (see Figure 21.1, usually in the \Windows\ directory. In Windows 3.1 you had the command line option of /v to toggle between normal and advanced mode. In Windows 95 there is just one mode: Power User.
Warning For you diagnosticians out there, when you trace a problem with a client machine to a "mysterious" registry problem, try to find out if they did not go running around lose in the RegEdit program. It's a good place for someone who does not know what they are doing to really hurt themselves.
Figure 21.1. The Windows 95 Registration Editor.
The RegEdit utility is handy for editing the way OLE is carried out on a system. The functions that can be customized through RegEdit include Open, Close, Delete, Print, Edit, and other functions you might find on the File menu of an application.
When you have an OLE application on your system, you will want to make sure that it's registered in the registration database. Ideally, the software author included processes to automatically register and unregister their OLE server.
If the author did not include this process, or if the program somehow becomes unregistered on your system, there should be a REG file somewhere. These files are associated with the RegEdit utility to register the software component. This can also be
done from the RegEdit Merge-Registration Info menu.
Here is a sample REG file for the Windows Media Player (also see Figure 21.2:
REGEDIT HKEY_CLASSES_ROOT\mplayer = Media Clip HKEY_CLASSES_ROOT\mplayer\protocol\StdExecute\server = mplayer.exe HKEY_CLASSES_ROOT\mplayer\protocol\StdFileEditing\Handler = mciole.dll HKEY_CLASSES_ROOT\mplayer\protocol\StdFileEditing\server = mplayer.exe HKEY_CLASSES_ROOT\mplayer\protocol\StdFileEditing\PackageObjects = HKEY_CLASSES_ROOT\mplayer\protocol\StdFileEditing\verb\1 = &Edit HKEY_CLASSES_ROOT\mplayer\protocol\StdFileEditing\verb\0 = &Play HKEY_CLASSES_ROOT\mplayer\shell\open\command = mplayer.exe /play /close %1 ;OLE2 Compatibility entries. HKEY_CLASSES_ROOT\MPlayer\CLSID = {0003000E-0000-0000-C000-000000000046} HKEY_CLASSES_ROOT\CLSID\{0003000E-0000-0000-C000-000000000046} = Media Clip HKEY_CLASSES_ROOT\CLSID\{0003000E-0000-0000-C000-000000000046} \InprocHandler = mciole.dll HKEY_CLASSES_ROOT\CLSID\{0003000E-0000-0000-C000-000000000046}\ProgID = MPlayer HKEY_CLASSES_ROOT\CLSID\{0003000E-0000-0000-C000-000000000046} \Ole1Class = MPlayer HKEY_CLASSES_ROOT\.avi = mplayer HKEY_CLASSES_ROOT\.mmm = mplayer HKEY_CLASSES_ROOT\.mid = mplayer HKEY_CLASSES_ROOT\.rmi = mplayer
Figure 21.2. The registry entries for MPLAYER from the MPlayer registry file .
For the truly advanced or daring administrator, the RegEdit utility includes a menu option, Add | File Type, which enables you to manually add the OLE registration information that should have been in the REG fileor to modify it to your own
preferences. It is very similar to Windows 95's Menu, View | Options | File Types.
You may have seen the RegSvr32.exe utility being distributed in the setup disks for different programs. This is the command line utility to register the OLE server features of an OCX or DLL file.
By typing RegSvr32 and the filename of an OLE Server, you can register that item in the system registry. This registration process will make its features available to all the other OLE-capable programs on your system.
The RegSvr32 Utility
RegSvr32.exe [/u] [/s] [/c] [OLE Server]
The 32-bit server registration utility is used to register and unregister OLE servers (such as OCX and DLL files) in the system registry.
Example:
RegSvr32.exe /c MyServer.DLL
This will register the OLE server MyServer.DLL and output the results to the console (monitor).
RegSvr32.exe /u /s MyServer.OCX
This will unregister the OLE server MyServer.OCX and will do it in silent mode (no output to the console).
The RegClean utility (See figure 21.3) is available from Microsoft's Software Library (ftp://ftp.microsoft.com/SoftLib/MSLFiles). It includes a Registry Cleanup utility that, among other things,
will remove entries in your system registry for components or OCX files that are no longer available to your system.
Figure 21.3. Microsoft's Registry Cleaning Wizard.
There are many OLE controls out there that work just fine as they are, ActiveX environment or not. To attain the title ActiveX Control, your OCX or DLL file must support certain featureswhich the following sections introduce.
Note
This following sections introduce you to the APIs and SDKs involved in creating an ActiveX control . There are a variety of these tools that you may wish to use (such as security and versioning). Each can be quite complex and are included here for the truly daring programmer.
Microsoft makes their Internet APIs and SDKs publicly available on its Web site. Also, most of the documentation files on these tools were installed on your computer by the ActiveX SDK in the \IntDev\ directory.
An ActiveX Control's API must support the standard calls for registering and unregistering a control.
The DLL Register Server Standard API feature (STDAPI DLLRegisterServer()) loads all the .CLASS information (from the DLL or OCX file) into the system registry.
The DLL UnRegister Server Standard API feature (STDAPI DLLUnRegister Server()) removes all the previously loaded .CLASS information from the System Registry.
Ver.DLL contains the Windows versioning features. It supports three important functions:
RPCs provide the programmer with a series of functions to access the Win32 registry. At this level, network functions such as SNMP procedures can be used. The client machine would need to have the Microsoft RPC service installed (from the
\Admin\NetTools\ directory of the Windows 95 CD-ROM). Use of this feature is not required for ActiveX Controls, but it sure is powerful.
Programmers add utility for users whose machines are running the RPC service. If the user with whom you wish to interact is running the Windows RPC service (included with the Windows 95 CD-ROM in \Admin\NetTools) this allows programmatic access to the
OLE procedure calls within Windows API. This is how features such as SNMP can be accessed.
Another feature which programmers can make use of is the Base Security Layer of Windows. You were introduced to various parts of this feature in earlier chapters. What should be made clear here is that much of the information that is read from, and
written to, ActiveX objects, is stored in the system registry. This goes for all ActiveX security features such as code signing, ratings, trust verification, and user locator services.
In order for a control to be truly ActiveX/OLE-enabled, it must support the central features of OLEaggregation, marshaling, and reference countingand support IUnknown interfaces. Briefly, these can be defined as follows:
Note
The Java Virtual Machine (VM) uses a Garbage Collector rather than reference counting to determine if it is being used and how many times.
Microsoft's implementation of the Java Virtual Machine combines OLE Reference Counting with the Java Garbage Collector. This relieves the programmer of the burden of coding when a reference to a control should be added or deleted, and of when a control needs to be loaded or unloaded. Also Java allows for exception handling, whereas COM does not. These are perfect examples of how Java makes OLE programming a lot easier!
To actually compile your control for use, you need to use an OLE-aware programming environment such as Visual C++, Visual Basic, or Visual Java++.
Visual J++ (which Microsoft codenamed "Jakarta") is the first full-blown IDE to make Internet programming fully available to OLE developers. (Refer to Figure 21.4 for a view of the Jakarta IDE.) This programming language is based on the Java
language developed by Sun Microsystems and integrates the features of OLE.
In this marriage, COM objects are exposed to Java as Java objects, and a public Java class is exposed to OLE as COM objects. Although you can program COM objects in a variety of languages, you still must use a Java compiler to create Java objects.
This, however, may not be true for other Java compilers besides Jakarta, since this one is based on the Microsoft Java VM.
One security feature for running Java applets in ActiveX browsers is that they are hobbled. Hobbling restricts the control from calling code or classes that cannot be verified by the Java byte code verifier. Also, any interface that cannot be
defined in a type library (TLB file) will be hobbled.
You can find more information about Visual J++ at Microsoft's Web site, http://www.microsoft.com/visualj.
Figure 21.4. Microsoft's Visual JAVA++ IDE.
Visual Basic (Figure 21.5) supports various levels of OLE connectivity with COM objects, depending on the version of VB you are using. Even Visual Basic 4 enables you to program against a previously registered object.
A powerful feature of Visual Basic is its capability to make API calls to OLE servers. This feature enables 16-bit VB applications to make calls to 32-bit OLE out-of-process servers, and 32-bit VB applications to make calls to 16-bit OLE out-of-process
servers. When using in-process servers, you still must consider bitness.
Figure 21.5. Microsoft's Visual Basic IDE.
You can find out more about Visual Basic at Microsoft's Web site, http://www.microsoft.com/vbasic.
Warning When making API calls over a distributed network (such as with the Microsoft RPC Service API), performance is slowed considerably as remote connections are established and disconnected.
VB is wonderful for using OLE servers. On the enclosed CD-ROM, you should find a sample VB application, MyServer, for creating an OLE server in VB4. It does not do anything, but if you view the source code with Notepad, you will see that each
contains nothing but comments about what should be done in a particular part.
Visual C++ has always (until now, anyway) been the language of choice for OLE programmers. Versions 4 and later enable you to program with foundation classes (predefined OLE classes) or templates (programming language-specific code snippets). Each has
its own features for accessing COM.
C programmers do most of their OLE programming with the classes supported in Microsoft's Foundation Classes Library. You must be sure to include the dependent files with your distribution disks. These include
The ATL is distributed by Microsoft to enable programmers to use API calls instead of relying on foundation classes. The most current version can be found at http://www.microsoft.com/visualc/v42/atl/default.htm.
This thing is a set of Visual C++ templates that enable quick and easy programmatic access to the ActiveX OLE features. This library is not at all a comprehensive library of functions, but it will enable you to create redistributable functioning COM
Class objects.
Dual Interfaces
The ATL enables you to add support for dual interfaces to your C++ program. This makes possible access to features by way of both the IDispatch interface and vtable entries. This enables interaction through third-party features such as scripting.
This library also allows for support of Tear-Off Interfaces. This means that an object can be enumerated (defined) within the system with an IEnum... interface BUT you do not have to worry about the resource demand on your OLE connection. The OLE
connection is not actually instantiated (loaded) until it is used. It can be used many times after that, and will stay loaded. When all the objects that were using it report that they are no longer using it (that is, the reference count hits 0), it is
unloaded (uninstantiated).
When you create an OLE interface for an object, there is one standard, IUnknown , with which most of your calls will work. (For a graphical representation of how IUnknown is used as an interface, refer to figure 21.6.) Determining the number of
references (current implementations of this interface) and querying the interface (asking about a specific implementation) is determined by the processes that occur through this interface.
The basic model of the IUnknown interface would support the QueryInterface, AddRef, and Release methods:
Interface IUnknown { Virtual HResult QueryInterface(REFID, VOID FAR *) = 0; Virtual ULong AddRef()=0; Virtual ULong Release()=0; };
An example of C++ code that would implement a DragDrop function by way of the IUnknown interface would look like this:
Interface IDropTarget:IUnknown { Virtual HResult DragDrop()=0; Virtual HResult DragEnter()=0; Virtual HResult DragLeave()=0; Virtual HResult DragOver()=0; };
Note
Make sure your program makes AddRef and Release calls as necessary. This will inform the system when it is using an object and when it's not. Then the system can load and unload it as necessary. If you keep opening interfaces and not closing them, you could easily run out of memory and hang your system.
Every interface, IUnknown or not, implements three methods:
Figure 21.6. Graphical representation of how programmers and their programs interact with COM.
OLE Definitions
OLE is a component technology (a theory).
COM is a convention for referring to computer objects.
A class is the definition of how one object behaves. The object it defines does not exist until it is instantiated. Each has a 128-bit Uniform Unique Identifier property (UUID).
An interface is any class based on the IUnknown class. This class will be the contract under which any objects created with it will operate.
The IUnknown class provides the details of a user-defined object, but it can not be loaded itself. It only provides the definitions by which other objects are loaded.
An ActiveX IDE (Integrated Design Environment) is a program that enables interaction with COM objects.
A language is the syntax and vocabulary used in an IDE to reference objects and procedures.
An object is the instantiation of an interface. It is usually contained in an EXE or a DLL file, but can be on a remote machine altogether (using RPC) .
Taken as a whole, these features are a bit much to swallow in one gulp. However, whether you are a control programmer who uses controls or a control programmer who creates them, it is important to have an exposure to the design considerations in
ActiveX Controls.
Your ActiveX Controls will be working closely with your system registry, and you may have to use a utility such as RegEdit or RegClean to fix something. Also, if other programmers' controls are running rampant in your registry, you may find it
necessary to remove or edit them manually.
If you do design ActiveX Controls, you have a wide choice of programming languages with which to work. Microsoft makes Visual Basic, Visual C++, and Visual J++ with control creation features.
Also, you will need to include certain interfaces, based on the IUnknown interface. They will need to be self-registering, using the API calls for DLLRegisterServer and DLLUnRegisterServer. The controls will also need to support versioning through API
calls to Ver.DLL. Several additional, optional interfaces can be added to the control to enable enhanced features such as RPCs (Remote Procedure Calls) and code signing.
Create an OLE server that supports self-registering and versioning using any or all the following IDEs:
Note
Refer to the Appendix, "Answers to Quiz Questions," for the answers to these question.