A number of global OLE functions encapsulate a sequence of OLE interface calls. Following are some that we'll use in the EX28B example:
HRESULT OleCreate(REFCLSID rclsid, REFIID riid,
, IOleClientSite* pClientSite, IStorage* pStg, void** ppvObj);
The OleCreate function first executes the COM creation sequence using the specified class ID. This loads the component program. Then the function calls QueryInterface for an IPersistStorage pointer, which it uses to call InitNew, passing the pStg parameter. It also calls QueryInterface to get an IOleObject pointer, which it uses to call SetClientSite using the pClientSite parameter. Finally it calls QueryInterface for the interface specified by riid, which is usually IID_IOleObject.
HRESULT OleCreateFromData(IDataObject* pSrcDataObj, REFIID riid,
, IOleClientSite* pClientSite, IStorage* pStg, void** ppvObj);
The OleCreateFromData function creates an embedded object from a data object. In the EX28B example, the incoming data object has the CF_EMBEDDEDOBJECT format with an IStorage pointer. The function then loads the component program based on the class ID in the storage, and then it calls IPersistStorage::Load to make the component load the object's native data. Along the way, it calls IOleObject::SetClientSite.
HRESULT OleDraw(IUnknown* pUnk, DWORD dwAspect, HDC hdcDraw, LPCRECT lprcBounds);
This function calls QueryInterface on pUnk to get an IViewObject pointer, and then it calls IViewObject::Draw, passing the lprcBounds parameter.
The OleLoad function first executes the COM creation sequence by using the class ID in the specified storage. Then it calls IOleObject::SetClientSite and IPersistStorage::Load. Finally, it calls QueryInterface for the interface specified by riid, which is usually
IID_IOleObject.
HRESULT OleSave(IPersistStorage* pPS, IStorage* pStg,
);
This function calls IPersistStorage::GetClassID to get the object's class ID, and then it writes that class ID in the storage specified by pStg. Finally it calls IPersistStorage::Save.