Previous Page TOC Next Page

19 — In Process OLE Servers

by Chuck Traywick

Wouldn't it be nice if you had the ability to create procedures in Visual Basic that you could call like standard DLLs? Well, guess what? Part of Visual Basic 4.0 has that exact capability. It's called In Process and Out of Process servers.

As a brief refresher, in the previous chapter, you created a class module and then compiled and installed this new class into the system registry. A class defines what an object is or can become. The actual object is created when you call its class or define a class in a procedure. You can call a class multiple times and create multiple instances of this class.

When you define a class, you specify what actions it can take. These actions are called methods. Most classes also have static fields where values can be stored; these fields are called properties. When you insert, for example, a text box onto a form and then press F4, a dialog box that displays the current properties of the text box control appears. Double-clicking on the text box causes a code window to appear. This code window contains a combo box that lists the events from which you can choose; these events are the methods for this object.

You can now create this same capability for extensions to Visual Basic or for use by other applications within Visual Basic. You can compile a library of functions that you can encapsulate into an In Process server that can in turn be called by multiple applications. Suppose that your applications always format the header and footer the same way when using the Printer object. You could develop a routine that formats the header and footer by accepting parameters and then call that routine from all applications that you develop. You can use this same capability to extend the operating system as well as your development tools. For example, you can now (using Windows NT 3.51 and above and Windows 95) develop an application as you would develop a general purpose query. When this application is installed, you can choose to install it into the system registry as a object. Then other applications that are OLE 2.0-compliant can paste your object into their applications.

OLE objects that are defined by In Process servers use the basic Windows messaging structure, which involves a server and a client(s) that calls the methods and properties of the server.

Understanding the Benefits of OLE Servers

OLE servers and OLE itself are not as difficult to use as some people in the computer industry would lead you to believe. If you are comfortable programming in Visual Basic, you can learn to use OLE effectively. I frequently encounter smart, capable individuals who don't try some of the new technology because someone wrote an article about how difficult it is to implement compared with what you get out of it. Experiment with this technology and try it out for yourself.

There have always been protracted discussions about the philosophy of software development. C programmers do the really hard stuff, COBOL programmers work on the everyday stuff, and so on. My advice to you is don't put yourself into a box, and don't let others put you in a box about new ideas. The whole purpose of OLE is simple: share data and code; reduce cost; and improve reliability.

OLE, as the previous chapter discussed, is not as widespread in non-shrink-wrapped applications as it is in shrink-wrapped applications. I think this is partly due to competition among vendors of shrink-wrapped applications in their feature wars. To be fair, OLE is not yet a mature technology, but that does not mean you should not use it. By the time you get a good application up and implemented, OLE will be much further along.

In my experience, most organizations take considerable time to implement new technology. For example, if your organization has 500 employees and has been in existence for awhile, then most likely you will have a wide array of computer types and users. Most organizations that I have dealt with cannot afford to throw away the equipment and training they have whenever a new technology comes along.

There is also an element of risk in investing in learning OLE and developing some applications using it because there's no way of knowing whether it will become a standard. I have absolutely no doubts that object technology is going to dominate software in the future, and I think Microsoft with OLE will have a large piece of that market when it matures. Even so, if some other concept becomes a standard, what you learn with this technology will give you a leg up on those that are waiting until the technology matures.

Some pundits believe that programming will become a task of coordinating multiple software components over the next few years. An OLE object can be a software component. Programmers are doing significant new things with OLE objects. Have you ever written any client/server applications in Visual Basic? If you have, you know how frustrating it was with version 3. Version 4 has remote data objects (RDO). The RDO control is an OLE object for connecting to remote data that is ODBC-compliant. Not only does the RDO object simplify the connection to remote data but it dramatically improves speed of the connection as well. RDO is a good example of what OLE objects can do: improve access, improve reliability, reduce programming time, and improve performance. If you start using OLE now in a meaningful way, then, as the standard matures, you will have in house expertise and working applications that will increase reliability, lower cost, and allow data to be shared more easily.

Creating an In Process Server

