> It was magical that dropping a telephony component into a form enabled the form to make phone calls
the magic of COM[0]!
But when it crashed it crashed hard. And the underlying programming model (beyond just using premade ones) are a bit hard to grok and fraught with footguns that shoot not only yourself, but the OS as well.
And COM/OLE/ActiveX components (whatever Microsoft fancied calling them that year) could have been used just as easily from Delphi.
And you don't even need COM. You could do the same things today with RAD components in, say, Java. But it's just no longer a fad. Programmers nowadays don't think that dragging a component that makes phone calls and linking it to a button.
Nowadays, they would just write "npm install telephony" and then add a couple of lines that they got from the README.md on GitHub (or from their AI assistant) to make a call:
import { Dialer } from "telephony";
const dialer = new Dialer();
dialer.call("+1 800 1234 1234");
> And COM/OLE/ActiveX components [] could have been used just as easily from Delphi
I wanted to use Excel from within Delphi - I wasted more than a few weeks and ultimately failed. I always suspected that the COM/OLE integration had problems with some of the advanced features I was trying to use (I was trying to do something rather complicated). Plus the documentation and support was lacking for Delphi - Microsoft best supports Microsoft tools. I did use Delphi and COM successfully in many other situations but that one failure really soured me towards COM and Delphi together. I am typically capable of making complex integrations work, so I was surprised to fail.
The way COM model worked, is that an application (for example, microsoft word) would implement this COM interface (that they'd have to anyway, for various reasons such as interoperability), and it would become available as a component to be used in another application.
It's a grandiose vision. It just didnt work out because of how complicated it is in practise to implement the COM interface(s), and not enough apps did it anyway.
It is slightly different from a library, since that library would have to be useable from your language (or have some sort of FFI mechanism).
It was (is) an ABI, more stable than something available through a C/C++ compiler. It’s been years since I’ve lived in a Windows world, but as I understand it, it’s still very much alive and well. It didn’t fail because it was complicated, although it was, but it continued to evolve and was eventually superseded by .net. I worked with win32 & mfc quite a bit and had to interface with Com/activex a little, usually through wrappers of some kind, but it was always under the covers. I also wouldn’t say that it failed because not enough apps did it. I can’t speak to drivers or system components, but if you were distributing windows apps prior to and early into .net, you dealt with com directly or indirectly.
I remember some things being very tiresome, esp. from a C or C++ view of the world. There weren't any default implementations for most things, as you would find in Java. So for Java you might have an abstract class that got you 95% there, in COM/OLE you needed to do that 95% yourself, and this was before you had lots of public domain things available. Later, we could go on Codeguru or whatever and get a good example.
Many things were designed at the level of Microsoft App 1 (e.g. Word), and then when they needed something different for another app (e.g. Shell) they extended the interface in a different interface, and so on. The only authority for interfaces was Microsoft. Nobody else was really able to come along and make a set of interfaces that would become universal for something new, so you had to wait for Microsoft's design, and then it would be designed to support the way it was implemented in Word, Excel, or Internet Explorer, and they would not release the implementation details, just an interface specification and some hastily-written documentation.
Naming things was hard for Microsoft, so they came up with idiotic names like "IClassFactory" because they couldn't decide if they wanted to call something a Class (Smalltalk-style) or a Factory.
It took forever to learn because the documentation was not oriented around practical things, it was toy examples that didn't even work within the system. As a young programmer, it took me a long time to understand how everything was registered, what the difference between a CoClass and an interface really was, where to get that initial IUnknown pointer, etc., because the books were so focused on vtables and toy examples, etc.
The system was mostly replicated by Netscape/Mozilla for XPCOM, so it had areas where you could apply the same principles on other platforms. It also had superficial similarity to SOM/CORBA so learning those systems (thankfully mostly gone now) was also somewhat easier after learning COM.
There were several categories of applications.
- Those that used COM/OLE fully, as the underlying basis of everything they did, used structured storage, and exposed components and automation to the rest of the world.
- Those that implemented some sort of automatability and things like shell preview.
- Finally, those that used the minimal amount to support drag and drop and the like.
After a while, Microsoft's habit of introducing the next big thing and mostly abandoning it a few years later caused Windows application development to decline. COM has always been around, but many related technologies come and go. .NET blurred the lines between COM and the .NET runtime, and then Microsoft started making substantial overhauls of the Windows runtime without, IMO, getting buy-in. Why write WPF when it's similar to but incompatible with UWP? Why write UWP when Win32 works just fine? I wonder if they're going to introduce yet another? Oh, sure, Windows App SDK. Should we use GDI+ or Direct2D? Which one is going to "win"? Why do any of this when Microsoft themselves is using Electron in VS Code?
I personally think one of the main design problems of COM was that, ironically (given its name), it never really had "component" as a first-class concept. It was all about interfaces, and the rules on how implementation of IUnknown's QueryInterface must behave really highlight that: it's almost impossible to delegate to/compose over another component if that component was not written with this scenario in mind.
And it’s nowhere near these neat 3 lines. Same for ui.
I agree that the spirit of VB/Delphi is in theory easily transferrable to any modern runtime. But in practice we suck at it and there’s nothing even remotely close to just dropping a component on a form. All we have is miles of vaguely explained boilerplate and the most convoluted idioms that don’t connect. The basic technology is lost and only miraculously exists as a windows support artifact.
I had a client with a C++ application that used COM for everything. They wouldn't write a simple C++ class or structure but rather would always fire up the wizard in Visual Studio to create a COM object. It was horrendous.
Having said that COM itself wasn't that bad. If you read the Don Box book he justifies pretty much all the technical decisions they made.
In the end my productivity doubled when I shifted from C++/COM to C#/.Net.
Dropping that little telephone icon on the form was designed to act like most of the other objects at your disposal, but it had an additional footgun all its own.
It depended on the existence of the RS-232 Communication Port object, MSCOMM32.OCX. Which often turned up missing :\
Plus unlike most of the other activex objects, mscomm32 had a certificate that was set to expire, and in only about 5 years, but loads of people never knew it until about 5 years later when it happened, and it's been a shitshow ever since Windows XP.
Just searched a bit and the situation may be looking up:
You may still need to "locate" a suitable version of mscomm32.ocx since there are probably more expired versions in archives than there are acceptable files which will register properly.
This may be one, still referred to as a trick at the time:
the magic of COM[0]!
But when it crashed it crashed hard. And the underlying programming model (beyond just using premade ones) are a bit hard to grok and fraught with footguns that shoot not only yourself, but the OS as well.
[0]: https://en.wikipedia.org/wiki/Component_Object_Model