1994 may finally be the year that distributed object computing becomes a reality
Jon Udell
"We prototyped our application in Visual Basic, expecting to rewrite it in C," said a friend of mine recently. "But in the end we just shipped the prototype." I have heard this same story from more than a few programmers. How can a mere BASIC interpreter power a commercial Windows application? By exploiting prebuilt components. You use VB to evolve a user interface that VB itself can, in many cases, run acceptably fast. Then you bind that user interface to DLLs or VBXes (Visual Basic custom controls) that do the real computational work in compiled code.
The first wave of VB applications leaned heavily on DLL support. Two years ago I built a VB database application u
sing standard VB controls (i.e., buttons, text fields, and listboxes) and Sequiter Software's CodeBase DLL. The glue holding it together was my own VB code.
Nowadays I use VBXes like Q+E's MultiLink/VB and Coromandel's Integra VDB to write much fancier database applications with much less effort. These new data-smart custom controls understand complex idioms such as navigating related tables. That means less VB code to write (i.e., faster development) and less to interpret (i.e., faster execution). When you do write VB code, it's often just a snippet to handle a navigation or update event generated by the custom control.
VBXes aren't just for database work, although that's the most popular category. There are custom controls for many application domains, including imaging, CAD, telephony, communications, data acquisition, and financial modeling. In fact, the dramatic success of VBXes is quite embarrassing to OOP (object-oriented programming) purists. A VBX is, after all, only an odd sort of DLL
that co-opts the VB message pump in a useful way. (VB, in turn, co-opts the Windows message pump in a useful way.) While a VBX encapsulates methods and data, it isn't inheritable or polymorphic.
But despite these theoretical shortcomings, VBXes are just what C++ and other OOP languages have long promised yet conspicuously failed to deliver: reusable software components. The culture clash became brutally obvious when Microsoft and Borland were forced to add VBX support to their C++ compilers. To enable a C++ program to host a VBX, the compiler has to supply emulation code that fools the VBX into thinking it's running in the VB environment.
If native C++ components were abundant and easily reusable, C++ programmers would surely prefer them. Why isn't this the case? There's no good way to package C++ components in binary form for use in Windows. In theory, you ought to be able to bundle a C++ class library into a DLL for use by other C++ programs. But in practice that's hard, because DLLs don't do
OOP-style method dispatching and can't smooth over differences in the binary objects produced by different C++ compilers.
IBM's SOM (System Object Model), which can solve these problems and is slated to debut on Windows, currently runs only on OS/2 and AIX. And while Sun Microsystems has now anointed NextStep as its object standard, no one is talking about moving it to Windows. Hence the unholy alliance of C++ and VBX technologies. Windows programmers want to be able to build and use components today, and their binary object standard--for better and for worse--is VBX.
VBX at the Crossroads
Developers were shaken when Microsoft announced that the 16-bit Windows platform was the end of the line for VBXes. Existing custom controls will operate on Win32 platforms (i.e., NT and Chicago), because these operating systems can run VB and other 16-bit VBX hosts.
But you won't see Win32-based VBXes on Chicago, or portable versions of them on NT. What you will see instead, Microsoft says, are Win3
2-based OLE 2.0 objects that export methods and properties using the OLE automation interface, IDispatch. Clients that can call those methods and edit those properties will include current and future versions of VB, applications (e.g., Excel) that have VBA (Visual Basic for Applications) embedded in them, and any Win16 or Win32 application that conforms to the IDispatch client protocol.
Were developers reassured by this statement of direction? Quite the contrary. Many were horrified, because OLE 2.0 represents the most stupefyingly complex software technology Microsoft has ever created. IDispatch-style automation is just one of the beast's many heads. Other interfaces govern linking, embedding, in-place activation, data transfer, and structured storage.
Once mastered, however, OLE 2.0 delivers tremendous benefits. Witness Excel 5.0, which, among other things, can function as both an OLE automation client and server. The client capability flows from VBA, which Excel 5.0 offers as an alternative t
o its existing macro language. An Excel VBA script can control any OLE 2.0 server, including, most notably, Excel itself. OLE 2.0 clients, reciprocally, can tap into the Excel 5.0 object library, which contains dozens of objects and hundreds of methods and properties. You can, for example, quite easily write a VB application that uses Excel 5.0 as though it were a high-powered custom control for charting or data analysis.
Windows component builders know that OLE objects will somehow replace VBXes, but they've found climbing the OLE learning curve to be like an oxygenless assault on Everest. Fortunately, help has arrived.
Make Friends with MFC
The latest release of Visual C++, version 1.5, which includes version 2.5 of the MFC (Microsoft Foundation Classes), delivers a stunningly powerful encapsulation of OLE embedding and automation. "We've written the 20,000 lines of C++ that make OLE useful," says Visual C++ product manager Denis Gilbert. Whether an operating-system extension should require
20,000 lines of code to be usable by mere mortals is an interesting question, but in any case, MFC 2.5 is here, and it works wonders. Experimenting with it has given me a glimpse of how OLE-style custom controls--the VBXes of tomorrow--will work.
I started with a simple MFC database application. Because MFC 2.5 also encapsulates ODBC (Open Database Connectivity) database access, it required essentially no code. I used a checkbox in AppWizard to pull in the database classes, laid out a form in AppStudio, and bound database fields (via member variables) to the form in ClassWizard. When I built the resulting application, it connected to a SQL Server database, and I could use its VCR-style toolbar to advance through a set of records.
There's more. Because I'd used another AppWizard checkbox to indicate that the application should work as an OLE 2.0 in-place server, it was automatically embeddable in OLE 2.0 containers. Using Excel 5.0's Insert Object command, for example, I was able to place an ins
tance of my application on the surface of a spreadsheet; when active, my application's menu and toolbar replaced those of the Excel container.
MFC provided the implementation of multiple OLE interfaces, including IOleObject, IRunnableObject, IViewObject, and IDispatch--things I've read about and understand in a general way but can scarcely conceive of programming with raw OLE API calls. And Visual C++ took care of housekeeping details such as adding the document type to the Windows registry.
Together, MFC and Visual C++ made a mountain of complexity just disappear and handed me a usable OLE toolkit. I'm no hotshot Windows programmer, but I was able to construct what was beginning to feel like a database custom control.
There's more. Because I'd also told AppWizard that my application should include support for OLE automation, ClassWizard invited me to export methods and properties for use by VB or other OLE automation clients. I decided to export a GetCompany method that returned a value
from the current record, and a NextRecord method that would advance the record pointer.
Here, finally, I had to write some code. Implementing these methods took only a few lines of C++, but I spent hours discovering which lines I needed and where to put them. It all hinged on how MFC's generic document and view classes related to each other and to the derived RecordSet and RecordView classes. In MFC, as in Smalltalk, you swim in a sea of objects that you know are all somehow connected. Discovering how they're connected, and learning to manipulate the connections, is the trick.
Eventually--and certainly weeks sooner than had I attempted the feat unaided by MFC--I could launch my application and control it from VB. Now it was really starting to feel like a database custom control.
Missing Pieces
There's plenty of work still to be done before OLE custom controls can fully replace VBXes. OLE 2.0 lacks an event model. VB can call my application's NextRecord method, but the application can't
report a NextRecord event back to VB. Enabling OLE servers to fire off events, and OLE clients to register handlers for those events, will require extensions to the current OLE 2.0.
Further extensions will be required to extend OLE's interprocess communication across networks. Finally, for visual programming environments like VB, OLE objects will also need a framework for design-time form layout and property editing. So OLE custom controls are still hazily defined.
Component builders shouldn't wait until the picture clarifies, however. The toughest job will be to define which methods and properties your application should export and how to organize them. The hard work of engineering dual-purpose applications that function interactively and as programmable components can and should begin now, because the component software revolution really is--finally--about to happen.
OOP purists bothered by the seeming primacy of BASIC can relax--it's just an accident of history. VB and VBA were the fi
rst languages enabled for OLE automation, but I predict that by the end of 1994 you'll see Lisp, Smalltalk, and other interpretive OOP languages acquire OLE bindings as well. Meanwhile, C++ will enable OLE component builders to leverage the power of a compiled OOP language. There's nothing wrong with C++ that a decent binary object standard can't fix. OLE 2.0 will be one of the most important examples of such a standard.
Microsoft detractors bothered by the seeming primacy of OLE can also relax. OLE will likely become network-capable rather sooner than Microsoft's own leisurely schedule for Cairo (ship date: 1995) implies. Distributed object computing can't wait that long. Microsoft and DEC are already working to make DEC's CORBA-compliant ObjectBroker interoperate with OLE. Meanwhile, Symbiotics has announced that its Networks Connect 2.0 will extend OLE linking and automation across networks.
These are just a few of the proposals that will be submitted to the OMG (Object Management Group) this
year in response to its request for a next-generation distributed object architecture. As a result, it now seems possible--even likely--that the OMG's influence will prevail and that Microsoft's OLE, IBM's DSOM (Distributed System Object Model), and Sun's DOE (Distributed Objects Everywhere) can meet on common ground.
Jon Udell is a BYTE senior technical editor at large. He can be reached on the Internet or BIX at
judell@bix.com
.