TweetFollow Us on Twitter

SimpleServer
Volume Number:10
Issue Number:8
Column Tag:New Apple Technology

SimpleServer

A Simple OLE 2.01 Object Server Revealed

By Michael Fanning, Microsoft

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

Code Reuse or Object Reuse?

Code reuse has often been cited as a significant goal of object-oriented programming. Successful examples of code reuse have been few, despite the now-widespread adoption of object-oriented languages and techniques. Applications frameworks, such as MacApp, TCL, and PowerPlant have been reused extensively-but they’re about the only case of code reuse to which one can point. These examples represent not only the success, but also the failure, of object-oriented programming to date: it focused on the reuse of CODE rather than the reuse of OBJECTS. Up to now, it has been impossible to reuse an object without access to its source code-or at least, a static library to which one’s own code (written in the same language) could bind at link-time.

Microsoft Object Linking and Embedding (OLE), version 2.01, addresses this fundamental problem of reusing code. Using OLE, any object can make its services available to any other object at run-time. Objects can be mixed, matched, and reused without regard to the language in which they were written or the vendor from which they came.

Using OLE, you can define any arbitrary service-an “interface” -which any object can then share with any other object. For example, you could easily define an interface for spell-checking which any other object could bind to at run-time, without knowing (or caring) who wrote the spell-checking service or in what language. Similarly, you could define an interface for charting data, for recalculating spreadsheet data, or for rendering photorealistic images.

OLE provides a set of standard services, which are available to any application that wants to use them. These standard services include interfaces for many features that are of interest to software developers today, such as compound documents (documents that include arbitrary data, like a video clip or a CAD blueprint in a word processor) and Visual Editing (the ability to edit that arbitrary data within the context of the containing application, without having to switch to another application). These OLE services provide a structure within which objects interact to reuse each other’s unique features, thus improving the end-user experience (which is what it’s all about, after all).

Goal of This Article

This article describes how basic OLE features were implemented in a simple Macintosh application. The application does not implement every OLE feature; indeed, one of OLE’s most important features-Visual Editing-has not been implemented in the sample to ensure that it is as easy as possible to examine and understand. (Visual Editing will be added to the sample in a subsequent article). Enough features have been added to give you the flavor of OLE development and to let you understand its basic concepts and idioms. The OLE 2.01 SDK CD that accompanies this issue of MacTech will provide you the means to get started in adding OLE support to your application today.

It is important to note that an OLE application is just that: an application much like those your firm develops and sells today. SimpleServer is a stand-alone, double-clickable application designed to provide simple drawing services to any other object. Just as we did with this sample application, you can easily add OLE support to your application, without changing its nature, its distribution, or its business model.

Now, let’s put on our code snorkels, and dive in!

SimpleServer, Revealed

SimpleServer is a minimal implementation of an OLE 2.0 embeddable object server written in C++. The implementation of OLE in this sample code allows SimpleServer objects to be embedded in OLE containers and saved in compound documents.

The first section of this article contains a general description of the sample code source files. The second tracks the communication between SimpleServer and an OLE container as a SimpleServer object is embedded. Finally, I’ve included a glossary of important OLE concepts: consult this section if you come across an unfamiliar term. If you’re new to OLE, or just that kind of person, you might want to go ahead and review this section before reading on. The rest of us who leave manuals wrapped in plastic until all hell breaks loose will continue on without you.

The SimpleServer Source Files

The SimpleServer source files (located in “Sample Code (OLE):SimpleServer:src”on the OLE SDK CD bound in this issue) can be broken out into three groups: a set of source files which provide the basic structure and functionality of the application; a set of sources which contain the OLE-specific code, file utilities, error reporting, and debug information; and sources taken from the sample OLE UI library.

Note: Every OLE interface is in its own file, for easy review, named CInterface (where Interface is the name of the OLE interface implemented in the file).

The Basic Application

IUnknown - IUnknown is the abstract base class for all SimpleServer objects. Defined in the OLE header compobj.h, its methods (like the member functions of all standard OLE interfaces) are pure virtual and are implemented in SimpleServer’s derived object classes.

Class Source Files

Capplication.cp - Methods used to initialize the Mac Toolbox, set up menus, install AppleEvent handlers, and handle events and menu commands. CApplication tracks the life of the application object through its reference-counting methods (AddRef and Release), registers SimpleServer in the Registration Database, and instantiates the application’s ClassFactory.

These tasks (and other OLE-specific tasks mentioned in the next sections) will be covered in more detail later in the article.

Cwindow.cp (derived from IUnknown) - A window class containing methods for handling mouse, keyboard, update, and activate events.

