There is a single copy of Inside OLE 2 by Kraig Brockschmidt at the Internet Archive, as well as the second edition from 1995. This book taught me so, so much about COM and OLE, I thought I'd dedicate a post to it.
The year was 1994. The highest-grossing films of the year were The Lion King and Forrest Gump; Schindler's List was awareded seven Academy Awards. Mariah Carey, Bryan Adams and Ace of Base blasted through the radio. Inside OLE 2 was available at your friendly bookstore.
1994 was also de year of the Design Patterns book by Erich Gamma et al. Windows 95 was around the corner (it would release in August of '95), along with Office 95.
The suite of '95 products supported new hotness in user interface: drag-and-drop everywhere, rich copy and paste, and the ability to embed and link documents together, so for example your Word document could have an Excel spreadsheet that would be editing in Excel proper. Soon enough, the apps would matter less and less, as rich documents were composed everwhere.
How to access the new hotness? With OLE2, the evolution of the older Dynamic Data Exchange (DDE).
The book starts off with an overview, an explanation of how to write for COM/OLE2 in C++, and then describes objects, interfaces, and the component object model. The second edition also covers type information and metadata early on.
At this point, a solid foundation has been established. The patterns for lifetime management and rules for data are set out, which are still widely used today both in COM-specific contexts, as well as in many "well we need something well understood" ad-hoc cases.
One other foundational bit that shows up in the first part of the second edition is local/remote transparency. This includes cross-apartment marshalling, standard and custom marshalling, and the use of MIDL (Microsoft Interface Definition Language), as well as some of the concurrency concerns I've discussed elsewhere.
There are many foundational APIs in COM and OLE2 that the object describes that are simply good starting patterns for multiple area. We have hindsight today to make them even better, often simply by looking at what has stood the test of time vs. what has faded away (usually because they turned out to be too complex for common cases).
Structured storage still exists especically in various stream forms, although these day's you're more likely to see them implemented over memory and simple files, without the locking bits. Compound files supported a mini-file-system within, with a very rich feature set: locks, transactions, shareable elements ... This never really took off the way one might have expected.
Persistent objects did OK - basically the idea of asking an object to persist itself in a stream or file, or to rehydrate itself from one.
Monikers are an interesting area. They are a very useful concept: the ability to use different chained mechanisms to reference or dereference elements within a "path". Today, some form of URL is often used in its place, with custom protocols as needed. They are still in use in a very dark corners, at least in their basic form. The fact that the kinds of parts are also extensible (as most of COM is) does make for a more complicated processing model though, which is likely why more uniform URLs are much more in vogue these days.
Data transfer objects for clipboard or drag/drop are definitely still in use today, and in my opinion have a very good balace of richness and complexity. At its core, it consists of enumerating supported formats for a piece of data, with lowering levels of fidelity, and allowing consumers to select their preferred representation. Drag and drop add a bit of interactivity to show richer UI. Data change notifications are more complex and less likely to be seen.
Embedded objects (view objects) are very seldom seen these days, as a full proper implementation requires a fair bit of coding, and ultimately drawing works via GDI. There's an HDC passed along for drawing to IViewObject) where this coupling is made. A proper interface for drawing would be quite nifty indeed - these days, one might pass along something like an IUnknown in the general case, with implementations supporting something like a D2D device context or perhaps a DXGI device, from which other APIs can be reached to select an appropriate one.
Automation is worth its own section. It powered the Visual Basic for Applications, replacing older per-app macro systems as the favored approach. It was also a much improved platform for Visual Basic applications and eventually scripting languages like JScript. For all its coupling to the Visual Basic language (there are lots of allowances for language quirks, like a default property for indexing expressions off an object), it remained a popular bit of technology for a long time.
Documents, linking and embedding are full of little nuggets of design solutions to interesting problems. They form the framework by which you could create a document or document fragment (like an Excel region, or a Visio diagram) and embed it in another program. There were many states to manage and many bits of integration (mouse, rendering, menu access), but in turn you got the ability to view the content without loading the appropriate extension, to edit in-place by merging bits of menu or toolbar, and to do a full-on activation of the source program.
OLE controls straddles the line a bit between automation (much simpler, especially with type libraries) and documents (much more complex with all the toolbar extension bits).
OK, so I've touched a bit on the book contents. I also enjoyed the style of the book tremendously (in transparency, this was during my formative years, so it's not like I can completely remove my nostalgia-colored glasses).
There are examples running through, and the various bits of technology are presented with examples an in context of the problem they're solving. There are also tidbits about the history of the development, which I always find very educational - it's good to learn from others' experience.
So, does Inside OLE offer anything to the modern programmer? I think so. The book covers a wide selection of design challenges and solutions, using an extensible framework that has stood the test of time like few others.
The book is fertile soil for new ideas and tried approaches for solving basic design problems you will find in any medium- to large-sized project: dealing with abstractions, creating and versioning contracts, how to separate things and put them back together, how to solve problems of persistenace, resilient references, registration, interception, and many more.
Happy component-based programming!