Automation is a COM protocol that defines how one application accesses an object that resides within another application or DLL. An Automation controller is a client application that controls an Automation server through one or more server-provided objects which implement the IDispatch interface.
Automation controllers can be written in any language for which an implementation of COM and Automation is provided. Most automation controllers are currently written in C++, Object Pascal (Delphi), or Visual Basic.
Examples of Automation servers include Microsoft Word, Microsoft Excel, and Internet Explorer. These applications can be controlled by Delphi applications or by other Automation controllers.
Delphi gives you the flexibility to integrate applications and DLLs with a variety of applications as either Automation servers or as controllers.
This chapter describes how to create an Automation controller in the Delphi environment. It is not intended to provide complete details of controller application development for every type of server. For specific information on a server application, you should consult that application's documentation.
For information about creating an Automation server, see Chapter 47, "Creating an Automation server."
In Delphi, you create an Automation controller by importing an Automation server's type library and installing it on the Component palette.
You can create an Automation controller by importing an Automation server's type library and using the automatically generated classes to control the Automation server. With the Import Type Library dialog, you install the server that the type library describes to the Component palette, which allows you to connect to the server and hook up its events using the Object Inspector. You can then manipulate the server properties programmatically.
To import an Automation controller's type library,
The dialog lists all the libraries registered on this system. If the type library is not in the list, choose the Add button, find and select the type library file, choose OK, and repeat step 2. Note that the type library could be a standalone type library file (.TLB, .OLB), or a server that provides a type library (.DLL, .OCX, .EXE).
Specify where you want the type library to reside, either in an existing package or new package. This button is grayed out if no component can be created for that type library.
A server that the type library described now resides on the Component palette. You can use the Object Inspector to write an event handler for the server.
To control the Automation server through this controller, you add code to the implementation unit to provide support for early (VTable) binding and late (dispatch) binding. The unit that you just created includes interface wrappers for both VTable binding for all exposed interfaces, and dispatch binding for dual and dispatch interfaces.
Once you have installed a server on the Component palette, you can use the Object Inspector to write an event handler.
After implementing your event handler, you can connect to a server.
Typically, you connect to a server through its main interface. For example, you would connect to Microsoft Word through the WordApplication component. Once you've connected to the main interface, you can connect to any of the application's components (such as a WordDocument or WordParagraphFormat) by using the ConnectTo method.
Here is the event handler for the ExcelApplication event, OnNewWorkBook. In it, we are assigning the workbook to the ExcelWorkbook component.
procedure TForm1.XLappNewWorkbook(Sender: TObject; var Wb:OleVariant); begin ExcelWorkbook1.ConnectTo((iUnknown(wb) as ExcelWorkBook)); end;
After importing the type library, add code to the implementation unit to control the server with either a dual interface (most typical) or a dispatch interface.
Note: The import files created when a type library is imported (libname_TLB.CPP and libname_TLB.H) should be considered to be read-only, and are not intended for modification of any kind. These files are regenerated each time the type library is refreshed, so any changes are overwritten.
For servers that expose a Quit method (such as WordApplication and ExcelApplication), code is generated to call this method in the Disconnect method. Quit typically exposes functionality that is equivalent to clicking on File to quit the application. If AutoConnect is set to True, the application server will Quit when the client exits. Therefore, hitting F1 when AutoQuit is highlighted in the Object Inspector does nothing.
When you create an Automation controller by selecting an object from the Component Palette, it automatically provides a dual interface because Delphi can determine the VTable layout from information in the type library. Calling a method on the class automatically connects to an instance of Word.
For example, for a Word server, you call on a method of class TWordApplication as follows:
foo := TWordapplication foo.DoSomething;
Of course, the former way of controlling an Automation server with a dual interface still works, but it is more cumbersome. You must first, declare an interface and initialize it with the Create method of a CoClass client proxy class. Then you call methods of the smart interface object. For example,
foo : _Application foo := CoWordApplication.Create foo.DoSomething;
The interface and CoClass client proxy class are defined in the unit that is generated automatically when you import a type library. The names of smart interfaces start with "I". For example, the main smart interface for Microsoft Word is "IWordBasic". The names of the CoClass client proxy classes start with "Co". For example, the main CoClass client proxy class for Microsoft Word is CoApplication.
For information about dual interfaces, see "Automation interfaces".
Typically, you will use the dual interface to control the Automation server, as described above. However, you may find a need to control an Automation server with a smart dispatch interface object. To do so,
For information on dispatch interfaces, see "Automation interfaces".
The following steps show how to create an Automation controller that prints a document using Microsoft Word 8 from Office 97.
Before you begin, create a new project that consists of a form, a button, and an open dialog box (TOpenDialog). These controls constitute the Automation controller.
For your convenience, Delphi has provided many common servers, such as Word, Excel, and Powerpoint, on the Component Palette. To demonstrate how to import a server, we use Word. Since it already exists on the Component Palette, this first step asks you to remove the package containing Word so that you can install it on the palette. Step 4 describes how to return the Component Palette to its normal state.
To remove Word from the Component palette,
The Servers page of the Component Palette no longer contains any of the servers supplied with Delphi. (If no other servers have been imported, the Servers page also disappears.)
To import the Word type library,
If Word (Version 8) is not in the list, choose the Add button, go to Program Files\Microsoft Office\Office, select the Word type library file, MSWord8.olb choose Add, and then select Word (Version 8) from the list.
The Install dialog appears. Select the Into New Packages tab and type WordExample to create a new package containing this type library.
You can use either a VTable or a dispatch object to control Microsoft Word.
To use a VTable interface object to control Microsoft Word, you add code to the OnClick event handler of the Automation controller's button. To do so, you simply call on methods of the class you just created. For Word, this is the TWordApplication class.
Note: : You must include the Word type library, Word_TLB, in the Uses clause of the Automation controller's implementation file.
var
FileName: OleVariant;
begin
MyWord: _Application;
WordApplication1.Create;
if OpenDialog1.Execute then
begin
FileName := OpenDialog1.Filename;
WordApplication1.Documents.Open(FileName,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam);
WordApplication1.ActiveDocument.PrintOut(EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam);
WordApplication1.Quit(EmptyParam,EmptyParam,EmptyParam);
end;
To use a dispatch interface object to control Microsoft Word, perform the following tasks, adding code to the OnClick event handler of the Automation controller's button:
var MyWord: _ApplicationDisp; FileName: OleVariant; begin MyWord:= CoApplication_.Create;Note: Go to the Uses clause of the automation controller's implementation file and add Word_TLB to include the Word type library.
if OpenDialog.Execute then
begin
FileName := OpenDialog1.Filename;
MyWord.Documents.Open(FileName,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam);
MyWord.ActiveDocument.PrintOut(EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam);
MyWord.Quit(EmptyParam,EmptyParam,EmptyParam);
end;
After completing this example, you will want to restore Delphi to its original form.
For the most up-to-date information about the dispatch interface, dual interface, and CoClass client proxy classes, refer to the comments in the automatically-generated source file.
pubsweb@inprise.com
Copyright © 1999, Inprise Corporation. All rights reserved.