Cdocument.cp (derived from CWindow) - A document class which instantiates the primary interfaces associated with an embeddable object: IDataObject, IOleObject, and IPersistStorage The CDocument class acquires all the interface pointers it will use during a document’s lifetime when a document is initialized. These pointers are stored as member data and are released when the document is deallocated.

Ctoolbar.cp (derived from Cwindow) - A small toolbar class.

CShape.cp (derived from CObject) - A shape class. Shape objects are drawn upon a document and maintained in a linked list associated with a CDocument.

Utility Source Files

AEvents.cp - Handlers for the required AppleEvents and one special OLE 2.01 AppleEvent (‘EMBD’) which indicates the application has been launched as a result of an embedding.

OleErrors.cp - Error routines for evaluating results of Toolbox and OLE function calls. Also contains functions which return human-readable strings for SCODES.

Debug.h/Debug.c - A set of macros for asserting; includes macros for dumping messages to the OLE LRPCSpy utility on entering an interface method or calling AddRef or Release. (LRPCSpy is described in detail later in the article).

Utitilies.cp - Utilities for detecting System 7. Contains two OLE-specific utilities: one for freeing pointers to blocks of memory allocated by OLE and another for writing to the OLE registration database.

SimpleServer.r - Resource file for SimpleServer.

OLE-Specific Source Files

CClassFactory.cp - Implementation of the IClassFactory interface.

CDataObject.cp - Implementation of the IDataObject interface, which is used to transfer data to and from an OLE object. IDataObject methods set and retrieve data (GetData, SetData), enumerate supported data formats (EnumFormatEtc), and establish connections between an object and its container.

COleObject.cp - Implementation of IOleObject, the primary means by which an embedded object provides functionality to its container.

CPersistStorage.cp - Implementation of IPersistStorage. Objects generated by a server’s IClassFactory::CreateInstance method are initialized by calling either IPersistStorage::InitNew or IPersistStorage::Load.

OleMessageFilter.cp - Installs a minimal implementation of the IMessageFilter interface, which allows an application to handle incoming Macintosh events while waiting for synchronous OLE calls to complete. Adding IMessageFilter is straightforward: the OLE Sample User Interface Library contains a standard implementation (in msgfiltr.c) that an application can use without modification.

UI Source Files : The following files included in the SimpleServer project are taken from the OLE Sample UI source code: busy.c, common.c, geticon.c, msgfiltr.c, ole2ui.c, ole2ui.r, olestd.c, regdb.c, utility.c.

The OLE Sample User Interface Library contains source code for the standard OLE dialogs (for example, the Insert Object and Paste Special dialogs), as well as helper functions for memory management, object feedback (the way an object appears in various editing states), linking, data transfer, debugging and more. A full discussion of the UI Library is beyond the scope of this article. For more information, see the “OLE 2.01 UI Help” help file included with the OLE SDK.

Running SimpleServer

SimpleServer is a regular Macintosh application. It can be launched and used like any other Mac application. Go ahead and try it. It is already built and can be found in the Applications folder on the OLE SDK CD.

Stepping Through SimpleServer

SimpleServer comes with a ThinkC Project and an MPW makefile. (NOTE: In order to link SimpleServer in ThinkC, you’ll need to add OutputDebugString to Ole2Lib.near.debug.v before compiling and linking. To make the change, open the .v file in any text editor, add a newline, and type out the function name (with matching case). The function prototype is located in the SimpleServer source file, Debug.h. If you’d like to use OutputDebugString in your own application, you’ll need to include a function prototype as well.)

After compiling, launch SimpleServer and set a breakpoint on the first statement of main() in file main.cp. To see how an OLE server typically handles startup, step through its initialization routine. Eventually, SimpleServer will fall into its event loop where you can set a breakpoint on the call to gApp->DisposeApplication and step through its shutdown code.

Here’s a synopsis of what SimpleServer does on startup and exit (calls to the OLE API are marked in boldface):

1. main(), main.cp - Instantiates a CApplication object.

• The constructor for CApplication does nothing more than initialize member variables (this is consistent across all SimpleServer class constructors).

2. CApplication::InitApplication - Initializes the CApplication object

• Calls standard Macintosh initialization routines.

• Retrieves and displays application menus.

• Installs handlers for the required AppleEvents and the OLE ‘EMBD’ event.

• Instantiates a toolbar.

• Calls OleInitApplication.

3. CApplication::OleInitApplication - Initializes OLE

• Calls InitOleManager. This routine loads OLE into memory if it is not already present, registers application context information and sets up a table which exposes the OLE API to the application. Passing the OLEMGR_BIND_NORMAL flag specifies a normal launch, bind, and AddRef of the OLE libraries. A call to InitOleManager is always balanced by a call to UninitOleManager in an application’s shutdown code.