To see how OLE In Process servers work, try the following procedure. This procedure shows you how to create a server that displays copyright information and does a couple of other things for clients that call it. Follow these steps to create the OLE server:

  1. Start up Visual Basic 4.0. Then choose File | New project.

  2. Select Tools | Options.

  3. Click on the Project tab at the top of the form. Your screen should look like Figure 19.1.


Figure 19.1. The Project tab of a Visual Basic form.

  1. From the Startup Form drop-down list, pick Sub Main(). This option causes your application to start with an invisible procedure named Sub Main() instead of a visible form. Because this OLE server will be called from client applications, you don't want it to specify a form as its start module. Sub Main() is a reserved name used for this purpose.

  2. In the Project Name box, enter MyCopyRight.

  3. Select the OLE Server option button in the Start Mode box.

  4. In the Application Description text box, enter MyCopyDemo.

  5. Click the OK button on this screen to save your changes.

The Sub Main procedure you chose in step 4 above is where you can establish start-up code prior to initialization if you need or want to do so. To make this procedure work, you first need to create a code module. Follow these steps:

  1. From the main Visual Basic menu choose Insert | Module.

  2. While this module is on-screen, choose View | Properties.

  3. From the Object drop-down list, pick General.

  4. In the code window, type in Sub Main() followed by an Enter. Visual Basic automatically adds the End Sub to create the outline of a procedure.

  5. Press F4 to view the properties window. After viewing the properties window, close the Properties dialog box by double-clicking on the close icon. You should now already be in the code window for the module you just inserted. If not, display the code window by double-clicking on the form.

  6. You should now have a module that looks like Figure 19.2. This code module doesn't contain anything, but you need to create it regardless of whether you intend to use it.

  7. Close the code window for Sub Main() by double-clicking on the close icon.


Figure 19.2. The default Sub Main procedure.

Now you need to add a class module. Remember from Chapter 18 that a class defines an object. The object itself does not get created until it is called. Then Visual Basic uses the specifications defined in the class module to create a specific instance of this class as your particular object. The OLE server creates a reference to the specific object that is created at call time. In other words, the only thing you are creating here is the outline or parameters of your object. When the class is called, a specific object that has its own life will be created using the parameters that you define here. To create a class module, follow these steps:

  1. Choose Insert | Class Module. You now should have a blank Class Module code window on your screen.

  2. With the Class Module window highlighted, press F4 to display this class' properties window.

  3. Change the properties as follows:

    NAME = CopyR
    PUBLIC = TRUE
    INSTANCING = 2 -creatable MultiUse

The Name property specifies the name of the class. Setting the Public property to TRUE means you can see the class from other applications. Setting the Instancing property to 2-creatable multiuse allows the OLE server to create multiple objects. (Note that it is sometimes useful to be able to restrict an object instance to one call. You might want to make this restriction if, for example, you were to use OLE to do maintenance on a database.) These properties create a framework for your object.

Now you need to define properties and methods. If you want your properties and methods to be public, they must be defined as such. There are cases, even in an OLE server, in which you might want private variables and procedures instead. Users can read private variables, but they cannot change these variables.

Follow these steps to define the properties and methods:

  1. In the Declarations section of the class module, define the following properties:

    Option Explicit
    Public Msg1 As String
    Public CopyDate As Date

    Your screen should look like Figure 19.3.


  2. Figure 19.3. The object properties.

  3. To create a method that gets the copyright data, choose Insert | Procedure.

  4. In the Name field, enter Copy_Date and select the Property and Public option buttons. Because this is a property, Visual Basic automatically creates a LET (or read) function and a GET (or write) function.

  5. To test what you've done so far, press Ctrl + F5. If everything is correct, you should see a running debug screen as shown in Figure 19.4. Nothing is displayed because you are testing the OLE server. Remember that the client application displays and processes the data in this example.


Figure 19.4. Testing the Visual Basic object.


TIP

Always test your OLE server to see whether it will run without errors before developing your client application. If a bug exists in the server and you don't discover it until you have two pieces of code (the client and the server), the bug is more difficult to find because you have increased the number of variables.

Creating the Client Application

