You are on page 1of 8

7/9/13

Using OLE Automation in Visual FoxPro

Using OLE Automation in Visual FoxPro


Paul Bienick July 13, 1995 Since the introduction of the Microsoft FoxPro database management system for Windows, developers have been able to use OLE technology to embed or link documents from other applications directly into FoxPro tables. Now Visual FoxPro 3.0 goes much further, allowing you to use OLE Automation to add the functionality in Microsoft Office productssuch as Microsoft Word and Microsoft Excelto applications created with FoxPro. An OLE Automation server application allows other, external applications to control it by exposing certain parts of its internal structure in the form of objects. These objects have properties and methods. Properties allow you to set or retrieve values that might represent the state of the object. Methods allow you to perform an action on a specific object, such as opening a new document, printing a file, or recalculating a range of cells.

Quick review
You need to consider only two FoxPro functions to retrieve another application's objects: CreateObject and GetObject. Once you have obtained the object, you can immediately begin to access its properties and methods. CreateObject creates an object from a class definition or an OLE object. It is also used to create objects of built-in FoxPro or user-defined classes: < m e m v a r >=C R E A T E O B J E C T ( c C l a s s N a m e ) cClassName specifies the OLE object from which the new object is created. FoxPro will search for the class name you specify in the following order: 1. Visual FoxPro base classes. 2. User-defined class definitions in memory in the order they were loaded. 3. Classes in the current program. 4. Classes in .VCX class libraries opened with SET CLASSLIB. 5. Classes in procedure files opened with SET PROCEDURE. 6. Classes in the Visual FoxPro program execution chain. 7. The Windows registry (for OLE objects). OLE objects are created using the following syntax for cClassName: A p p l i c a t i o n N a m e . C l a s s For example, to create a Microsoft Excel object using OLE Automation, use the following: x l=C R E A T E O B J E C T ( " E x c e l . A p p l i c a t i o n " ) When this code is run, Microsoft Excel is started but is not visible. If Microsoft Excel is already running, another separate instance is created when you execute this command. GetObject activates an OLE Automation object and creates a reference to the object. For example:
www.dfpug.de/loseblattsammlung%5Cmigration%5Cwhitepapers/foxole.htm 1/8

7/9/13

Using OLE Automation in Visual FoxPro

G E T O B J E C T ( [ c F i l e N a m e[ ,c C l a s s N a m e ] ] ) cFileName specifies the full path and filename to activate. The application does not need to be specified, because the OLE dynamic-link libraries (DLLs) determine which application to start based on the filename provided. For example, the following code launches Microsoft Excel, opens a file named BUDGET.XLS, and creates a reference through an object memory variable named xlBudget : x l B u d g e t=G E T O B J E C T ( " C : \ E X C E L \ W O R K \ B U D G E T . X L S " ) cClassName specifies the class name of the object to retrieve. Some applications can store more than one object type in the same file, allowing you to use the class name to specify the object to activate. For example, if a word-processing application stores its documents, macro definitions, and toolbar objects in the same file, you can create a reference to the document file with the following command: m D o c F i l e=G E T O B J E C T ( " C : \ W R D P R O C \ M Y D O C . D O C " ," W r d P r o c . D o c u m e n t " ) With some server applications, each time a GetObject function is called an additional instance of the application is started, which uses additional memory. For example, if Microsoft Excel is already running, you can prevent additional instances from starting by omitting cFileName and including cClassName, as in this example: x l=G E T O B J E C T ( ," E x c e l . A p p l i c a t i o n " ) If Microsoft Excel is not running, a trappable error will be generated. Trapping the error and resorting to the CreateObject function is a common technique to test if an application is already running. An alternative technique is to use dynamic data exchange (DDE) to establish a link with the server application on the System topic, which all DDE applications support. If the link is successfully established, the application is running.

The registration database


The registration database is where FoxPro looks for the class name you specify with the CreateObject and GetObject functions. Under the Windows 3.11 and Windows for Workgroups 3.11 operating systems, entries into the registration database are stored as keys, with a corresponding value for each key in a tree-like structure. You can view the registration database with a program called REGEDIT.EXE, which is located in the directory where you installed Windows. Run REGEDIT with the /V option to see more detail. Under the Windows NT and Windows 95 operating systems, look under the HKEY_CLASSES_ROOT category or window to find entries for OLE Automation objects. The Windows NT 3.5 registration database editor was invoked by running the REGEDT32.EXE program with no options, as illustrated in the following figure.

www.dfpug.de/loseblattsammlung%5Cmigration%5Cwhitepapers/foxole.htm

2/8

7/9/13

Using OLE Automation in Visual FoxPro

Windows NT registration database

Object-oriented extensions in Visual FoxPro 3.0


One of the greatest advantages of using OLE Automation from within Visual FoxPro is the new object-oriented extensions. Because you now can create custom classes, and because classes serve to encapsulate both data and behavior, you can build classes that shield you from the peculiarities of a specific type of OLE server application. To illustrate this, let's look at the differences between controlling Word and Microsoft Excel. Begin by developing an abstract class that defines how to control all OLE applications. A subclass of this class can then be created for each specific OLE application that you want to control. # I N C L U D E" F O X P R O . H "