• Calls OleInitialize. This API fully initializes OLE. At this point, OLE functions can be called by an application. An argument of NULL for pMalloc indicates that OLE should use its default implementation of IMalloc to handle process memory. An application always calls OleUninitialize in its shutdown code to balance a call to OleInitialize.

• Calls OleUpdateRegDB.

4. CApplication::OleUpdateRegDB - Updates the Registration Database

• Opens the OLE 1.0 registration database (“Embedding Preferences”) and registers SimpleServer if references to it do not already exist in the file.

• Opens the OLE 2.01 registration database (“Registration Database”) and registers SimpleServer, if necessary. A helper function, WriteToOleReg, is used to handle this procedure and can be found in Utilities.cp.

SimpleServer registers itself in the OLE 1.0 Embedding Preferences because OLE provides a compatibility layer that allows OLE 1 and 2 applications to interact with each other transparently. SimpleServer objects can be embedded in all OLE 1.0 client applications.

5. CApplication::RegisterClassFactory - Instantiates and registers the ClassFactory

• Instantiates an instance of CClassFactory and assigns its pointer to a CApplication member variable.

• Calls CoRegisterClassObject with SimpleServer’s CLSID and a pointer to the just-instantiated class factory. Another CApplication member variable (m_CoRegisterResult) will be filled out with a value identifying the object class. This value is passed to CoRevokeClassObject in order to revoke the class registration on application shutdown. After calling CoRegisterClassObject, other OLE applications can now connect to SimpleServer’s object class.

6. CApplication::OleMessageFilterRegister - Registers the MessageFilter

• Instantiates and registers a standard implementation of the IMessageFilter interface. The OLE libraries continually call an application’s IMessageFilter::MessagePending method while waiting for a reply from a synchronous OLE call. This allows an application the opportunity to process critical events such as update, activate, and os events. Applications call WaitNextEvent within this method (with a sleep parameter greater than zero) and act on the ‘urgent’ events listed above.

7. CApplication::OleLockApplication - Locks the CApplication object in memory

• Calls CoLockObjectExternal. This routine sets a strong reference on the CApplication object which explicitly locks the application in memory on behalf of the user (a strong reference dictates that an object will remain in memory even if its reference count falls to zero). Once a context for the launch has been established (that is, whether it was launched from the Finder or as the result of an embedding), the CApplication will be unlocked and the life of the application will be subject to the standard rules of reference counting. Note the ‘artificial’ AddRef immediately preceding the call and the Release following it. This strategy applies an artificial weak reference to the CApplication object for purposes similar to CoLockObjectExternal and should only be used within the scope of a single function.

8. HandleOpenApplication, AEvents.cp - SimpleServer processes an ‘oapp’ AE

• In its ‘oapp’ handler, SimpleServer creates a document (CApplication::CreateNewDocument).

9. CApplication::CreateNewDocument - Creates and initializes a new document

• Instantiates a new CDocument object.

• Calls CWindow::InitWindow in order to create a window (CDocument is derived from CWindow). The CDocument this pointer is retained by a call to SetWRefCon .

• Instantiates CDataObject, COleObject, and CPersistStorage; their pointers are retained as member data.

• Increments the application document count.

10. CApplication::DisposeApplication, CApplication::OleCleanup - Cleanup on shutdown

• Calls CApplication::OleCleanup to revoke the class object from the class factory table. Revokes the application IMessageFilter. Calls OleUninitialize and UninitOleManager.

After launching and exiting the sample, SimpleServer is registered in the Registration Database. Once registered, containers that support insertable objects can now be used to embed a SimpleServer shape object, which is what we’ll look at next.

Embedding a SimpleServer Object

LRPCSpy

The OLE SDK includes a utility, called LRPCSpy, which we’ll use to track the communication between SimpleServer and its container as a SimpleServer object is embedded. LRPC stands for lightweight remote procedure call, the mechanism by which OLE transfers data between processes (referred to as “lightweight” because the communication is currently restricted to processes on one machine). OLE has been carefully designed so that the LRPC mechanism can be easily replaced with a fully-distributable RPC based on OSF DCE RPC (Open Software Foundation Distributed Computing Environment Remote Procedure Call). This will be done in a future version of OLE.

LRPCSpy is an extremely useful tool that displays messages from the debug version of the OLE Manager. These messages track inter-process communication between a container and server. LRPCSpy displays method names as they are called, the arguments passed by the caller, and the return value from the callee. When debugging an OLE application, LRPCSpy will show how much progress was made before failure. Comparing the output to that generated by a working container/server combination can be invaluable during development.

OLE2 applications can write their own messages to LRPCSpy by calling OutputDebugString, an undocumented OLE routine. OutputDebugString can be called after adding a function prototype your project (and manually typing the function name into your OLE library .v file, if compiling under ThinkC). SimpleServer writes a debug message to LRPCSpy on entry of any interface method and dumps a reference count identifying any object which is AddRef’ed or Release’d.