To create the client application that will call the server you just created, follow these steps:

  1. While your OLE server is still running, start another instance of Visual Basic, and then start a new project.

  2. Resize the form to a smaller size and place the command buttons that are shown in Figure 19.5.


  3. Figure 19.5. Defining the client object.

  4. Define a second form that overlays the first form.

  5. Change Form1's caption to MyCompany. Change Form2's caption to Copyright Information.

  6. In Form2, create a text box that almost fills up the form.

  7. In Form2, set the MultiLine property to TRUE and the Visible property to FALSE.

  8. Create the two command buttons on Form1 shown in Figure 19.5. Set the caption on Command1 to Show Copyright, and set the caption on Command2 to Hide Copyright.

Linking the Client and the Server Applications

To create a link or reference between this client application and the server that you are calling, follow these steps:

  1. Choose Tools | Reference. Your screen should look like Figure 19.6. At the bottom of the screen, you should see the server named MyCopyDemo (you may have to scroll down to see this server). Any other applications you have loaded on your computer also appear on this screen.


  2. Figure 19.6. Including a reference in your client object application.

  3. Click on the box to the left of MyCopyDemo and then click on OK.

  4. Press F2 to display the object browser. The initial screen should show Form1 and Form2.

  5. From the Library/Projects drop-down list, select MyCopyDemo. The screen shown in Figure 19.7 appears. The left window shows the CopyR class module you created earlier. The right window shows the methods(s) (in this case Copy_Date) and the properties (in this case MSG1 and CopyDate) you defined.


  6. Figure 19.7. Browsing objects in our OLE server object.

  7. Press Alt+Tab to go to the OLE server you have running. Then click on the Stop button on the toolbar.

  8. Highlight the class module and display its code window.

  9. From the Object drop-down list, select General.

  10. In the Proc window, select COPY_DATE[PropertyGet].

  1. Press Alt+Tab to switch to your other instance of Visual Basic and display your client application.

  2. Display the code window for Form1.

  3. In the Object drop-down list, pick General.

  4. Make sure the Proc window says Declarations. Then add the following code:

    Option Explicit
    Dim MyRights As New CopyR

  5. To access the CopyR class, you need to attach some code to the command buttons you placed above. Add the following code to the Form Load event on Form1:

    Private Sub Form_Load()
    MyRights.Msg1 = InputBox("Enter your name")
    End Sub

  6. Insert the following into Command1's Click event:

    Private Sub Command1_Click()
    Form2.BackColor = vbBlue
    Form2.Text1.BackColor = vbYellow
    Form2.Text1.TEXT = "All rights reserved by " & MyRights.Msg1 & Chr(169) & vbCrLf & MyRights.Copy_Date
    Form2.Visible = True
    End Sub

  7. With the OLE server still running, test the client application by pressing F5. The screen shown in Figure 19.8 should appear.


Figure 19.8. Testing the client object.

  1. Enter your name and press Enter. The Form1 screen appears.

  2. Click on the Show Copyright button. The screen defined by Form2 and the data called from the OLE server should appear, as shown in Figure 19.9.


Figure 19.9. A running client accessing the In Process server.

This example worked because you had both the client and the server applications running at the same time. Closing the OLE server and running the client application produces an error. To prevent this error from occurring, you need to register the server application into the system registry.

Registering Your OLE Server

To register your OLE server on the same computer you created it on, choose File | Make OLE DLL file. Enter an appropriate name and the system will register the In Process server in the system registry as shown in Figure 19.10.


Figure 19.10. Registering the In Process server.


NOTE

Be careful about the naming syntax you use. When you install these objects into the system registry, they become public names throughout your system. There are limited restrictions to names, but you do not want to create conflicts with what other applications may do. For example, you may want to have your own section in the registry for each application that installs under LOCAL_MACHINE: LOCAL_MACHINE;SOFTWARE;MY_APP;THIS_OPTION. This section would look like the following:

LOCAL_MACHINE
LOCAL_MACHINE
SOFTWARE;
MY_APP
THIS_OPTION OPTION 0x1

Because this technology is new, developers will have to add to their applications install procedures code that checks the registry for duplicate section names in order to avoid this problem.