D E F I N EC L A S SO L E A p p l i c a t i o nA SC u s t o m P R O T E C T E Do O L E A p p ,; c O L E R e g N a m e ,; l C l o s e A p p W h e n D o n e

o O L E A p p=" "
www.dfpug.de/loseblattsammlung%5Cmigration%5Cwhitepapers/foxole.htm 3/8

7/9/13

Using OLE Automation in Visual FoxPro

c O L E R e g N a m e=" " l C l o s e A p p W h e n D o n e=. T .

* M e t h o d s F U N C T I O NI n i t ( ) I FE M P T Y ( t h i s . c O L E R e g N a m e ) = M E S S A G E B O X ( " C a n n o tc r e a t eo b j e c t d i r e c t l yf r o mc l a s s O L E A p p l i c a t i o n " ,; M B _ I C O N S T O P ,; " " ) R E T U R N. F . E N D I F

I Ft h i s . A p p R u n n i n g ( ) t h i s . o O L E A p p=t h i s . G e t C u r r e n t I n s t a n c e ( ) E L S E t h i s . o O L E A p p=t h i s . C r e a t e N e w I n s t a n c e ( ) E N D I F E N D F U N C

* A d d i t i o n a lm e t h o d sg e ti n s e r t e dh e r e E N D D E F I N E This defines the core functionality of your abstract OLEApplication class. First check to ensure that a user of the class is not trying to instantiate it directly. If so, just cancel the INIT method, which prevents the object from being created. Then check to see if the application is running. If it is, create a reference to it. If not, create a new instance. You need to determine if the application you're trying to control is currently running because certain applications, such as Microsoft Excel, let you create multiple instances, while others, such as Word, don't. Here are two suggestions to determine if an application is already running. The first involves using the GetObject function to attempt to retrieve a reference to an OLE Automation server. At the time of this writing, this option works fine with Microsoft Excel, but not with Word. Override this function when you define a Word for Windows class, but for now, define this option as a protected function within your OLEApplication class. (You define the function as protected because you will only be calling this function from within the OLEApplication class or any class that you derive from it. There is no need to expose it to the "outside world.")
www.dfpug.de/loseblattsammlung%5Cmigration%5Cwhitepapers/foxole.htm 4/8

7/9/13

Using OLE Automation in Visual FoxPro

P R O T E C T E DF U N C T I O NA p p R u n n i n g ( ) * R e t u r n s. T .i fa p pi sa l r e a d yr u n n i n g L O C A Ll c O l d E r r o r ,; l l R u n n i n g l l R u n n i n g=. T . l c O l d E r r o r=O N ( " E R R O R " ) O NE R R O Rl l R u n n i n g=. F . * A t t e m p tt og e tar e f e r e n c et oar u n n i n ga p p l i c a t i o n = G E T O B J E C T ( ,t h i s . c O L E R e g N a m e ) O NE R R O R& l c O l d E r r o r

t h i s . l C l o s e A p p W h e n D o n e=! l l R u n n i n g R E T U R Nl l R u n n i n g E N D F U N C To complete the definition of the OLEApplication class, create two methods, also defined as protected functions, that you will use to create references to new instances or retrieve references to current instances. Notice that each method contains only one statement. You could eliminate the overhead of the function call and place the CreateObject and GetObject calls directly in the INIT method, but then you wouldn't be able to customize the behavior of these methods in your subclasses. P R O T E C T E DF U N C T I O NC r e a t e N e w I n s t a n c e ( ) R E T U R NC R E A T E O B J E C T ( t h i s . c O L E R e g N a m e ) E N D F U N C

P R O T E C T E DF U N C T I O NG e t C u r r e n t I n s t a n c e ( ) R E T U R NG E T O B J E C T ( ,t h i s . c O L E R e g N a m e ) E N D F U N C

The Microsoft Excel class


Define your first subclass to handle OLE Automation with Microsoft Excel. Most of the inherited functionality from the OLEApplication class works just fine with Microsoft Excel. The first thing you need to do is initialize the cOLERegName property with the appropriate name of the Microsoft Excel application object as it appears in the registration database. Then set up a Destroy event method that sends the Quit command to Microsoft Excel whenever the object is being destroyed. The Destroy event method will fire whenever you explicitly release a Microsoft Excel object, or whenever the Microsoft Excel object goes out of scope. D E F I N EC L A S SE x c e lA SO L E A p p l i c a t i o n * I n h e r i t e dp r o p e r t i e s

www.dfpug.de/loseblattsammlung%5Cmigration%5Cwhitepapers/foxole.htm

5/8

7/9/13

Using OLE Automation in Visual FoxPro

c O L E R e g N a m e=" E x c e l . A p p l i c a t i o n "

* M e t h o d s F U N C T I O ND e s t r o y ( ) I FT Y P E ( " t h i s . o O L E A p p " )= =" O "A N D; t h i s . l C l o s e A p p W h e n D o n e t h i s . o O L E A p p . Q u i t ( ) E N D I F E N D F U N C E N D D E F I N E

