Running Object Table
In general when binding to an object, we want to open it if it is currently passive, but if not, then we want to connect to the running instance. To take an example from Compound Documents, a link to a Lotus™ 1-2-3 for Windows spreadsheet, for example, when first bound to should open the spreadsheet, but a second bind should connect to the already-open copy. The key technical piece that supports this type of functionality is the Running Object Table.
The Running Object Table is a globally accessible table on each workstation. It keeps track of the objects that are currently running on that workstation so that if an attempt is made to bind to one a connection to the currently running instance can be made instead of loading the object a second time. The table conceptually is a series of tuples, each of the form:
(pmkObjectName, pvObject)
The first element is the moniker that if bound should connect to the running object. The second element is the object that is publicized as being available, the object that is running. In the process of binding, monikers being bound with nothing to their left consult the pmkObjectName entries in the Running Object Table to see if the object that they (the moniker being bound) indicate is already running.
Access to the Running Object Table is obtained with the function GetRunningObjectTable. This returns an object with the interface IRunningObjectTable (note as described earlier, however, that moniker implementations should not use this API, but should instead access the Running Object Table from the bind context they are passed).
interface IRunningObjectTable : IUnknown {
HRESULT Register(reserved, pUnkObject, pmkObjectName, pdwRegister);
HRESULT Revoke(dwRegister);
HRESULT IsRunning(pmkObjectName);
HRESULT GetObject(pmkObjectName, ppunkObject);
HRESULT NoteChangeTime(dwRegister, pfiletime);
HRESULT GetTimeOfLastChange(pmkObjectName, pfiletime);
HRESULT EnumRunning(ppenumMoniker);
};
SCODE GetRunningObjectTable(reserved, pprot);