You can also create an OLE server as an executable file for installation onto a target machine by choosing File | Make EXE. When you install on your target machine, enter the following in the Run command dialog box:

C:\MyProg.EXE /REGSERVER

Figure 19.11 shows how the executable file named TARGET.EXE would look in the registry.


Figure 19.11. Registering external In Process servers.

The computer shown in Figure 19.11 now has two OLE servers that do the same thing installed on it. The COPYR.DLL is located in the C:\OLESERV directory and now also is TARGET.EXE. When you run the client application again, you must first terminate the instance of Visual Basic that is running your OLE server. Then go into your client application and remove the reference to MyCopyDemo (you called your DLL COPYR.DLL). Using the Browse button, point to COPYR.DLL in the C:\OLESERV directory. When you run the application again and click on the Show Copyright button (now without the other instance of Visual Basic running), you see the screen shown in Figure 19.12. Save this OLE server project and client project as separate projects.


Figure 19.12. A client application accessing a built-in In Process server.

The previous application examples are defined as In Process servers because they execute in the same process space as the client that called them. In the example, you knew ahead of time that you wanted to link the copyright server to your application, so you could include a reference to it. What if that were not the case? Or what if we wanted to use some pre-existing OLE servers?

As demonstrated in the previous example, you can dramatically expand OLE servers to perform all kinds of tasks. Before you can put this technology to work, however, you need to ask yourself some questions. I do not have the space in this chapter to define all of the following characteristics, but you can use the following questions as a brief checklist of issues to resolve prior to creating your OLE servers:


NOTE

OLE servers with Visual Basic 4.0 do not support in place editing. In OLE-compliant applications, you can embed, for example, an Excel form that invokes the Excel interface. Visual Basic doesn't have this capability. You can execute forms and procedures, but not complete application interfaces. For example, you could run a query that returned data to an Excel spreadsheet, but you could not run the application in its entirety within Excel.

Answering all these questions will guide you to a proper design. You also need to consider the normal programming concerns such as determining how many resources the application will consume, figuring out how large the in-memory image will be, and deciding whether to use many small objects or large DLLs that contain many objects. The answers to these questions are, of course, dependent upon the application involved.

When you start to answer the questions mentioned previously, it is helpful to look at objects in another light. Traditionally, good programming style has dictated using parametric design in many of the algorithms that you create. This design means that a set of given values that a program may use to display or get data are not coded into the program but are established in a Setup function somewhere within the system. In this way, you can think of objects as stored procedures. Like anything that you store and retrieve, you can also link these objects together into a database-like hierarchy.

When I use the term stored procedure, I don't mean it in the same vein that this term is used in SQL databases. These procedures are limited in function to specific database activities and are tied to very specific applications. Objects are like stored procedures in that they do not reside in the client software, but, unlike stored procedures, they can be called and used by a wide variety of applications and can be used throughout the system.


NOTE

Of note here is the last minute addition of Remote OLE, which is the ability to use objects across a network. Using Remote OLE, you can have multiple stored OLE objects that reside on a server that can be used repeatedly by multiple users from multiple locations. For example, you could create an In Process Server that could install onto an Windows NT server that could be pasted into client applications—like a query written in Visual Basic 4.0 that extracts data from a SQL database. Let's say you have monthly reports to create each month. The report is the same, and only the data changes. You could take this query that you create in VB as an OLE object and paste it into an Excel spreadsheet. The spreadsheet could contain graphs (showing what a wonderful job you are doing) and other functions that create your report. When you load the spreadsheet, the query would automatically execute to refresh the data and your report is done.

In traditional database nomenclature, you can have flat files, and you can have hierarchical files. This is also true of objects. You could create a set of objects that are all flat in that no one object depends upon the other. For example, you could have a set of objects that you use with the printer object. You could have a page header object, a page footer object, a print logo object, and so forth. You could call each one of these objects directly.