The Word for Windows class


The second way to determine if an application is already running involves the use of DDE. This is useful in Word because the GetObject function doesn't work properly with Word. To check if an instance is running, it's necessary to use DDE to attempt to establish a link with Word. If you are successful, you know that Word is running, so you immediately terminate the link. In doing so, you also define a new implementation for the GetCurrentInstance method. This is because of Word's inability to respond to the GetObject function. To get the current instance of Word, you can safely use the GetObject function, passing an empty string as the first parameter. D E F I N EC L A S SW i n W o r dA SO L E A p p l i c a t i o n * I n h e r i t e dp r o p e r t i e s c O L E R e g N a m e=" W o r d . B a s i c "

P R O T E C T E DF U N C T I O NA p p R u n n i n g ( ) L O C A Ll n C h a n n e l ,; l l R u n n i n g ,; l l D D E O l d S a f e t y

l l D D E O l d S a f e t y=D D E S E T O P T I O N ( " S a f e t y " ) = D D E S E T O P T I O N ( " S a f e t y " ,. F . ) l n C h a n n e l=D D E I N I T I A T E ( " W i n W o r d " ," S y s t e m " ) I Fl n C h a n n e l< >1 * I t ' sr u n n i n g t h i s . l C l o s e A p p W h e n D o n e=. F . = D D E T E R M I N A T E ( l n C h a n n e l )
www.dfpug.de/loseblattsammlung%5Cmigration%5Cwhitepapers/foxole.htm 6/8

7/9/13

Using OLE Automation in Visual FoxPro

l l R u n n i n g=. T . E N D I F

= D D E S E T O P T I O N ( " S a f e t y " ,l l D D E O l d S a f e t y )

R E T U R Nl l R u n n i n g

P R O T E C T E DF U N C T I O NG e t C u r r e n t I n s t a n c e ( ) R E T U R NG E T O B J E C T ( " " ,t h i s . c O L E R e g N a m e ) E N D F U N C

E N D D E F I N E It is interesting to note that Word does not support creating multiple instances of itself through OLE Automation, while Microsoft Excel does. Using the classes presented here will prevent you from having to worry about inadvertently creating another instance of Microsoft Excel. Another interesting difference between these two applications is that when releasing a reference to Word that was started through OLE Automation, the Word instance is automatically terminated. However, a reference to Microsoft Excel will not terminate in this fashion. Instead, we must send the Quit method to the Microsoft Excel object, explicitly instructing it to terminate. Furthermore, Microsoft Excel will terminate even if the reference to it was created from a previously running instance.

Providing access to the reference


Note that the reference to the OLE Automation server is a protected member of the OLEApplication class. This means that you can only access this reference through methods of the class or one of its subclasses. There are three approaches you can take to provide access to the reference: Unprotect the oOLEApp property. This will provide direct access to the reference from outside the class's methods. This is the most dangerous option, as you then lose control of the reference. Create a method that simply returns the reference. This is somewhat less dangerous than the first option, but care must be taken since you now have two references to the same object. Create custom methods to manipulate the protected reference. This option is preferred, as you maintain almost complete control over the reference, even though more work must be done initially.

For more details


This article is based on a presentation made by the author at TechEd 95. For a more detailed discussion of this material, please see "Using OLE in Microsoft Visual FoxPro" by Paul Bienick in the July 1995 release of the Microsoft Development Library. Paul Bienick is a software engineer at Flash Creative Management, a New Jersey firm
www.dfpug.de/loseblattsammlung%5Cmigration%5Cwhitepapers/foxole.htm 7/8

7/9/13

Using OLE Automation in Visual FoxPro

specializing in helping companies improve business processes. He can be reached on CompuServe at 71510,3217.

Dealing with Complex Object Models


Microsoft Excel provides more than 100 objects, each of which has a myriad of properties and methods. You don't have to memorize each property and method to be productive with Microsoft Excel but it does help to become familiar with what's there. A great way to learn how to use these properties and methods is through Visual Basic for Applications, which includes the Microsoft Excel built-in macro language. Visual Basic for Applications uses the same objects, properties, and methods available to FoxPro through OLE Automation. In fact, Visual Basic for Applications itself uses OLE Automation to communicate with Microsoft Excel. Knowing this, you can use the macro recorder built into Microsoft Excel to record the functionality you are trying to model. The macro recorder generates Visual Basic code, which you can examine to see how various objects are being used. Granted, not every construct in the Visual Basic programming system is directly portable to FoxPro, but Visual Basic interacts with Microsoft Excel in much the same way as FoxPro, and the syntax when dealing with Microsoft Excel objects is almost identical. In many cases you may discover new objects or techniques. Another great way to become familiar with an application's objects is through the command window, from which you can interactively create objects, set object properties, and call object methods.

www.dfpug.de/loseblattsammlung%5Cmigration%5Cwhitepapers/foxole.htm

8/8

You might also like