For the next debugging session, be sure LPRCSpy is running in the background and the Extensions folder contains DDEWatchInit and the debug version of the OleManager. Set a breakpoint on CClassFactory::CreateInstance (CClassFactory.cp) and launch the OLE 2.01 Test Container application (Cl2Test). From the Edit menu, choose “Insert Object”. From the Object Type list, select “Simple OLE 2.01 Server Document” and click OK.

SimpleServer should now launch and stop at the breakpoint at CClassFactory::CreateInstance. When stepping through the debugger, we see a call to CDocument::CreateDocument. (Watch LRPCSpy as you step past this call. On creation of a document, SimpleServer AddRef’s the object three times, once for each instantiated interface (IDataObject, IOleObject, and IPersistStorage). The IUnknown implementation for these interface classes delegates all calls to CDocument. CDataObject::QueryInterface, for example, passes the call to CDocument::QueryInterface which actually handles the request. Calls to AddRef and Release are similarly delegated to the document class; reference counts are still maintained at the interface level, to assist in debugging.

Back in LRPCSpy, the “LRPC” window shows that SimpleServer’s CreateInstance method has been called but has not yet returned. Press the command-key for ‘Go’ from within whatever debugger you are using and watch the conversation between the container and server. In the following section, SimpleServer and Cl2Test are referred to by their Creator codes, just as they are in LRPCSpy output. SimpleServer’s creator code is ‘SiSe’; Cl2Test’s creator code is ‘CLT2’. The “>” character indicates the direction of the conversation (for example, “CLT2 > SiSe IClassFactory::CreateInstance” means Cl2Test called SiSe’s IClassFactory::CreateInstance method).

1. CLT2 > SiSe IClassFactory::CreateInstance.

2. CLT2 > SiSe QueryInterface for IPersistStorage. SimpleServer recognizes the IID for IPersistStorage and returns the appropriate interface pointer.

3. CLT2 > SiSe IPersistStorage::InitNew. Initializes the object retrieved by CreateInstance, above.

4. CLT2 > SiSe QueryInterface for IDataObject and IOleObject. SiSe returns the requested pointers.

What the heck just happened? Cl2Test called OleCreate and passed SimpleServer’s CLSID as the requested object type and the IID for the IOleObject interface. OLE launches SimpleServer after retrieving its location from the registration database) and calls its class factory (#1, above) to create a new SimpleServer object. OLE retrieves a pointer to IPersistStorage (#2) and calls InitNew (#3) to give SimpleServer a chance to initialize the object. Finally, OLE queries the object for IOleObject (#4) and returns the interface pointer to Cl2Test. IDataObject is retrieved by OLEfor internal use.

5. CLT2 >SiSe IOleObject::SetClientSite. Cl2Test passes a pointer to its IOleClientSite for SimpleServer to retain. All containers implement IOleClientSite, the primary means of communication between an object and its container.

6. CLT2 > SiSe IOleObject::Advise. Establishes a connection between SimpleServer and Cl2Test which will be used to notify the container when an object is saved, closed, or renamed.

7. CLT2 > SiSe IOleObject::SetMoniker. A moniker is to an object what an alias is to a file: it’s a conceptual handle to a link source (that is, an object) which can be stored with and dereferenced by a linking application.SimpleServer does not support linking and so returns E_NOTIMPL (not implemented) from the method.

8. CLT2 > SiSe IDataObject::QueryGetData. Cl2Test asks whether a PICT presentation is available. SimpleServer responds in the affirmative.

9. CLT2 > SiSe IDataObject::DAdvise. This creates another advisory connection which will be used to notify the container when any data in the object has changed. SimpleServer sends an OnDataChange notification before returning from the call. (Note: the LRPCSpy output window lists this method name as ‘Advise’. The function was renamed during OLE development to differentiate the call from the IOleObject::Advise method.)

10. LockConnection. LockConnection is an internal OLE routine used to manage the LRPC connection between applications. Since this involves no SimpleServer code, we’ll skip an explanation.

11. CLT2 > SiSe IOleObject::GetMiscStatus. SimpleServer returns OLE_S_USEREG indicating that the value should be retrieved from the Registration Database.

12. CLT2 > SiSe IOleObject::GetExtent. Cl2Test requests the extent (the width and height) of the object.

13. CLT2 > SiSe IOleObject::SetHostNames. Cl2Test passes user-presentable text strings for the name of the container application and the container object. SimpleServer concatenates the strings and sets the window title of the embedded object document to this value.

14. CLT2 > SiSe IOleObject::DoVerb. Cl2Test asks SimpleServer to invoke its primary verb. . An OLE verb is an operation supported by a server. OLEIVERB_PRIMARY is that verb which is invoked on double-clicking an object in its container. For SimpleServer, OLEIVERB_PRIMARY activates the server, loads the object, and puts the user in editing mode.

15. SiSe > CLT2 IOleClientSite::ShowObject. SimpleServer calls this to request that the container scroll the object into view. This ensures that the object’s presentation is visible.

16. SiSe > CLT2 IOleClientSite::OnShowWindow. OnShowWindow(true) lets Cl2Test know that the server object window is visible. The container “hatches” the object presentation as a visual indicator that the object is being edited in another window.

At this point, try drawing a few shapes into the SimpleServer document window and note the LRPCSpy output.

17. SiSe > CLT2 IAdviseSink::OnDataChange. SimpleServer sends an OnDataChange notification to Cl2Test as each shape is drawn. Cl2Test updates its presentation.

Delete a shape (from the Edit menu, choose “Delete Last Shape”, or press command-D).

18. SiSe > CLT2 IAdviseSink::OnDataChange. SimpleServer calls OnDataChange again to reflect the change in the server object.

Now close the SimpleServer window. Back in LRPCSpy, examine the resulting messages:

19. SiSe > CLT2 IOleClientSite::SaveObject. SimpleServer asks Cl2Test to save the object. Cl2Test calls OleSave, an OLE helper function which retrieves SimpleServer’s CLSID (GetClassID), writes it to the storage, and then invokes SimpleServer’s IPersistStorage::Save method. In IPersistSave, SimpleServer writes out the object data. Afterwards, Cl2Test can write additional data to the same storage. Cl2Test calls IPersistStorage::SaveCompleted to let SimpleServer know the storage can be written to again. Finally, SimpleServer sends an OnSave notification to Cl2Test’s IAdviseSink.

20. SimpleServer sends two final notification messages to the container. OnShowWindow(false) lets Cl2Test know that SimpleServer is hiding its object window. Cl2Test redraws the object without hatching. OnClose indicates the object is closing.

Back in Cl2Test, the SimpleServer object displays in the document window. Double-click the object in order to open it again. The LRPCSpy output is similar to that generated when creating an object, but is briefer because the work of creating the object has already been accomplished. Note the lack of any calls to QueryInterface on the part of Cl2Test. Cl2Test retains the pointers to the object’s OLE interfaces it previously acquired:

21. CLT2 > SiSe IClassFactory::CreateInstance.

22. The OLE calls its internal IStubManager::LockConnection method.

23. Cl2Test > SiSe IPersistStorage::Load. CLT2 passes the persistent representation of the object created on the previous call to IPersistStorage::Save. SimpleServer reads this information and uses it to fill out an instance of CDocument.

24. CLT2 > SiSe IDataObject::Advise.

25. CLT2 > SiSe IOleObject::SetClientSite.

26. CLT2 > SiSe IOleObject::SetHostNames

27. CLT2 > SiSe IOleObject::Advise

28. CLT2 > SiSe IOleObject::SetMoniker

29. CLT2 > SiSe IOleObject::DoVerb

30. SiSe > CLT2 IOleClientSite::ShowObject

31. SiSe > CLT2 IOleClientSite::OnShowWindow

Whew!

The LRPCSpy output looks like an awful lot of work, but in fact, all of this interaction happens without a user’s knowledge and, in many cases, without a developer’s concern. In fact, it’s the code that lies within and between interface calls that gives OLE its real power and flexibility.

Tracking LRPC conversation, however, is a good way to become familiar with OLE and how it goes about its business. A strategy such as SimpleServer uses to generate messages during execution can also go a long way to assist debugging.

Now What?

In this simple sample application, you have seen how support for OLE can be implemented in an application using the headers, libraries, and run-time on the OLE SDK CD that accompanies this article. Again, we do not claim that this sample application is complete-it would have to support Visual Editing to even approach completeness-but we will defer the addition of Visual Editing until a later issue of MacTech (this issue’s full enough already!).

And when your implementation of support for OLE is completed, your application will be able to interact with those from the other Macintosh software vendors now completing their OLE support, including Adobe, Aldus, Brio, Caere, Calera, EBT, Microsoft, Oracle, PowerSoft, Shapeware, Summit, and others.

OLE 2.01 for the Macintosh is in final form-it is not a beta; you can ship its redistributable elements today, without paying any fees to Microsoft, Apple, or anyone else. These are also the terms under which OLE 2.01 for the Power Macintosh will ship, later this summer. For your convenience, a beta version of OLE 2.01 for the Power Macintosh is included on the OLE CD.

Future versions of OLE will support additional features, including an inter-object event model (OLE Controls), distributed services, irregularly-shaped objects, database access, etc. Combined, these features will make OLE even more approachable and powerful for developers and end users. This incremental evolution of OLE ensures that it continues to progress in the direction most demanded by software developers-and, more importantly, by end-users. For more information on the future of OLE, see the white papers and backgrounders in the “White Papers” folder on the OLE CD.

But when thinking about the future, don’t forget the present. Right now, OLE 2.01 provides the technology and features that you need to turn your existing applications into powerful, reuseable objects. OLE has made the dream of component software a reality, today. Don’t wait to get started!

Some Important OLE Terms and Concepts

GUIDs, IIDs, and CLSIDs - GUIDs are globally unique identifiers (sometimes referred to as universally unique identifiers). They are 128-bit values used to identify OLE interfaces and object classes (something like an application Creator code identifies an application, only in 16 bytes, not 4). SimpleServer uses two types of GUIDs: IIDs and CLSIDs.

IIDs, or interface identifiers, do just that: identify interfaces. OLE 2 defines IIDs for every standard interface. IIDs are used typically when requesting an instance of an interface implementation. CLSIDs, or class identifiers, identify object classes. CLSIDs associate objects with particular OLE object servers.

Functions which require IIDs or CLSIDs as arguments are passed a reference to a GUID structure using the REFIID and REFCLSID types. In C, functions pass pointers to the structure (that is, &IID_xxx or &CLSID_xxx). C++ allows the & to be dropped.

To compare a GUID, IID, or CLSID for equality, compobj.h (in the Macintosh OLE SDK) defines the IsEqualGUID, IsEqualIID, and IsEqualCLSID functions (the latter two are actually macros which map to the IsEqualGUID function). For C++ applications, compobj.h overloads the ‘==’ operator for the GUID type (which also applies to IID and CLSID, of course), precluding the need to use the IsEqualxxx functions for comparison.

Interfaces - An OLE interface is an array of function pointers known as a virtual table (vtbl). The functions pointed to by the members of a vtbl are called the methods, or member functions, of the interface. In C++ terms, an interface is an abstract base class, composed of pure virtual functions, which specifies a protocol without providing an implementation. Although it is very convenient to use C++ to define interfaces - because C++ builds the vtbl for you - it is not necessary. Interfaces can be defined, implemented and used in any language (in fact, the Outline sample code which ships with the Mac OLE SDK is written entirely in C).

An OLE interface defines a contract between any object which implements the interface and any client which makes use of it. This contract includes the name of the interface and its methods (or member functions), the parameter types and names of the methods, and the purpose of each functions. An object must implement all methods in an interface and adhere to the defined protocol (or intent) of each routine.

The IUnknown Interface - IUnknown is the base interface from which all other OLE 2 interfaces are derived and it defines methods for three member functions (QueryInterface, AddRef, and Release). The IUnknown interface encapsulates two fundamental concepts behind interface and object operations: reference counting and pointer retrieval (or interface negotiation).

Interface Negotiation (IUnknown::QueryInterface) - Objects retrieve interface pointers through a mechanism known as interface negotiation. Each interface has a globally unique interface identifier (IID) by which it is known at run-time. The IID allows a client to dynamically determine, through a call to IUnknown::QueryInterface, the capabilities (i.e., supported interfaces) of other objects. The ability to discover an object’s capabilities at run-time avoids the need to have specific knowledge of objects at compile-time, a central idea behind the concept of reusable objects.

Given a pointer to an interface, pInterface, a caller can invoke pInterface->QueryInterface to retrieve pointers to other interfaces which are implemented by the object. The caller passes an IID to QueryInterface, which then returns either a NULL pointer, indicating that the interface is not supported, or a valid pointer to the requested interface.

Reference Counting (IUnknown::AddRef and IUnknown::Release) - The IUnknown::AddRef and ::Release methods comprise OLE reference counting, a mechanism for tracking the life of OLE 2 objects. An object keeps a usage count for each interface derived from IUnknown. An interface is never deallocated if its usage count is greater than zero. Objects (which might contain multiple interfaces) are kept alive if there are one or more references to one or more of their interfaces.

Reference counting ensures that an object is never disposed before all references to it are released. This strategy allows independent objects to obtain and release pointers to the same object with no coordination required.

HRESULTs and SCODEs - OLE methods and API calls use a new HRESULT return type in order to pass back a useful return value and/or an indication of status or error information. HRESULT values are defined to be zero for success, and non-zero if an error or informational status is being returned. If the result value is non-zero, the application calls GetScode to map the HRESULT into a known status code (or SCODE). ResultFromScode can be used to wrap a specific SCODE in an HRESULT for return from an interface method.

The Registration Database - OLE 2.01 optimizes performance by caching certain kinds of data in the Registration Database (reg db). OLE applications (and OLE itself) can retrieve the location or capabilities of an object class without the overhead of loading the object server.

Much of an OLE application’s registration information is stored under its class identifier (CLSID). Examples include the location of the object server (as a full path, or even as an alias), a list of the data formats the object supports, and whether it is embeddable in an OLE container.

The IClassFactory Interface - IClassFactory is used to create instances of an OLE object in memory. It contains only two methods beyond those derived from IUnknown: CreateInstance and LockServer. CreateInstance does the actual work of creating an uninitialized instance of an OLE object. LockServer can be used to lock a server in memory when it is advantageous to guarantee the server’s presence (for example, when a container plans to instantiate several instances of an object class).

The IMalloc Interface - IMalloc defines a set of methods for allocating and freeing memory. An application passes an instance of IMalloc as a parameter to the OLE library initialization function OleInitialize. Applications can implement IMalloc to integrate their own memory management schemes with the OLE libraries.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

BetterTouchTool 1.84 - Customize Multi-T...
BetterTouchTool adds many new, fully customizable gestures to the Magic Mouse, Multi-Touch MacBook trackpad, and Magic Trackpad. These gestures are customizable: Magic Mouse: Pinch in / out (zoom... Read more
Dropbox 8.4.21 - Cloud backup and synchr...
Dropbox is an application that creates a special Finder folder that automatically syncs online and between your computers. It allows you to both backup files and keep them up-to-date between systems... Read more
OmniGraffle Pro 6.6.1 - Create diagrams,...
OmniGraffle Pro helps you draw beautiful diagrams, family trees, flow charts, org charts, layouts, and (mathematically speaking) any other directed or non-directed graphs. We've had people use... Read more
OmniGraffle 6.6.1 - Create diagrams, flo...
OmniGraffle helps you draw beautiful diagrams, family trees, flow charts, org charts, layouts, and (mathematically speaking) any other directed or non-directed graphs. We've had people use Graffle to... Read more
f.lux 37.7 - Adjusts the color of your d...
f.lux makes the color of your computer's display adapt to the time of day, warm at night and like sunlight during the day. Ever notice how people texting at night have that eerie blue glow? Or wake... Read more
BBEdit 11.6.1 - Powerful text and HTML e...
BBEdit is the leading professional HTML and text editor for the Mac. Specifically crafted in response to the needs of Web authors and software developers, this award-winning product provides a... Read more
ScreenFlow 6.1 - Create screen recording...
ScreenFlow is powerful, easy-to-use screencasting software for the Mac. With ScreenFlow you can record the contents of your entire monitor while also capturing your video camera, microphone and your... Read more
Microsoft Office 2016 15.25 - Popular pr...
Microsoft Office 2016 - Unmistakably Office, designed for Mac. The new versions of Word, Excel, PowerPoint, Outlook and OneNote provide the best of both worlds for Mac users - the familiar Office... Read more
FileZilla 3.21.0 - Fast and reliable FTP...
FileZilla (ported from Windows) is a fast and reliable FTP client and server with lots of useful features and an intuitive interface. Version 3.21.0: Fixed Vulnerabilities Fixed a string format... Read more
Fantastical 2.2.5 - Create calendar even...
Fantastical 2 is the Mac calendar you'll actually enjoy using. Creating an event with Fantastical is quick, easy, and fun: Open Fantastical with a single click or keystroke Type in your event... Read more

Pokemon GO update: Take me to your leade...
The Team Leaders in Pokemon GO have had it pretty easy up until now. They show up when players reach level 5, make their cases for joining their respective teams, and that's pretty much it. Light work, as Floyd Mayweather might say. [Read more] | Read more »
Ruismaker FM (Music)
Ruismaker FM 1.0 Device: iOS Universal Category: Music Price: $4.99, Version: 1.0 (iTunes) Description: Following up on the success of Ruismaker, here's her crazy twin-sister, designed for people who want to design their own... | Read more »
Space Marshals 2 (Games)
Space Marshals 2 1.0.15 Device: iOS iPhone Category: Games Price: $5.99, Version: 1.0.15 (iTunes) Description: The sci-fi wild west adventure in outer space continues with Space Marshals 2. This tactical top-down shooter puts you in... | Read more »
Dungeon Warfare (Games)
Dungeon Warfare 1.0 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0 (iTunes) Description: Dungeon Warfare is a challenging tower defense game where you become a dungeon lord to defend your dungeon against greedy... | Read more »
Solitairica (Games)
Solitairica 1.0.7 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0.7 (iTunes) Description: Solitairica takes RPG combat and challenging rogue-like progression to a fresh new place—the world of solitaire! | Read more »
Bowmasters tips, tricks and hints
At least for this writer, archery was one of the more pleasant surprises of the 2016 Rio Olympics. As opposed to target shooting with guns, which was dreadfully boring, watching people shoot arrows at targets was pretty darn cool. [Read more] | Read more »
Best apps for watching live TV
The Olympics have come and gone, leaving nearly everyone in a temporary state of "What the heck am I going to watch on TV right now?" Besides old reruns of Golden Girls, but that goes without saying. [Read more] | Read more »
What is Flip Diving, and why has it take...
Move over Pokemon GO. There's a new king in town, and it's "the world's #1 cliff diving game." [Read more] | Read more »
5 places where Pokemon GO is still numbe...
In the U.S., the bloom is off the Pokemon Go rose ever so slightly. It's still doing great, sitting atop the top grossing chart as it has for some time, but it's no longer among the top 10 free apps in downloads, possibly because darn near... | Read more »
Madden NFL Mobile: How defense has chang...
Saying that defense is not a priority in Madden NFL Mobile is a bit of an understatement. In asynchronous head-to-head play, you don't take control of your defenders at all, as the AI manages them while your opponent plays offense. When it's your... | Read more »

Price Scanner via MacPrices.net

Apple refurbished 13-inch MacBook Airs availa...
Apple has Certified Refurbished 2016 and 2015 13″ MacBook Airs now available starting at $849. An Apple one-year warranty is included with each MacBook, and shipping is free: - 2016 13″ 1.6GHz/8GB/... Read more
Apple refurbished iPad mini 2s available for...
Apple is offering Certified Refurbished iPad mini 2s for up to $80 off the cost of new minis. An Apple one-year warranty is included with each model, and shipping is free: - 16GB iPad mini 2 WiFi: $... Read more
Save up to $600 with Apple refurbished Mac Pr...
Apple has Certified Refurbished Mac Pros available for up to $600 off the cost of new models. An Apple one-year warranty is included with each Mac Pro, and shipping is free. The following... Read more
Mac Pros on sale for $200 off MSRP
B&H Photo has Mac Pros on sale for $200 off MSRP. Shipping is free, and B&H charges sales tax in NY only: - 3.7GHz 4-core Mac Pro: $2799, $200 off MSRP - 3.5GHz 6-core Mac Pro: $3799, $200... Read more
Will We See A 10.5″ iPad Pro in 2017? – The ‘...
A MacRumors report, cites a research note from KGI Securities analyst Ming-Chi Kuo, saying a new size iPad model is in the works. According to the highly respected Cho, who has a strong track record... Read more
IOGEAR USB-C Docking Station Transforms Lapto...
IOGEAR has announced the launch of its innovative USB-C Docking Station with Power Delivery which turns USB-C enabled laptops into desktop workstations. The new IOGEAR USB-C Docking Station features... Read more
12-inch Retina MacBooks on sale for up to $10...
Amazon has 2016 12″ Apple Retina MacBooks on sale for $100 off MSRP. Shipping is free: - 12″ 1.1GHz Space Gray Retina MacBook: $1199 $100 off MSRP - 12″ 1.1GHz Silver Retina MacBook: $1224.99 $75 off... Read more
13-inch 2.5GHz MacBook Pro (Apple refurbished...
Apple has Certified Refurbished 13″ 2.5GHz MacBook Pros available for $829, or $270 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free: - 13″ 2.5GHz MacBook Pros... Read more
21-inch iMacs on sale for up to $120 off MSRP
B&H Photo has 21″ iMacs on sale for up to $120 off MSRP including free shipping plus NY sales tax only: - 21″ 3.1GHz iMac 4K: $1379 $120 off MSRP - 21″ 2.8GHz iMac: $1199.99 $100 off MSRP - 21″ 1... Read more
Typinator 6.10 comes with 50 improvements – G...
Ergonis Software today announced release of Typinator 6.10, a new version of their text expander utility for macOS. Typinator 6.10 comes with 50 improvements, including new features, compatibility... Read more

Jobs Board

*Apple* Mobile Master - Best Buy (United Sta...
What does a Best Buy Apple Mobile Master do? At Best Buy, our mission is to leverage the unique talents and passions of our employees to inspire, delight, and enrich Read more
*Apple* Retail - Multiple Positions Akron, O...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Simply Mac *Apple* Specialist- Repair Techn...
…The Technician is a master at working with our customers to diagnose and repair Apple devices in a manner that exceeds the expectations set forth by Apple Read more
*Apple* Retail - Multiple Positions Germanto...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Professional Learning Specialist - A...
# Apple Professional Learning Specialist Job Number: 51234379 Portland, Maine, Maine, United States Posted: Aug. 18, 2016 Weekly Hours: 40.00 **Job Summary** The Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.