A hierarchical file could be something like an inventory class. The top or main class could be Inventory. Transactions could be a subclass. You could tie the Transactions subclass to the Inventory class with a Collection class. Therefore, when you refer to the Inventory class, you automatically get the Transactions class as well. For instance, in the previous example, you could get to the MSG1 object by defining a new instance of CopyR. This is because MSG1 is encapsulated within CopyR, each new instance of CopyR also creates a reference to the subclasses within this object. If you defined a new instance of Inventory, you would get all of the methods and properties of Inventory as well as all of the subclasses, properties, and methods of Transactions. Again, this is because Transactions as a class is encapsulated within Inventory. You could extend this idea dramatically to nest classes several levels deep. Of course, when you have several levels of classes, you have slower performance (because there are more classes to go through to find objects) and a larger program image size.

Keep in mind the purpose of your objects. If they become too specific, you may want to weigh the time it takes to create an object class versus the time it takes to embed the code in your application. A class or object should be a code fragment that has multiple applications and uses.

Another example may give you a better idea of how this process works. As you did in the previous example, you need to set up the project somewhat differently in order to create an OLE server. Consider Figure 19.13.


Figure 19.13. Defining an In Process server.

The first thing you need to do is to enter a name in the Project name box. At this point in the process, some planning is worthwhile. Remember that the project name needs to be unique when you install it into the system registry. In the previous example, you created a class CopyR. To use this class in a new client application, you could use the following code fragment:

PUBLIC MyNewObject As MyCopyRight.CopyR

This kind of code is called a fully qualified class name because it contains the project name (MyCopyRight) and the class you are creating (CopyR). Remember that most of your users' Windows applications will now have multiple definitions of unique classes for a given application. For example, I recently read that Excel 5.0 has over 100 object classes of its own. If you were to define a class that had the same name as your application, your application could crash. For this reason, you should use fully qualified class names in addition to planning out what class names you want to use.

Figure 19.14 shows an example of how not to name your projects. Remember when you created two objects earlier in the chapter and named one COPYR.DLL and the other TARGET.EXE? Next, you installed TARGET.EXE with the /REGSERVER option. As a result, you ended up with two of the same object. You can prevent such situations by planning your names and controlling versions and compiles. Even though one of our compiles was a DLL and another was as an EXE, both used the same object name. The object name is what you see here in the Visual Basic reference window.


Figure 19.14. Duplicate In Process servers.

In the Start Mode box, make sure you select the OLE server option in order to create your server first. Visual Basic creates temporary entries into the system registry and creates links to any client provided that you execute two copies of Visual Basic in Design mode, the first copy being your OLE server and the second copy being your client, and perform the proper setting with the Reference function. Although you may not yet want to compile this application of your server and link it into the registry, note that Visual Basic creates temporary links for you so that you can test your client applications. This means that you do not have to permanently link server applications until you are ready to do so.

You would most likely want to make sure that your OLE server compiles and runs before launching a client to test it. This feature is built into the Visual Basic Design mode. Normally, a compiled OLE server would not start until the client called it. When you set the Start mode to OLE server, Visual Basic knows to keep your project running even though no calls are being made to it. Otherwise, the project would end immediately because there are no clients requesting it. In Development mode, it is useful to be able to execute two copies of Visual Basic, one running the server and the other running the client. If you have an OLE server running in Design mode and a client that calls it, stopping your OLE server will produce an error message that notifies you that you have dependent applications.

The vast majority of the time your start-up form will contain a Sub Main() procedure as its primary start-up mode. If you need a start-up form, you should display that form from Sub Main(). Be sure that Sub Main() is not in a class module. Also, use caution when putting forms into OLE servers. Many developers think most, if not all, of the user interface should be in the client application.


NOTE

If you do specify a start-up form, note that the OLE servers Form Load event will be called prior to the Initialize event. This could cause problems depending upon your code. Also, if you use a start-up form, Visual Basic will keep it running even when there are no active clients calling it, thereby necessitating additional action by your server to control Startup and Terminate events.

As discussed briefly in the previous example, another distinguishing feature of an OLE server is that it contains at least one class module with its Public property set to TRUE. Clients can read and write to the procedures and properties in the class module that have their Public properties set to TRUE. This applies to variables, procedures, and functions.

Extending Your OLE Server

Of course, because the OLE server is a project like any other Visual Basic project, you can extend it. To demonstrate this fact, try adding an initialize procedure for when the server you created earlier starts and ends. Follow these steps:

  1. Display the OLE server that you previously created.

  2. In the Project window, highlight COPYR.CLS and double-click it. You should see the screen shown in Figure 19.15.


  3. Figure 19.15. Extending an In Process server.

  4. Display the CopyR class module. In the object window, make sure the caption states Class.

  5. In the Proc: window, select the Initialize event.

  6. Add the following statement to the Initialize event:

    MsgBox "Started OLE server On: " & vbCrLf & Format$(Now, "MM/DD/YY")

  7. Save this project and compile it to an OLE server .DLL. Replace the old COPYR.DLL in the directory that you initially created it in. If you have trouble with this procedure, delete the old COPYR.DLL and compile and save a new one.

  8. Start your client application. Your screen should look like Figure 19.16. You can see that the OLE server's Initialize event performed its function.


  9. Figure 19.16. Running the In Process server with new extensions.

  10. Click on OK to display the screen in Figure 19.17.


Figure 19.17. Expanding the In Process server functionality.

As you can see, you can extend existing OLE servers quite easily. Try adding another method to the OLE server by following these steps:

  1. Activate the class module CopyR.

  2. Double-click the module to display the code window.

  3. Make sure General is selected in the Object drop-down list, and then enter the following code:

    Public Property Get Legal()
    Legal = "According to U.S. Copyright Law 1995"
    End Property

  4. Save your project and replace the COPYR.DLL by recompiling and using the Make DLL command on the File menu.

  5. Add the following changes to the client applications Command1 button. You don't need to replace all of the code; just add the & vbCrLf & MyRights.Legal to the Form2.Text1.TExt = statement:

    Form2.BackColor = vbBlue
    Form2.Text1.BackColor = vbYellow
    Form2.Text1.TEXT = "All rights reserved by " & MyRights.Msg1 & Chr(169)
    _& vbCrLf & MyRights.Copy_Date & vbCrLf & MyRights.Legal
    Form2.Visible = True

  6. Rerun the client application; it should produce the screen shown in Figure 19.18.


Figure 19.18. Adding a new method to the OLE server.

In order to create a complete OLE server, you should add a help file to assist end users and other developers that want to reuse your code. (If the code you are contemplating for an OLE server cannot be reused, you should consider whether you need to create an OLE server at all.) Follow these steps to add a help file:

  1. In your OLE server project, choose Tools | Options.

  2. Display the Project tab. Then specify a path and name for a help file. For example, specify c:\oleserv\oleserv.hlp. Your screen should look like Figure 19.19.

  3. Open your Oleserv project and press F2 to display the object browser. Your screen should look like Figure 19.20. The left hand window shows the methods and properties for the CopyR class. If the CopyR class is not highlighted in the left window, click on it to get the correct display in the right hand window.


  4. Figure 19.19. Adding a help file to your In Process server.


    Figure 19.20. Browsing the In Process server.

  5. Click on Class_Initialize(Sub).

  6. Click on Options. Your screen should now look like Figure 19.21.


  7. Figure 19.21. Browsing elements of our server.

  8. Enter a description as follows:

    This procedure is the initialization code for MyCopyRight. This procedure shows the date that you initialized the OLE server in a dialog box.

  9. Click on close to return to the Visual Basic editor.

The confines of this chapter do not allow me to describe all of the features you could add to your OLE server. Two important features you should add are error handling and version control. The Microsoft Visual Basic manuals present some information on these subjects, but it is best to experiment for yourself and keep in mind the problems you can avoid downstream by building in code for these two additional areas.

Summary

I could write a very long book just on OLE programming. Because OLE is not the main focus of this book, I will stop here with a couple of additional thoughts that may be helpful. Hopefully, you can see the tremendous potential in OLE and OLE programming. Yes, it is new. Yes, it has constraints. Yes, it has some bugs. However, I believe Microsoft will be adept at addressing these issues. If you want to move your organization forward and if you are tired of programming the same old stuff over and over again, OLE is a way to resolve both issues in an elegant fashion.

Happy coding!

Previous Page TOC Next Page